AMY&PINK

日本のITを世界へ!

Windows Azure Storageを使う

演習1:Blobを使ってみる

この演習では、画像ファイルを Windows Azure ストレージにblob として保存・読み出しできるアプリケーションの作成を通して、Windows Azure Blog Storage APIを使います。これは、Windows Azure Storageに画像の更新、削除し、参照ができる 簡単な画像ギャラリーのウェブサイトで構成します。そして、関連するメタデータの編集と表示を可能にします。アプリケーションは、画像をblobとして保存する為に単一のコンテナを使います。

Windows Azureにblob を作成する場合、APIが戻す画像ファイルのフォーマットや、blobに対応するURLで直接画像を取り出せることを想定して、コンテントタイプを関連付けておきます。

Task 1 - ストレージからBlobデータを取り出す

このタスクでは、Windows Azure Storageから取り出した画像を表示する イメージギャラリー Webページを作成します。 提供されるソリューションは、表示に必要な画像とメタデータの入力項目を含む、単一のページを持ったWebサイトプロジェクトによって構成されます。編集に必要な機能として、コードビハインドファイルを追加します。

  1. ユーザー “VMUser” パスワード “Pass0rd!” でログインします。
  2. スタートメニューから、Visual Studioを管理者として実行します。
  3. ”C:AzureServicesKitLabsGettingStartedAzureStorageEx01-WorkingWithBlobsbegin” にある begin.sln ソリューションを開きます。
  4. 次に、ストレージクライアントプロジェクトをソリューションに追加します。ソリューションエクスプローラーで、ソリューションノードを右クリックして「追加」、「既存のプロジェクト」を選択し、”C:AzureServicesKitLabsGettingStartedAzureStorageAssetsStorageClient”にある ”StorageClient.csproj” を開きます。

    .001-solution.

    ※注意
    StorageClient ライブラリには、REST APIを抽象化する為に使うWindows Azure Storageにアクセスするヘルパーメソッドとクラスが含まれます。これらは、Windows Azure SDKのサンプルと同様で、便利に使えるようにこのラボの一部として提供されています。

  5. 新しく追加されたプロジェクトへの参照を追加します。ソリューションエクスプローラーからRDImageGallery_WebRole プロジェクトノードを右クリックし、「参照の追加」をクリックします。プロジェクトタブに切り替えて、StorageClient プロジェクトを一覧から選択して、OK をクリックします。
  6. 不足している初期設定があるので、サービス定義(configurationスキーマ)のConfiguration settings を確認してから変更します。
  7. RDImageGallery プロジェクトのServiceDefinition.csdef ファイルを開き、既にメイン構成ファイルで使われるContainerName属性をサポートするように新しいエントリーを追加します。結果は以下のようになります。
      …
         <Setting name="TableStorageEndpoint" />
         <Setting name="ContainerName" />
       </ConfigurationSettings>
      …
  8. Windows Azure ストレージにアクセスする為に必要な configuration settings を確認して変更します。以下の設定が含まれます。
    • AccountName : Windows Azure アカウントを指定します。アカウント名は、ストアリソースのURIを構築するために使うコンポーネントの一つです。
    • AccountSharedKey : Windows Azure ストレージに対するリクエストの認証に使うキーを指定します。リクエストを認証するためには、リクエストにリクエストの為のアカウントのキーで署名する必要があります。
    • BlobStorageEndpoint : blob ストレージサービスのベースURIを指定します。
    • QueueStorageEndpoint : blob ストレージサービスのベースURIを指定します。(Queueストレージサービスの間違い?)
    • TableStorageEndpoint :blob ストレージサービスのベースURIを指定します。(Tableストレージサービスの間違い?)
    • ContainerName : このアプリケーションで画像を保存するために使うコンテナの名前を指定します。
  9. RDImageGalleryプロジェクトのServiceConfiguration.cscfg ファイルを開き、ConfigurationSettings セクションのContainerName の値を xxxgallery の xxx の箇所をあなたのフルネームに変更します。たとえば、このようにします。
        <ConfigurationSettings>
          <Setting name="AccountName" value="devstoreaccount1" />
          <Setting name="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" />
          <Setting name="BlobStorageEndpoint" value="http://127.0.0.1:10000"/>
          <Setting name="QueueStorageEndpoint" value="http://127.0.0.1:10001"/>
          <Setting name="TableStorageEndpoint" value="http://127.0.0.1:10002/" />
          <Setting name="ContainerName" value="davidaikengallery"/>
        </ConfigurationSettings>
    
    ※注意
    ContainerName に指定する値は、正しいドメイン名(DNS)で以下の命名規則に従っている必要があります。
    - 文字か数字で始まっている必要があり、その後は文字列、数字、ピリオド(.)、ハイフン(-) 文字を含むことができます。
    - 全ての文字は小文字で記述します。
    - 文字数は3から63文字にします。
    - 名前はハイフンで終わることはできません。
  10. RDImageGallery_WebRoleプロジェクトのDefault.aspx.cs ファイルをVisual Studioのテキストエディタに開きます。このファイルはHTMLとASP.NETマークアップを含むページのコードビハインドで、イメージギャラリーのユーザーインターフェイスを実装します。次のステップでは、いくつかの必要な機能を追加するために、コードビハインドファイルを修正します。
  11. ファイルの先頭近くにあるネームスペースコードブロックの既存のネームスペースの後に、ユーティリティクラスと、ServiceRuntimeクラスを使うためのネームスペース宣言を追加します。
    using Microsoft.Samples.ServiceHosting.StorageClient;
    using Microsoft.ServiceHosting.ServiceRuntime;
  12. _Default クラスで、ギャラリー内で画像を扱うblobコンテナの参照を保持するプライベートなメンバー変数を定義します。BlobContainer は、コンテナのblobをアクセスして羅列するためのユーティリティクラスです。
    private BlobContainer container;
    
    
  13. BlobContainerのインスタンスを、存在していなければ新規生成し、存在する場合はそれを返すメソッドを追加します。このメソッドは、Step5で入力した configuration settings を使います。
    (コードスニペット - Getting Started Azure Storage Lab-Ex01 GetContainer method)
    
    private BlobContainer GetContainer()
    {
      BlobStorage blobStorage = BlobStorage.Create(StorageAccountInfo.GetDefaultBlobStorageAccountFromConfiguration());
      BlobContainer newContainer = blobStorage.GetBlobContainer(RoleManager.GetConfigurationSetting("ContainerName"));
    
      newContainer.CreateContainer(null, ContainerAccessControl.Public);
      return newContainer;
    }
    
    ※注意
    VMに含まれるコードスニペットは、このステップでは間違えているかもしれません。特に return ステートメントは生成されたインスタンスの"newContainer" ではなく、"container" を返すかもしません。
    もしスニペットを使用した場合、戻り値が上記のコードと一致するよう必ず確認してください!
  14. ストレージから取り出した画像を表示するページ上の asp:ListView コントロールのリフレッシュとコンテナの初期化の為に、Page_Load メソッドを完成させましょう。
    
    (コードスニペット - Getting Started Azure Storage Lab-Ex01 Page_Load method)
    
    protected void Page_Load(object sender, EventArgs e)
    {
      try
      {
        this.container = this.GetContainer();
        if (!IsPostBack)
        {
          this.RefreshGallery();
        }
      }
      catch (System.Net.WebException we)
      {
        status.Text = "Network error: " + we.Message;
        if (we.Status == System.Net.WebExceptionStatus.ConnectFailure)
        {
           status.Text += "<br />Please check if the blob storage service is running at " + ConfigurationManager.AppSettings["storageEndpoint"];
        }
      }
      catch (StorageException se)
      {
        Console.WriteLine("Storage service error: " + se.Message);
      }
    }
  15. イメージギャラリーコンテナで利用可能なblobのリストを images コントロールにバインドするためのメソッドを追加します。このコードでは、各blobの情報を保存したBlobPropertiesオブジェクトのコレクションを返す BlobContainer オブジェクトの ListBlobs メソッドを使います。
    ページにあるimages asp:ListView コントロールにオブジェクトを値の表示の為にバインドします。
    (コードスニペット - Getting Started Azure Storage Lab-Ex01 RefreshGallery method)
    
    private void RefreshGallery()
    {
      this.images.DataSource = this.container.ListBlobs(String.Empty, false);
      this.images.DataBind();
    }
  16. アプリケーションのビルドと実行の為にF5キーを押します。ブラウザが起動して、イメージギャラリーのコンテンツが表示されます。ここで注意したいのは、コンテナは空で、listview は"No Data Available"メッセージを表示している点です。次のタスクでは、Windows Azure ストレージのblobsに画像を表示するのに必要な処理を実装します。

    .002-no-data.※注意

    ストレージの設定が正しく構成できていない場合、または、ストレージサービスが起動していない場合、以下に示すようなエラーが表示されます。

    .003-error.※注意

    MessageDataServiceContext のビルド時間に関して大きなエラー番号を受け取った場合、あなたがPage_Loadにスニペットを使って挿入した間違ったコードのせいかもしれません。”Getting Started Azure Storage Lab”バージョンのスニペットを必ず選択するようにし、”Azure Table Storage Lab”のものを誤って選択しないようにしてください。これらは異なるラボです。

  17. Shift + F5キーを押してVisual Studioのデバッグを終了し、開発ファブリックからテナントを削除します。

