#mynavi(Azureメモ)
#setlinebreak(on);

* 概要 [#da217e7d]
#html(<div class="pl10">)

azure-sdk-for-go では Azureサービスを管理、使用する為のGoパッケージが提供されているが、以下については別でパッケージが提供されている。

| サービス | パッケージ |h
| ストレージ-Blob | github.com/Azure/azure-storage-blob-go |
| ストレージ-ファイル | github.com/Azure/azure-storage-file-go |
| ストレージ-キュー | github.com/Azure/azure-storage-queue-go |
| サービスバス | github.com/Azure/azure-service-bus-go |
| イベントハブ | github.com/Azure/azure-event-hubs-go |
| Application Insights | github.com/Microsoft/ApplicationInsights-go |

以下のURLを見る限り、azure-sdk-for-go の同等機能は将来的に廃止される予定らしい。
https://github.com/Azure/azure-sdk-for-go/tree/master/storage 

なので、ここでは [[azure-storage-blob-go:https://github.com/Azure/azure-storage-blob-go]] を使用してBlobのファイルを読み書きする実装について確認する。
#html(</div>)

* 目次 [#pdfb53e8]
- 関連
-- [[Azureメモ]]
-- [[Azure CLI の操作]]
-- [[Azure Functions を Go で書く]]
-- [[Azure FunctionsからVMにアクセスする]]
- 参考
-- https://github.com/Azure/azure-sdk-for-go
-- https://github.com/Azure/azure-storage-blob-go

* 準備 [#o9f2d184]
#html(<div class="pl10">)

Goパッケージのインストール
#myterm2(){{
go get github.com/Azure/azure-storage-blob-go/azblob
}}

ログイン
#myterm2(){{
az login
}}

リソースの作成
#myterm2(){{
region=japanwest
resourceGroup=リソースグループ名
storageAccountName=ストレージアカウント名
storageContainer=sample-container

# リソースグループの作成
az group create \
  --name $resourceGroup \
  --location $region

# ストレージアカウントの作成
az storage account create \
  --name $storageAccountName \
  --location $region \
  --resource-group $resourceGroup \
  --sku $storageSku

# Storageコンテナの作成
az storage container create \
  --name $storageContainer \
  --resource-group $resourceGroup \
  --account-name $storageAccountName
}}

#html(</div>)

* 実装 [#n4db5760]
#html(<div class="pl10">)

sample_sdk_blob.go
#mycode2(){{
package main

import (
    "bytes"
    "context"
    "fmt"
    "net/url"

    "github.com/Azure/azure-storage-blob-go/azblob"
)

/**
 * 環境変数の取得.
 */
func getEnv(envName string, defaultValue string) string {

    value, exists := os.LookupEnv(envName)
    if exists {
        return value
    } else {
        return defaultValue
    }   
}

/**
  * メイン処理.
  */
func main() {

    fmt.Println("START main")

    accountName := getEnv("storageAccountName", "") 
    accountKey := getEnv("storageAccountKey", "") 
    containerName := getEnv("storageContainer", "") 
    fileName := getEnv("storageBlobFileName", "") 
    containerUrlTempl := getEnv("storageContainerUrl", "https://%s.blob.core.windows.net/%s")

    if accountName == "" || accountKey == "" || containerName == "" || fileName == "" {
        fmt.Println("環境変数が設定されていません。")
        return
    } 

    ctx := context.Background()

    containerUrlText := fmt.Sprintf(containerUrlTempl, accountName, containerName)
    u, _ := url.Parse(fmt.Sprintf("%s/%s", containerUrlText, fileName))
    credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
    if err != nil {
        fmt.Println(err)
    }   

    /****************************
     * アップロード
     ****************************/
    blockBlobURL := azblob.NewBlockBlobURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))

    // サンプルデータ作成
    data := []byte("sample1\nsample2\nsample3")

    // アップロード
    bufferSize := 2 * 1024 * 1024
    maxBuffers := 3
    _, err = azblob.UploadStreamToBlockBlob(ctx, bytes.NewReader(data), blockBlobURL,
        azblob.UploadStreamToBlockBlobOptions{BufferSize: bufferSize, MaxBuffers: maxBuffers})
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("Upload Success!")
    }   

    /****************************
     * ダウンロード
     ****************************/
    p := azblob.NewPipeline(credential, azblob.PipelineOptions{})
    cURL, _ := url.Parse(containerUrlText)
    containerURL := azblob.NewContainerURL(*cURL, p)
    blobURL := containerURL.NewBlobURL(fileName)

    // サイズを取得
    var blobSize int64 = 1024
    blobPropResponse, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
    if err != nil {
        fmt.Println("GetProperties Error!")
        fmt.Println(err)
    } else {
        fmt.Println("GetProperties Success!")
        fmt.Printf("type: %s\n", blobPropResponse.ContentType())
        fmt.Printf("size: %d\n", blobPropResponse.ContentLength())
        blobSize = blobPropResponse.ContentLength()
    }   

    // バッファに取得
    downloadedData := make([]byte, blobSize)
    err = azblob.DownloadBlobToBuffer(ctx, blobURL, 0, azblob.CountToEnd, downloadedData, azblob.DownloadFromBlobOptions{})
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("Download Success!")
        fmt.Println(string(downloadedData))
    }   

    // ファイルにダウンロード
    //err = azblob.DownloadBlobToFile(ctx, blobURL, 0, azblob.CountToEnd, file *os.File, o DownloadFromBlobOptions)

    fmt.Println("END   main")
}
}}

#html(</div>)

* 動作確認 [#q3067885]
#html(<div class="pl10">)

アカウントキーの確認
#myterm2(){{
az storage account keys list -n $storageAccountName
}}

実行
#myterm2(){{
export storageAccountName=ストレージアカウント名
export storageAccountKey="ストレージアカウントキー"
export storageContainer=sample-container
export storageBlobFileName=sample.txt

go run sample_sdk_blob.go

START main
Upload Success!
GetProperties Success!
type: application/octet-stream
size: 23
Download Success!
sample1
sample2
sample3
END   main
}}

#html(</div>)

* ローカルエミュレータに対して実行する時 [#z8e0adc1]
#html(<div class="pl10">)

ローカル実行する場合は、アカウント名、キー 及び コンテナURLを以下の通り設定する。
https://docs.microsoft.com/ja-jp/azure/storage/common/storage-use-emulator#connect-to-the-emulator-account-using-the-well-known-account-name-and-key

#myterm2(){{
export storageAccountName=devstoreaccount1
export storageAccountKey="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="
export storageContainerUrl=http://127.0.0.1:10000/%s/%s
export storageContainer=sample-container
export storageBlobFileName=sample.txt

go run sample_sdk_blob.go
}}
#html(</div>)

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS