0

NEW Storage API を使用して SAS を作成し、あるコンテナーから別のコンテナーに BLOB をコピーする、かなり単純な方法があります。

これを使用して、BETWEEN STORAGE ACCOUNTS 間で blob をコピーしようとしています。そのため、まったく同じコンテナーを持つ 2 つのストレージ アカウントがあり、ストレージ アカウントのコンテナーから別のストレージ アカウントのコンテナーに BLOB をコピーしようとしています。

SDKがそのために構築されているかどうかはわかりませんが、一般的なシナリオのようです.

いくつかの追加情報:

  1. 宛先コンテナーでトークンを作成します。そのトークンは、ソースと宛先の両方で作成する必要がありますか? トークンの登録に時間がかかりますか?リクエストごとに作成する必要がありますか、それともトークンの「ライフタイム」ごとに1回だけ作成する必要がありますか?

403 は Unauthorized Result http エラー コードです。

  private static string CreateSharedAccessToken(CloudBlobClient blobClient, string containerName)
    {
        var container = blobClient.GetContainerReference(containerName);
        var blobPermissions = new BlobContainerPermissions();

        // The shared access policy provides read/write access to the container for 10 hours:

        blobPermissions.SharedAccessPolicies.Add("SolutionPolicy", new SharedAccessBlobPolicy()
        {
            // To ensure SAS is valid immediately we don’t set start time 
            // so we can avoid failures caused by small clock differences:

            SharedAccessExpiryTime = DateTime.UtcNow.AddHours(1),
            Permissions = SharedAccessBlobPermissions.Write |
                          SharedAccessBlobPermissions.Read
        });


        blobPermissions.PublicAccess = BlobContainerPublicAccessType.Blob; 
        container.SetPermissions(blobPermissions);

        return container.GetSharedAccessSignature(new SharedAccessBlobPolicy(), "SolutionPolicy");

    }

このトークンを使用してコピー操作を呼び出すと、403 が返されます。

  var uri = new Uri(srcBlob.Uri.AbsoluteUri + blobToken);
            destBlob.StartCopyFromBlob(uri);

私の Azure.Storage のバージョンは 2.1.0.2 です。

これが役立つ場合の完全なコピー方法は次のとおりです。

    private static void CopyBlobs(
        CloudBlobContainer srcContainer, string blobToken,
        CloudBlobContainer destContainer)
    {
        var srcBlobList
            = srcContainer.ListBlobs(string.Empty, true, BlobListingDetails.All); // set to none in prod (4perf)

        //// get the SAS token to use for all blobs 
        //string token = srcContainer.GetSharedAccessSignature(
        //    new SharedAccessBlobPolicy(), "SolutionPolicy");

        bool pendingCopy = true;

        foreach (var src in srcBlobList)
        {
            var srcBlob = src as ICloudBlob;

            // Determine BlobType:

            ICloudBlob destBlob;
            if (srcBlob.Properties.BlobType == BlobType.BlockBlob)
            {
                destBlob = destContainer.GetBlockBlobReference(srcBlob.Name);
            }
            else
            {
                destBlob = destContainer.GetPageBlobReference(srcBlob.Name);
            }

            // Determine Copy State:

            if (destBlob.CopyState != null)
            {
                switch (destBlob.CopyState.Status)
                {
                    case CopyStatus.Failed:
                        log.Info(destBlob.CopyState);
                        break;

                    case CopyStatus.Aborted:
                        log.Info(destBlob.CopyState);
                        pendingCopy = true;
                        destBlob.StartCopyFromBlob(destBlob.CopyState.Source);
                        return;

                    case CopyStatus.Pending:
                        log.Info(destBlob.CopyState);
                        pendingCopy = true;
                        break;
                }
            }


            // copy using only Policy ID:
            var uri = new Uri(srcBlob.Uri.AbsoluteUri + blobToken);
            destBlob.StartCopyFromBlob(uri);


            //// copy using src blob as SAS
            //var source = new Uri(srcBlob.Uri.AbsoluteUri + token);
            //destBlob.StartCopyFromBlob(source);

        }
    }

そして最後に、アカウントとクライアント (精査済み) コード:

       var credentials = new StorageCredentials("BAR", "FOO");
        var account = new CloudStorageAccount(credentials, true);
        var blobClient = account.CreateCloudBlobClient();
        var sasToken = CreateSharedAccessToken(blobClient, "content");

RESTクライアントを使用すると、これはうまくいくようです...何かアイデアはありますか?

4

3 に答える 3

0

両方の CloudStorageAccount オブジェクトが同じアカウントを指しているため、SAS トークンなしでコピーしても問題なく動作します。

一方、別のアカウントからコピーするには、パブリックにアクセス可能な BLOB または SAS トークンが必要です。したがって、試したことは正しかったのですが、 MSDNにも記載されているように、有効になるまでに最大 30 秒かかる可能性があるコンテナー レベルのアクセス ポリシーを確立しました。この期間中、アクセス ポリシーがアクティブになるまで、保存されているアクセス ポリシーに関連付けられている SAS トークンは、状態コード 403 (禁止) で失敗します。

もう 1 つ指摘したいことは、次のとおりです。Get*BlobReference を呼び出して新しい BLOB オブジェクトを作成すると、FetchAttributes などの GET/HEAD 操作を実行するまで CopyState プロパティは設定されません。

于 2013-10-09T17:49:38.860 に答える
0

このタスクには共有アクセス トークンは必要ありません。最終的に 2 つのアカウントになりましたが、問題なく動作します。

        var accountSrc = new CloudStorageAccount(credsSrc, true);
        var accountDest = new CloudStorageAccount(credsSrc, true);

        var blobClientSrc = accountSrc.CreateCloudBlobClient();
        var blobClientDest = accountDest.CreateCloudBlobClient();


        // Set permissions on the container.
        var permissions = new BlobContainerPermissions {PublicAccess = BlobContainerPublicAccessType.Blob};
        srcContainer.SetPermissions(permissions);
        destContainer.SetPermissions(permissions);


   //grab the blob
        var sourceBlob = srcContainer.GetBlockBlobReference("FOO");
        var destinationBlob = destContainer.GetBlockBlobReference("BAR");

        //create a new blob
        destinationBlob.StartCopyFromBlob(sourceBlob);
于 2013-10-07T22:04:32.893 に答える