연습 - 클라이언트 라이브러리 구성 및 초기화

완료됨

Azure Blob Storage를 사용하는 앱의 일반적인 워크플로는 다음과 같습니다.

  1. 구성 검색: 시작 시 스토리지 계정 구성, 일반적으로 스토리지 계정 연결 문자열을 로드합니다.

  2. 클라이언트 초기화: Azure Storage 클라이언트 라이브러리를 초기화하려면 연결 문자열을 사용합니다. 이 초기화를 통해 앱이 Blob 스토리지 API로 작업하는 데 사용할 개체가 만들어집니다.

  3. 사용: 컨테이너 및 Blob에 적용하려면 클라이언트 라이브러리를 사용하여 API를 호출합니다.

연결 문자열 구성

앱을 실행하기 전에, 사용할 스토리지 계정에 대한 연결 문자열을 가져옵니다. Azure Portal, Azure CLI 및 Azure PowerShell을 비롯한 모든 Azure 관리 인터페이스를 사용하여 연결 문자열을 가져올 수 있습니다. 이 모듈의 끝부분에서 코드를 실행하도록 웹앱을 설정할 때 Azure CLI를 사용하여 이전에 만든 스토리지 계정의 연결 문자열을 가져옵니다.

스토리지 계정 연결 문자열에는 계정 키가 포함됩니다. 계정 키를 비밀로 간주하고 항상 안전하게 저장합니다. 여기서는 App Service 앱 설정에 연결 문자열을 저장합니다. App Service 앱 설정은 앱 비밀을 위한 안전한 장소입니다. 이 디자인은 로컬 개발을 지원하지 않으며 자체적으로 강력한 엔드투엔드 솔루션이 아닙니다.

Important

이 코드 예제에서는 연결 문자열을 사용하여 스토리지 계정에 대한 액세스 권한을 부여합니다. 이 구성은 예시 목적으로 사용됩니다. 연결 문자열 및 계정 액세스 키는 애플리케이션 코드에서 주의해서 사용해야 합니다. 계정 액세스 키가 손실하거나 실수로 안전하지 않은 위치에 배치되는 경우 서비스가 취약해질 수 있습니다. 액세스 키가 있는 사람은 누구나 스토리지 계정에 대한 요청에 권한을 부여할 수 있으며 모든 데이터에 효과적으로 액세스할 수 있습니다.

보안 수준을 최적화하기 위해 가능하면 Azure 리소스에 대한 관리 ID를 사용하여 Blob, 큐 및 테이블 데이터에 대한 요청에 권한을 부여하는 것이 좋습니다. 자세한 내용은 Microsoft Entra ID를 사용하여 Blob에 대한 액세스 권한 부여를 참조하세요.

Blob Storage 개체 모델 초기화

.NET용 Azure Storage SDK에서 Blob Storage를 사용하기 위한 표준 패턴은 다음과 같습니다.

  1. BlobServiceClient 개체를 인스턴트화하고 스토리지 계정에 연결 문자열을 제공합니다.

  2. BlobContainerClient를 가져오려면 BlobServiceClient에서 상호 작용하거나 만들 컨테이너의 이름으로 GetBlobContainerClient를 호출합니다.

코드에서 이러한 단계는 다음과 같습니다.

BlobServiceClient blobServiceClient = new BlobServiceClient(storageConfig.ConnectionString);
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(storageConfig.FileContainerName);

이 초기화 코드는 네트워크를 통해 호출하지 않습니다. 이 사실은 잘못된 정보로 인해 발생하는 일부 예외가 나중에도 throw되지 않음을 의미합니다. 예를 들어, 잘못된 형식의 연결 문자열이 BlobServiceClient 클래스의 생성자에 제공되는 경우 예외가 즉시 throw됩니다. 그러나 연결 문자열이 존재하지 않는 스토리지 계정을 가리키는 경우 스토리지 계정에 대한 작업을 시도할 때까지 예외가 throw되지 않습니다.

Java용 Azure Storage SDK에서 Blob Storage를 사용하는 표준 패턴은 다음 단계로 구성됩니다.

  1. 스토리지 계정에 대한 연결 문자열을 사용해 새 BlobServiceClientBuilder 개체를 인스턴스화하여 BlobServiceClient를 빌드합니다.

  2. BlobServiceClient에서 상호 작용하거나 만들 컨테이너의 이름으로 getBlobContainerClient를 호출하여 BlobContainerClient를 가져옵니다.

코드에서 이러한 단계는 다음과 같습니다.

BlobServiceClient blobServiceClient = BlobServiceClientBuilder()
    .connectionString(connectionString)
    .buildClient();
BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(containerName);

이 초기화 코드는 네트워크를 통해 호출하지 않습니다. 이 사실은 잘못된 정보로 인해 발생하는 일부 예외가 나중에도 throw되지 않음을 의미합니다. 예를 들어 잘못된 형식의 연결 문자열이 BlobServiceClientBuilder에 제공되는 경우 즉시 예외가 throw됩니다. 그러나 연결 문자열이 존재하지 않는 스토리지 계정을 가리키는 경우 스토리지 계정에 대한 작업을 시도할 때까지 예외가 throw되지 않습니다.