Task 2 - Blobデータをストレージにアップロードする

このタスクでは、Windows Azureストレージに、メタデータの入力と画像ファイルのアップロードをするための機能を、イメージギャラリーウェブページに追加します。このページには、選択したイメージの為の説明的メタデータを入力するために使うテキストコントロールが含まれます。ページ上の asp:FileUpload コントロールは、デスクトップから画像を取り出してそれらをblobストレージに保存する為にページにポストします。

  1. Default.aspx.cs ファイルをVisual Studioのエディターで開きます。
  2. Upload Image ボタンのイベントハンドラーに、以下のコードを追加します。
    (コードスニペット - Getting Started Azure Storage Lab-Ex01 upload_Click method)

    protected void upload_Click(object sender, EventArgs e)
    {
      if (imageFile.HasFile)
      {
        status.Text = "Inserted [" + imageFile.FileName + "] - Content Type [" + imageFile.PostedFile.ContentType + "] - Length [" + imageFile.PostedFile.ContentLength + "]";
        SaveImage(Guid.NewGuid().ToString(), imageName.Text, imageDescription.Text, imageTags.Text, imageFile.FileName, imageFile.PostedFile.ContentType, imageFile.FileBytes);
        RefreshGallery();
      }
      else
        status.Text = "No image file";
    }

    このコードは、ページにあるテキストボックスからメタデータと、asp:FileUpload コントロールのプロパティから、ポストされた画像のコンテントタイプと、ファイル名と、データのバイト配列を取り出します。それから、Windows Azureストレージに画像と、そのメタデータを保存するためにSaveImageメソッドを呼び出します。このメソッドは次のステップで実装します。

  3. 画像と、そのメタデータをWindows Azure ストレージにBlobとして保存するためのメソッドを追加します。このメソッドは、画像のデータ配列とメタデータのプロパティからBlobを生成する為に、BlobContainerオブジェクトのCreateBlobメソッドを使います。
    (コードスニペット - Getting Started Azure Storage Lab-Ex01 SaveImage method)

    private void SaveImage(string id, string name, string description, string tags, string fileName, string contentType, byte[] data)
    {
      BlobProperties properties = new BlobProperties(string.Format(CultureInfo.InvariantCulture, "image_{0}", id));
      NameValueCollection metadata = new NameValueCollection();
      metadata["Id"] = id;
      metadata["Filename"] = fileName;
      metadata["ImageName"] = String.IsNullOrEmpty(name) ? "unknown" : name;
      metadata["Description"] = String.IsNullOrEmpty(description) ? "unknown" : description;
      metadata["Tags"] = String.IsNullOrEmpty(tags) ? "unknown" : tags;
      properties.Metadata = metadata;
      properties.ContentType = contentType;
      BlobContents imageBlob = new BlobContents(data);
      this.container.CreateBlob(properties, imageBlob, true);
    }
  4. F5 キーを押して、アプリケーションのビルドし実行すると、ブラウザの中に画像ギャラリーページが開きます。
  5. テキストボックスに、Name, Description, Tagsのメタデータを入力します。次に、画像ファイル選択の為にBrowseボタンを押して、”C:AzureServicesKitLabsGettingStartedAzureStorageAssetsImages”フォルダに移動し、有効な画像を選択します。

    .004-enterdata.

  6. Webアプリケーションに画像をポストするために、Upload Image ボタンを押します。ページがリフレッシュされて、リストビューに新しく追加された画像が表示されます。ステータスメッセージに、アップロードした画像のファイル名、コンテントタイプ、サイズが表示されます。※注意 ここでのポイントは、画像のメタデータはまだ表示されていない点です。次のタスクでは、Windows Azure に保存されたBlobからメタデータを取り出して表示するのに必要な機能を実装します。

    .005-viewdata.

  7. Shift + F5キーを押して、デバッグを終了して、開発ファブリックからテナントを削除します。

