[英]Use Azure Storage SDK for Java to copy VM page blob from one Azure subscription to another
我正在尝试使用Azure Storage SDK for Java将Azure VM的页面blob(已停止和取消分配)从一个Azure订阅复制到另一个Azure订阅。
这是我正在使用的代码:
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)。
有问题的页面blob没有租约,因为Azure管理门户说租约状态是“Unlocked”并且它确实存在,即使Azure API通过在第42行输入代码块来确认这一点。
我已经尝试将blob复制到同一订阅中的另一个存储帐户,并且也会产生相同的错误。
更详细地查看异常,错误代码是“CannotVerifyCopySource”。
重复发布在azure-storage-java库问题59中 。 从那里复制我和mirobers答案:
要跨帐户复制blob,您需要为源使用SAS令牌或将源容器标记为公共访问。 请参阅以下页面的“授权”部分: https : //msdn.microsoft.com/en-us/library/azure/dd894037.aspx
因此,例如,您的代码可以生成SAS令牌,授予对源blob的读访问权限,将其附加到源blob URL的查询字符串,然后从URL启动副本。 如果您正在寻找特定的API,请查看blob对象上的generateSharedAccessSignature。 您可以使用此返回的标记创建新的CloudStorageAccount,并按照上面的代码流从中获取blob引用,或将其附加到blob URL并使用CloudBlockBlob(URL)构造函数直接获取blob引用。
您的代码还有一个问题,即getCopyState不进行服务调用。 这只是获取之前由startCopy设置的blob复制状态。 在while循环中,您应该尝试使用downloadAttributes,它实际上会进行服务调用以从blob获取更新的复制信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.