시작 시 컨테이너 만들기

앱이 시작될 때 또는 앱에서 컨테이너를 처음 사용하려고 할 때 컨테이너를 만들려면 BlobContainerClient에서 CreateIfNotExistsAsync를 호출합니다.

CreateIfNotExistsAsync은(는) 컨테이너가 이미 있는 경우 예외를 throw하지 않지만 Azure Blob Storage에 대한 네트워크 호출을 수행합니다. 컨테이너를 사용할 때마다가 아니라 초기화 중에 한 번 호출합니다.

앱이 시작되거나 처음 사용하려고 시도할 때 컨테이너를 만들려면 BlobContainerClient에 대해 exists을(를) 호출하여 컨테이너가 이미 있는지 확인합니다. 컨테이너가 없는 경우 create을(를) 호출합니다. 컨테이너를 사용할 때마다가 아니라 초기화 중에 한 번 호출합니다.

연습

완료되지 않은 앱 복제 및 살펴보기

  1. 먼저 GitHub의 시작 앱을 복제합니다. 원본 코드의 복사본을 가져오고 편집기에서 열기 위해 Azure Shell CLI에서 다음 명령을 실행합니다.

    git clone https://github.com/MicrosoftDocs/mslearn-store-data-in-azure.git
    cd mslearn-store-data-in-azure/store-app-data-with-azure-blob-storage/src/start
    code .
    
  2. 편집기에서 Controllers/FilesController.cs 파일을 엽니다. 여기에서는 수행할 작업이 없지만, 앱이 수행하는 작업을 간단히 확인합니다.

    이 컨트롤러는 다음과 같은 세 가지 작업으로 API를 구현합니다.

    • Index: (GET /api/Files)은(는) 업로드된 각 파일에 하나씩 URL 목록을 반환합니다. 앱 프런트 엔드는 이 메서드를 호출하여 업로드된 파일에 대한 하이퍼링크 목록을 빌드합니다.
    • upload: (POST /api/Files)은(는) 업로드한 파일을 받아 저장합니다.
    • download: (GET /api/Files/{filename})은(는) 개별 파일을 해당 이름으로 다운로드합니다.

    작업을 수행하기 위해 각 메서드는 storage라는 IStorage 인스턴스를 사용합니다. Models/BlobStorage.cs에 채워야 할 불완전한 IStorage 구현이 있습니다.

NuGet 패키지 추가

  • Azure Storage SDK에 참조를 추가합니다. Azure Shell CLI에서 다음 명령을 실행합니다.

    dotnet add package Azure.Storage.Blobs
    dotnet restore
    

    이 명령은 최신 버전의 Blob Storage 클라이언트 라이브러리를 사용하고 있는지 확인합니다.

구성

필요한 구성 값은 스토리지 계정 연결 문자열과 앱이 파일을 저장하는데 사용하는 컨테이너 이름입니다. 이 모듈에서는 Azure App Service의 앱만 실행합니다. App Service 모범 사례를 따라 App Service 앱 설정에 값을 저장합니다. App Service 인스턴스를 만들 때 이 작업을 수행합니다. 지금은 해야 할 일이 없습니다.

구성을 사용할 때, 시작 앱에 필요한 연결이 포함되어 있습니다. BlobStorageIOptions<AzureStorageConfig> 생성자 매개 변수에는 두 개의 속성, 즉 스토리지 계정 연결 문자열 및 앱이 Blob을 저장하는 데 사용하는 컨테이너 이름이 있습니다. Startup.csConfigureServices 메서드에는 앱이 시작될 때 구성에서 값을 로드하는 코드가 있습니다.

초기화

  1. 편집기에서 Models/BlobStorage.cs를 엽니다. 추가하려는 코드에 준비할 수 있도록 파일 맨 위에 다음 using 문을 추가합니다.

    using Azure;
    using Azure.Storage.Blobs;
    using Azure.Storage.Blobs.Models;
    
  2. Initialize 메서드를 찾습니다. 앱이 처음 BlobStorage을(를) 사용할 때 이 메서드를 호출합니다. 궁금한 경우 Startup.cs에서 ConfigureServices을(를) 보고 콜이 어떻게 이루어지는지 확인할 수 있습니다.

    Initialize에서 컨테이너를 만들려고 합니다(아직 없는 경우). 현재의 Initialize 구현을 다음 코드로 바꾸고 Ctrl+S를 사용하여 작업을 저장합니다.

    public Task Initialize()
    {
        BlobServiceClient blobServiceClient = new BlobServiceClient(storageConfig.ConnectionString);
        BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(storageConfig.FileContainerName);
        return containerClient.CreateIfNotExistsAsync();
    }
    

