本文介绍了AmazonS3ClientBuilder.defaultClient() 无法考虑区域?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Amazon Java SDK 已将 AmazonS3Client 的构造函数标记为弃用,取而代之的是某些 AmazonS3ClientBuilder.defaultClient().但是,遵循该建议并不会产生工作相同的 AmazonS3 客户端.特别是,客户端以某种方式未能考虑区域.如果您运行下面的测试,thisFails 测试会说明问题.

公共类 S3HelperTest {@测试public void thisWorks() 抛出异常 {AmazonS3 s3Client = 新 AmazonS3Client();//此调用已弃用s3Client.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).build());assertNotNull(s3Client);}@测试public void thisFails() 抛出异常 {AmazonS3 s3Client = AmazonS3ClientBuilder.defaultClient();/** 以下行抛出类似 com.amazonaws.SdkClientException:* 无法通过区域供应商链找到区域.必须在构建器中提供明确的区域或* 设置环境以提供区域.*/s3Client.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).build());}}com.amazonaws.SdkClientException:无法通过区域提供商链找到区域.必须在构建器或设置环境中提供显式区域以提供区域.在 com.amazonaws.client.builder.AwsClientBuilder.setRegion(AwsClientBuilder.java:371)在 com.amazonaws.client.builder.AwsClientBuilder.configureMutableProperties(AwsClientBuilder.java:337)在 com.amazonaws.client.builder.AwsSyncClientBuilder.build(AwsSyncClientBuilder.java:46)在 com.amazonaws.services.s3.AmazonS3ClientBuilder.defaultClient(AmazonS3ClientBuilder.java:54)在 com.climate.tenderfoot.service.S3HelperTest.thisFails(S3HelperTest.java:21)...

这是 AWS SDK 错误吗?是否有一些区域默认提供者链"或某种机制可以从环境中派生区域并将其设置到客户端中?替换弃用的方法不会导致相同的功能,这似乎真的很弱.

解决方案

看起来像 builder 需要一个区域.可能 这个线程 是相关的(我会使用 .withRegion(Regions.US_EAST_1) 虽然在第三行):

要模拟以前的行为(未配置区域),您需要还要在客户端构建器中启用强制全局存储桶访问":

AmazonS3 客户端 =AmazonS3ClientBuilder.standard().withRegion("us-east-1")//第一个尝试你的请求的区域.withForceGlobalBucketAccess(true)//如果bucket在不同的区域,请在正确的区域重试.建造();

这将抑制您收到的异常并自动重试请求下的区域在异常中.它在构建器,以便您了解这种跨区域行为.注意:SDK会在第一次失败后缓存bucket区域,以便针对此存储桶的每个请求不必发生两次.

此外,来自 AWS 文档 如果你想使用 AmazonS3ClientBuilder.defaultClient(); 那么你需要有~/.aws/credentials 和 ~/.aws/config 文件

~/.aws/credentials 内容:

[默认]aws_access_key_id = your_idaws_secret_access_key = your_key

~/.aws/config 内容:

[默认]地区 = us-west-1

来自相同的 AWS 文档 页面,如果您不想对区域/凭据进行硬编码,您可以按照通常的方式将其作为 Linux 机器中的环境变量:

导出 AWS_ACCESS_KEY_ID=your_access_key_id导出 AWS_SECRET_ACCESS_KEY=your_secret_access_key导出 AWS_REGION=your_aws_region

The Amazon Java SDK has marked the Constructors for AmazonS3Client deprecated in favor of some AmazonS3ClientBuilder.defaultClient(). Following the recommendation, though, does not result in an AmazonS3 client that works the same. In particular, the client has somehow failed to account for Region. If you run the tests below, the thisFails test demonstrates the problem.

public class S3HelperTest {
  @Test
  public void thisWorks() throws Exception {
    AmazonS3 s3Client = new AmazonS3Client();  // this call is deprecated
    s3Client.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).build());
    assertNotNull(s3Client);
  }

  @Test
  public void thisFails() throws Exception {
    AmazonS3 s3Client = AmazonS3ClientBuilder.defaultClient();
    /*
     * The following line throws like com.amazonaws.SdkClientException:
     * Unable to find a region via the region provider chain. Must provide an explicit region in the builder or
     * setup environment to supply a region.
     */
    s3Client.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).build());
  }
}

com.amazonaws.SdkClientException: Unable to find a region via the region provider chain. Must provide an explicit region in the builder or setup environment to supply a region.
    at com.amazonaws.client.builder.AwsClientBuilder.setRegion(AwsClientBuilder.java:371)
    at com.amazonaws.client.builder.AwsClientBuilder.configureMutableProperties(AwsClientBuilder.java:337)
    at com.amazonaws.client.builder.AwsSyncClientBuilder.build(AwsSyncClientBuilder.java:46)
    at com.amazonaws.services.s3.AmazonS3ClientBuilder.defaultClient(AmazonS3ClientBuilder.java:54)
    at com.climate.tenderfoot.service.S3HelperTest.thisFails(S3HelperTest.java:21)
    ...

Is this an AWS SDK Bug? Is there some "region default provider chain" or some mechanism to derive the region from the Environment and set it into the client? It seems really weak that the method to replace the deprecation doesn't result in the same capability.

解决方案

Looks like a region is required for the builder.Probably this thread is related (I would use .withRegion(Regions.US_EAST_1) though in the 3rd line):

AmazonS3 client =
        AmazonS3ClientBuilder.standard()
                             .withRegion("us-east-1") // The first region to try your request against
                             .withForceGlobalBucketAccess(true) // If a bucket is in a different region, try again in the correct region
                             .build();


Also, from the AWS documentation if you want to use AmazonS3ClientBuilder.defaultClient(); then you need to have~/.aws/credentials and ~/.aws/config files

~/.aws/credentials contents:

[default]
aws_access_key_id = your_id
aws_secret_access_key = your_key

~/.aws/config contents:

[default]
region = us-west-1


From the same AWS documentation page, if you don't want to hardcode the region/credentials, you can have it as environment variables in your Linux machine the usual way:

export AWS_ACCESS_KEY_ID=your_access_key_id
export AWS_SECRET_ACCESS_KEY=your_secret_access_key
export AWS_REGION=your_aws_region

这篇关于AmazonS3ClientBuilder.defaultClient() 无法考虑区域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 08:10