Task 3 - ストレージのBlobからメタデータを取り出す

Blob は、メタデータをそれらに付属させて持つことができます。メタデータのヘッダーは、コンテナや、blobリソースの新規作成時のリクエストか、既存リソースに対する明示的なプロパティ生成でセットすることが出来るでしょう。このタスクでは、Windows Azureコンテナに画像と結びつけて保存されているメタデータを取り出して、表示する機能をイメージギャラリーページに追加します。

  1. 画像が表示されているリストビューコントロールに表示される各blob からメタデータを取り出す為に、イベントハンドラを追加します。Default.aspx ページをデザインモードで開き、images リストビューコントロールを選択し、プロパティウィンドウのイベントボタンをクリックします。(プロパティウィンドウを表示する場合、コントロールを右クリックして”プロパティ”を選択します)データカテゴリのItemDataBound イベントにフォーカスをもっていき、自分でASP.NET のマークアップに直接イベントハンドラに必要な編集をする代わりに、OnBlobDataBound と入力して<Enter>キーを入力します。

    .006-properties.

  2. コードビハインドファイルの、OnBlobDataBound メソッドに移動して、リストビューに紐付けられた個々のblobからプロパティを取り出し、個々のメタデータの名前と値のペアを含むコレクションを作成する以下のコードを挿入します。そしてこのコレクションは、各画像のメタデータを表示する asp:Repeater コントロールに対するデータソースとして使います。
    (コードビハインド -  Getting Started Azure Storage Lab Ex01 OnBlobDataBound method)

    protected void OnBlobDataBound(object sender, ListViewItemEventArgs e)
    {
      if (e.Item.ItemType == ListViewItemType.DataItem)
      {
        Repeater metadataRepeater = e.Item.FindControl("blobMetadata") as Repeater;
        BlobProperties blob = ((ListViewDataItem)(e.Item)).DataItem as BlobProperties;
        NameValueCollection metadata = container.GetBlobProperties(blob.Name).Metadata;
        metadataRepeater.DataSource = from key in metadata.AllKeys
                                      select new
                                      {
                                        Name = key,
                                        Value = metadata[key]
                                      };
        metadataRepeater.DataBind();
      }
    }
  3. F5キーを押して、アプリケーションをビルドして実行します。※注意 リストビューは、前の演習でアップロードされた画像に関するメタデータを表示しています。

    .007-display-metadata.

  4. Shift + F5 キーを押してデバッグを終了し、開発ファブリックからテナントを削除します。