완료되지 않은 앱 복제 및 살펴보기

  1. 먼저 GitHub의 시작 앱을 복제합니다. 원본 코드의 복사본을 가져오고 편집기에서 열기 위해 Azure Shell CLI에서 다음 명령을 실행합니다.

    git clone https://github.com/MicrosoftDocs/mslearn-store-data-in-azure.git
    cd mslearn-store-data-in-azure/store-java-ee-application-data-with-azure-blob-storage/start
    code .
    
  2. 편집기에서 src/main/java/com/microsoft/azure/samples/jsf/IndexBean.java 파일을 엽니다. 여기에서는 수행할 작업이 없지만, 앱이 수행하는 작업을 간단히 확인합니다.

    이 요청 범위의 bean은 src/main/webapp/index.xhtml Java Server Faces(JSF) 페이지에서 사용하는 3가지 작업을 구현합니다.

    • listFileNames: 업로드된 각 파일에 대해 하나씩 파일 이름 목록을 반환합니다. index.xhtml 페이지는 이 메서드를 호출하여 업로드된 파일에 대한 하이퍼링크 목록을 빌드합니다.
    • upload: 업로드한 파일을 받아 저장합니다. 파일 내용 및 메타데이터가 JSF 프레임워크에 의해 uploadedFile 속성에 삽입됩니다.
    • download: 개별 파일을 해당 이름으로 다운로드합니다.

    작업을 수행하기 위해 각 메서드는 storage라는 Storage 인스턴스를 사용합니다. src/main/java/com/microsoft/azure/samples/service/BlobStorage.java에 채워야 할 불완전한 Storage 구현이 있습니다.

Java용 Azure Storage SDK 참조 추가

Azure BOM을 사용하여 프로젝트에 Azure 클라이언트 라이브러리를 추가하는 것이 좋습니다. 종속성 충돌을 최소화하면서 여러 Azure 클라이언트 라이브러리를 사용하여 오케스트레이션하는 간단하고 세련된 방법을 제공합니다.

  1. 편집기에서 pom.xml 파일을 엽니다.

  2. 프로젝트에 Azure BOM을 추가하려면 project xml 태그 아래에서 다음 dependencyManagement 섹션을 추가합니다.

    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>com.azure</groupId>
          <artifactId>azure-sdk-bom</artifactId>
          <version>1.0.6</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
      </dependencies>
    </dependencyManagement>
    
  3. Java용 Azure Storage SDK를 추가하려면 다음 dependencyproject/dependencies xml 섹션에 추가합니다.

    <dependency>
      <groupId>com.azure</groupId>
      <artifactId>azure-storage-blob</artifactId>
    </dependency>
    

구성

필요한 구성 값은 스토리지 계정 연결 문자열과 앱이 파일을 저장하는데 사용하는 컨테이너 이름입니다. 이 모듈에서는 Azure App Service의 앱만 실행합니다. App Service 모범 사례를 따라 App Service 앱 설정에 값을 저장합니다. 여러분은 App Service 인스턴스가 만들어질 때 이 작업을 수행합니다. 지금은 해야 할 일이 없습니다.

구성을 사용하게 되면 App Service 앱 설정이 앱 코드에 환경 변수로 전달됩니다. 초기화 코드에서 이를 읽습니다.

초기화

  1. 편집기에서 src/main/java/com/microsoft/azure/samples/service/BlobStorage.java를 엽니다. 추가하려는 코드에 준비할 수 있도록 파일 맨 위에 다음 import 문을 추가합니다.

    import java.util.stream.Collectors;
    
    import com.azure.storage.blob.BlobClient;
    import com.azure.storage.blob.BlobContainerClient;
    import com.azure.storage.blob.BlobServiceClient;
    import com.azure.storage.blob.BlobServiceClientBuilder;
    import com.azure.storage.blob.models.BlobItem;
    
  2. BlobStorage 클래스에서 클래스 속성을 추가하여 BlobContainerClient 참조를 포함합니다.

    private BlobContainerClient blobContainerClient;
    

    Azure 클라이언트는 상태 비저장 상태이며 스레드로부터 안전합니다. 해당하는 경우 해당 인스턴스를 캐시하는 것이 좋습니다. 예를 들어 작업 중인 앱은 일정한 이름의 단일 컨테이너를 사용하므로 앱 수명 범위에서 캐시하는 것이 가장 좋습니다. BlobStorage@Singleton으로 주석 처리되므로 해당 필드에 BlobContainerClient 참조를 저장하는 것이 좋습니다.

  3. @PostConstruct 주석을 사용하여 init 메서드를 찾습니다. 앱은 BlobStorage 인스턴스가 만들어진 후, 처음 사용되기 전에 이 메서드를 호출합니다.

    init은(는) 컨테이너가 아직 없는 경우 컨테이너를 만드는 위치입니다. 현재 init 구현을 다음 코드로 바꾸고 작업을 저장합니다.

    @PostConstruct
    private void init() {
        String connectionString = System.getenv("STORAGE_CONNECTION_STRING");
        String containerName = System.getenv("STORAGE_CONTAINER_NAME");
        BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
            .connectionString(connectionString)
            .buildClient();
        blobContainerClient = blobServiceClient.getBlobContainerClient(containerName);
        if (!blobContainerClient.exists()) {
            blobContainerClient.create();
        }
    }