[英]Copy Blob in Azure Blob Storage using Java v12 SDK
My Application is in a Kubernetes cluster and I'm using Java v12 SDK to interact with the Blob Storage.我的应用程序位于 Kubernetes 集群中,我使用Java v12 SDK与 Blob 存储进行交互。 To authorize against Blob Storage I'm using Managed Identities.
为了对 Blob 存储进行授权,我使用了托管身份。
My application needs to copy blobs within one container.我的应用程序需要在一个容器中复制 blob。 I haven't found any particular recommendations or examples of how SDK should be used to do the copy.
我还没有找到任何关于如何使用 SDK 进行复制的特定建议或示例。
I figured that the following approach works when I'm working with the emulator我认为以下方法在我使用模拟器时有效
copyBlobClient.copyFromUrl(sourceBlobClient.getBlobUrl());
However, when this gets executed in the cluster I get the following error但是,当这在集群中执行时,我收到以下错误
<Error>
<Code>CannotVerifyCopySource</Code>
<Message>The specified resource does not exist. RequestId: __ Time: __ </Message>
</Error>
Message says "resource does not exist" but the blob is clearly there.消息说“资源不存在”,但 blob 显然在那里。 My container has private access, though.
不过,我的容器具有私有访问权限。
Now when I change the public access level to "Blob(anonymous read access for blobs only)" everything works as excepted.现在,当我将公共访问级别更改为“Blob(仅对 Blob 进行匿名读取访问)”时,一切正常。 However, public access not acceptable to me.
但是,我无法接受公共访问。
Main question - what are the right ways to implement copy blob using Java v12 SDK.主要问题 - 使用 Java v12 SDK 实现复制 blob 的正确方法是什么。
What I could miss or misconfigured in my situation?在我的情况下,我可能会错过什么或配置错误?
And the last is the error message itself.最后一个是错误消息本身。 There is a part which says "CannotVerifyCopySource" which kind of helps you understand that there is something with access, but the message part is clearly misleading.
有一个部分说“CannotVerifyCopySource”,它可以帮助您了解有访问权限的内容,但消息部分显然具有误导性。 Shouldn't it be more explicit about the error?
不应该更明确地说明错误吗?
If you want to use Azure JAVA SDK to copy blob with Azure MSI, please refer to the following details如果要使用Azure JAVA SDK 使用Azure MSI 复制blob,请参考以下详细信息
If you copy blobs between storage accounts with Azure MSI.如果使用 Azure MSI 在存储帐户之间复制 Blob。 We should do the following actions
我们应该做以下的动作
Assign Azure Storage Blob Data Reader
to the MSI in the source container将 Azure
Storage Blob Data Reader
分配给源容器中的 MSI
Assign Azure Storage Blob Data Contributor
to the MSI in the dest container.将 Azure
Storage Blob Data Contributor
分配给目标容器中的 MSI。 Besides when we copy blob, we need write permissions to write content to blob除了复制blob的时候,我们还需要写权限才能将内容写入blob
Generate SAS token for the blob.为 blob 生成 SAS 令牌。 If the souce blob is public, we can directly use source blob URL without sas token.
如果源 blob 是公开的,我们可以直接使用源 blob URL,而无需 sas 令牌。
For example例如
try {
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
.endpoint("https://<>.blob.core.windows.net/" )
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
// get User Delegation Key
OffsetDateTime delegationKeyStartTime = OffsetDateTime.now();
OffsetDateTime delegationKeyExpiryTime = OffsetDateTime.now().plusDays(7);
UserDelegationKey key =blobServiceClient.getUserDelegationKey(delegationKeyStartTime,delegationKeyExpiryTime);
BlobContainerClient sourceContainerClient = blobServiceClient.getBlobContainerClient("test");
BlobClient sourceBlob = sourceContainerClient.getBlobClient("test.mp3");
// generate sas token
OffsetDateTime expiryTime = OffsetDateTime.now().plusDays(1);
BlobSasPermission permission = new BlobSasPermission().setReadPermission(true);
BlobServiceSasSignatureValues myValues = new BlobServiceSasSignatureValues(expiryTime, permission)
.setStartTime(OffsetDateTime.now());
String sas =sourceBlob.generateUserDelegationSas(myValues,key);
// copy
BlobServiceClient desServiceClient = new BlobServiceClientBuilder()
.endpoint("https://<>.blob.core.windows.net/" )
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
BlobContainerClient desContainerClient = blobServiceClient.getBlobContainerClient("test");
String res =desContainerClient.getBlobClient("test.mp3")
.copyFromUrl(sourceBlob.getBlobUrl()+"?"+sas);
System.out.println(res);
} catch (Exception e) {
e.printStackTrace();
}
If you copy blobs in the same storage account with Azure MSI, I suggest you assign Storage Blob Data Contributor
to the MSI in the storage account.如果您使用 Azure MSI 在同一存储帐户中复制 Blob,我建议您将
Storage Blob Data Contributor
分配给存储帐户中的 MSI。 Then we can do copy action with the method copyFromUrl
.然后我们可以使用
copyFromUrl
方法进行复制操作。
For example例如
a.一种。 Assign
Storage Blob Data Contributor
to the MSI at the account level在帐户级别将
Storage Blob Data Contributor
分配给 MSI
b.湾code
代码
try {
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
.endpoint("https://<>.blob.core.windows.net/" )
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
BlobContainerClient sourceContainerClient = blobServiceClient.getBlobContainerClient("test");
BlobClient sourceBlob = sourceContainerClient.getBlobClient("test.mp3");
BlobContainerClient desContainerClient = blobServiceClient.getBlobContainerClient("output");
String res =desContainerClient.getBlobClient("test.mp3")
.copyFromUrl(sourceBlob.getBlobUrl());
System.out.println(res);
} catch (Exception e) {
e.printStackTrace();
}
For more details, please refer to here and here欲了解更多详情,请参阅此处和此处
I had the same issue using the Java SDK for Azure I solved it by copying the blob using the URL + the SAS token.我在使用 Java SDK for Azure 时遇到了同样的问题,我通过使用 URL + SAS 令牌复制 blob 解决了这个问题。 Actually the resource you're getting through the URL won't appear as available if you don't have the right access to it.
实际上,如果您没有正确的访问权限,您通过 URL 获得的资源将不会显示为可用。 Here is the code I used to solve the problem:
这是我用来解决问题的代码:
BlobClient sourceBlobClient = blobServiceClient
.getBlobContainerClient(currentBucketName)
.getBlobClient(sourceKey);
// initializing the copy blob client
BlobClient copyBlobClient = blobServiceClient
.getBlobContainerClient(newBucketName)
.getBlobClient(newKey);
// Creating the SAS Token to get the permission to copy the source blob
OffsetDateTime expiryTime = OffsetDateTime.now().plusDays(1);
BlobSasPermission permission = new BlobSasPermission().setReadPermission(true);
BlobServiceSasSignatureValues values = new BlobServiceSasSignatureValues(expiryTime, permission)
.setStartTime(OffsetDateTime.now());
String sasToken = sourceBlobClient.generateSas(values);
//Making the copy using the source blob URL + generating the copy
var res = copyBlobClient.copyFromUrl(sourceBlobClient.getBlobUrl() +"?"+ sasToken);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.