1

Azure Storage SDK for Java を使用して、ある Azure サブスクリプションから別の Azure サブスクリプションに Azure VM のページ BLOB (停止および割り当て解除) をコピーしようとしています。

私が使用しているコードは次のとおりです。

public class BlobCopyExampleClean {

    public static final String sourceStorageConnectionString =
            "DefaultEndpointsProtocol=https;"
            + "AccountName=sourceStorageAccount;"
            + "AccountKey=key123";

    public static final String destinationStorageConnectionString =
            "DefaultEndpointsProtocol=https;"
            + "AccountName=destinationStorageAccount;"
            + "AccountKey=key321";

    public static void main(String[] args) {

        try {
            CloudStorageAccount srcAccount = CloudStorageAccount.parse(sourceStorageConnectionString);
            CloudBlobClient srcSrvClient = srcAccount.createCloudBlobClient();
            CloudBlobContainer srcContainer = srcSrvClient.getContainerReference("vhds");

            CloudStorageAccount destAccount = CloudStorageAccount.parse(destinationStorageConnectionString);
            CloudBlobClient destSrvClient = destAccount.createCloudBlobClient();
            CloudBlobContainer destContainer = destSrvClient.getContainerReference("vhds");

            boolean result = destContainer.createIfNotExists();

            CloudBlob srcBlob = srcContainer.getPageBlobReference("testvm-2015-11-06.vhd");
            if (srcBlob.exists()) {
                CloudBlob destBlob = destContainer.getPageBlobReference("testvm-2015-11-06-copied.vhd");
                System.out.println("Starting blob copy...");
                String copyJobId = destBlob.startCopyFromBlob(srcBlob);

                CopyState copyState = destBlob.getCopyState();

                while (copyState.getStatus().equals(CopyStatus.PENDING)) {
                    System.out.println("... copying ...");
                    Thread.sleep(30000);
            }

                System.out.println("Copy complete, status was: " + copyState.getStatus() + "!");
            } else {
                System.out.println("Source blob does not exist!");
            }
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (StorageException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

何を試しても、常に次のエラーが返されます。

Starting blob copy...
com.microsoft.azure.storage.StorageException: The specified resource does not exist.
    at com.microsoft.azure.storage.StorageException.translateException(StorageException.java:89)
    at com.microsoft.azure.storage.core.StorageRequest.materializeException(StorageRequest.java:305)
    at com.microsoft.azure.storage.core.ExecutionEngine.executeWithRetry(ExecutionEngine.java:175)
    at com.microsoft.azure.storage.blob.CloudBlob.startCopy(CloudBlob.java:883)
    at com.microsoft.azure.storage.blob.CloudBlob.startCopyFromBlob(CloudBlob.java:788)
    at com.company.azure.storage.BlobCopyExampleClean.main(BlobCopyExampleClean.java:44)

SDK ライブラリの v1.3.1、v3.1.0、v4.0.0 を使用してみましたが、blob.startCopyFromBlob() (v1.3.1 & v3.1.0) と blob.startCopy() (v4.0) の両方を使用して同じエラーが発生します。 0.0)。

問題のページ BLOB にはリースがありません。Azure 管理ポータルでは、リースの状態が "Unlocked" であり、存在しているためです。Azure API でさえ、42 行目にコード ブロックを入力してこれを確認します。

BLOB を同じサブスクリプション内の別のストレージ アカウントにコピーしようとしましたが、同じエラーが発生します。

例外を詳しく見ると、エラー コードは「CannotVerifyCopySource」です。

4

1 に答える 1

3

重複は azure-storage-java ライブラリの問題 59に投稿されています。そこから私の回答と mirobers の回答をコピーします。

アカウント間で BLOB をコピーするには、ソースに SAS トークンを使用するか、パブリック アクセス用にソース コンテナーをマークする必要があります。次のページの「承認」セクションを参照してください: https://msdn.microsoft.com/en-us/library/azure/dd894037.aspx

たとえば、ソース BLOB への読み取りアクセスを許可する SAS トークンをコードで生成し、それをソース BLOB URL のクエリ文字列に追加して、URL からコピーを開始できます。特定の API を探している場合は、blob オブジェクトの generateSharedAccessSignature を調べてください。これによって返されたトークンを使用して、新しい CloudStorageAccount を作成し、上記のコード フローに従ってそこから BLOB 参照を取得するか、それを BLOB URL に追加し、CloudBlockBlob(URL) コンストラクターを使用して BLOB 参照を直接取得できます。

コードには、getCopyState がサービス呼び出しを行わないという別の問題があります。これは、以前に startCopy によって設定された BLOB コピーの状態を取得しているだけです。while ループ内では、実際に blob から更新されたコピー情報を取得するサービス呼び出しを実行する代わりに downloadAttributes を使用してみてください。

于 2015-11-09T18:07:55.893 に答える