简体   繁体   English

使用 Java v12 SDK 在 Azure Blob 存储中复制 Blob

[英]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,请参考以下详细信息

  • Copy blobs between storage accounts在存储帐户之间复制 blob

If you copy blobs between storage accounts with Azure MSI.如果使用 Azure MSI 在存储帐户之间复制 Blob。 We should do the following actions我们应该做以下的动作

  1. Assign Azure Storage Blob Data Reader to the MSI in the source container将 Azure Storage Blob Data Reader分配给源容器中的 MSI

  2. 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

  3. 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();
        }

在此处输入图片说明

  • Copy in the same account复制到同一个账号

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.

相关问题 如何使用新的 Java v12 SDK 为 Azure Blob 存储检索分段的容器列表? - How to retrieve a segmented List of Containers using the new Java v12 SDK for Azure Blob Storage? Azure Blob 存储 SDK v12 - BlobClient DownloadAsync 消失了吗? - Azure Blob Storage SDK v12 - BlobClient DownloadAsync gone? 使用 spring boot 在 azure 中从 v8 升级到 v12 java sdk 后无法连接到 azure-blob-storage - Unable to connect to azure-blob-storage after upgrading from v8 to v12 java sdk in azure using spring boot 如何使用 Azure.Storage v12 SDK 从 Azure Blob 中删除元数据? - How can I remove metadata from an Azure Blob using Azure.Storage v12 SDK? 如何使用新的 Azure 存储 SDK v12 打开可写 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ 到新 Blob? - How can I open a writeable stream to a new Blob using the new Azure Storage SDK v12? 使用带有 Python V12 SDK 的 BlobServiceClient 将本地文件夹上传到 Azure Blob 存储 - Upload local folder to Azure Blob Storage using BlobServiceClient with Python V12 SDK 如何使用 .NET v12 SDK 在 Azure Blob 存储中使用指定的 ContentType 上传 Blob? - How upload blob in Azure Blob Storage with specified ContentType with .NET v12 SDK? 使用指定的 ContentType 将 blob 上传到 Azure Blob 存储并同时覆盖(.NET v12 SDK)? - Upload blob into Azure Blob Storage with specified ContentType and overwrite same time (.NET v12 SDK)? 使用 Azure 下载 Blob Blob 存储客户端库 v12 for .NET - Download blob using Azure Blob storage client library v12 for .NET ContentHash 未在 Azure Blob Storage v12 中计算 - ContentHash not calculated in Azure Blob Storage v12
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM