java AmazonS3ClientBuilder.defaultClient() 无法考虑区域?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46697047/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 09:20:08  来源:igfitidea点击:

AmazonS3ClientBuilder.defaultClient() fails to account for region?

javaamazon-web-servicesamazon-s3aws-sdk

提问by Bob Kuhar

The Amazon Java SDK has marked the Constructors for AmazonS3Clientdeprecated 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 thisFailstest demonstrates the problem.

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

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.

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

回答by Battle_Slug

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

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

To emulate the previous behavior (no region configured), you'll need to also enable "forced global bucket access" in the client builder:

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

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();

This will suppress the exception you received and automatically retry the request under the region in the exception. It is made explicit in the builder so you are aware of this cross-region behavior. Note: The SDK will cache the bucket region after the first failure, so that every request against this bucket doesn't have to happen twice.

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



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

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

~/.aws/credentials contents:

~/.aws/credentials 内容:

[default]
aws_access_key_id = your_id
aws_secret_access_key = your_key

~/.aws/config contents:

~/.aws/config 内容:

[default]
region = us-west-1


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

在同一AWS 文档页面中,如果您不想对 region/credentials 进行硬编码,则可以按照通常的方式将其作为 Linux 机器中的环境变量:

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

回答by aly

    BasicAWSCredentials creds = new BasicAWSCredentials("key_ID", "Access_Key");
    AWSStaticCredentialsProvider provider = new 
    AWSStaticCredentialsProvider(creds);

    AmazonSQS sqs =AmazonSQSClientBuilder.standard()
    .withCredentials(provider)
    .withRegion(Regions.US_EAST_2)
    .build();

回答by Raj kumar Bhakthavachalam

Create file named "config" under .aws. And place below content.

在 .aws 下创建名为“config”的文件。并放置在内容下方。

~/.aws/config contents:

~/.aws/config 内容:

[default]
region = us-west-1
output = json