Task 4 - ストレージからBlobを削除する

このタスクでは、Windows Azure ストレージに保存された画像データを削除するための機能を、イメージギャラリーWebページに追加します。

  1. ギャラリーコンテナから画像を削除するために使用する asp:LinkButton コントロールを配置するためにイメージリストビューをアップデートしましょう。 Default.aspx ページをソースモードで開いて、images  asp:ListView コントロールのItemTemplate の位置にカーソルを持って生きます。
    以下の blobMetadata リピートコントロール ASP.NET マークアップの箇所のコメントを解除します。(以下の太字でハイライトになっている箇所です)

    ...
        <div class="item">
          <ul style="width:40em;float:left;clear:left" >
            <asp:Repeater ID="blobMetadata" runat="server">
            <ItemTemplate>
              <li><%# Eval("Name") %><span><%# Eval("Value") %></span></li>
            </ItemTemplate>
            </asp:Repeater>
              <li>
                 <asp:LinkButton ID="deleteBlob" 
                      OnClientClick="return confirm('Delete image?');"
                      CommandName="Delete" 
                      CommandArgument='<%# Eval("Name")%>'
                      runat="server" Text="Delete" oncommand="OnDeleteImage" />                
              </li>
            </ul>
            <img src="<%# Eval("Uri") + "?id=" + Guid.NewGuid().ToString()%>"
                            alt="<%# Eval("Name") %>" style="float:left"/>
    ...
  2. Default.aspx.cs ファイルに、deleteBlob asp:LinkButton コントロールのコマンドハンドラーを実装しましょう。このコードは、blobがストレージに存在するか確認してから、それを削除します。
    (コードスニペット - Getting Started Azure Storage Lab Ex01 OnDeleteImage method)

    protected void OnDeleteImage(object sender, CommandEventArgs e)
    {
      if (e.CommandName == "Delete")
      {
        string blobName = (string)e.CommandArgument;
        if (this.container.DoesBlobExist(blobName))
        {
          this.container.DeleteBlob(blobName);
        }
        else
          this.status.Text = "Item does not exist";
          RefreshGallery();
      }
    }
    
    
  3. F5キーを押して、アプリケーションをビルドして実行しましょう。
  4. C:AzureServicesKitLabsGettingStartedAzureStorageAssetsImages フォルダから幾つかの画像をアップロードしてから、表示中の何れか画像に対応するblobをストレージから消す為に、Deleteキーをクリックします。
    
    .008-deletebutton.
  5. Shift + F5キーを押してデバッグを終了して、開発ファブリックからテナントを削除します。