2017-10-11 66 views
1

Amazon Java SDK已經標記爲AmazonS3Client的構造函數,因此棄用了某些AmazonS3ClientBuilder.defaultClient()。但是,按照建議,不會導致AmazonS3客戶端的工作方式相同。特別是,客戶以某種方式未能考慮區域。如果您運行以下測試,則thisFails測試將演示此問題。AmazonS3ClientBuilder.defaultClient()無法解釋區域?

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

這是一個AWS開發工具包錯誤?是否有一些「區域默認提供商鏈」或某種機制從環境中派生出該區域並將其設置爲客戶端?替代棄用的方法看起來確實很弱,並不會產生相同的能力。

+0

下面是我如何創建s3client: AmazonS3 s3client = AmazonS3ClientBuilder.standard()。build(); –

+0

@JohnHanley由於部署到多個區域,我有點不情願硬編碼'withRegion(「us-east-1」)'作爲這個應用程序。我想我可以從環境中派生出來,但我對實例憑證的工作方式不夠熟悉,並且擔心在部署到AWS時我的桌面上工作的某些內容會失敗。我很善良,希望通過某種方式來利用DefaultAwsRegionProviderChain。 –

+0

標準的方法是使用「環境變量」。我沒有使用DefaultAwsRegionProviderChain,因爲我知道我的存儲桶在哪裏,我把它放在環境變量中。 –

回答

3

看起來像一個地區是建設者所必需的。 大概this thread是相關的(我會在第三行中使用.withRegion(Regions.US_EAST_1)雖然):

爲了模擬以前的行爲(沒有配置區域),你需要 還啓用了「強制全局分區的訪問權限」客戶端生成器:

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

這會壓制你接收到異常,並自動重試 在異常區之下的請求。它在 明確了建設者,所以你知道這個跨區域的行爲。注意: SDK將在第一次失敗後緩存存儲區域,以便對該存儲桶的每個請求都不必發生兩次。


此外,從AWS documentation如果你想使用AmazonS3ClientBuilder.defaultClient();,那麼你需要有 〜/ .aws /憑證和〜/ .aws /配置文件

〜/ .aws /憑證內容:

[default] 
aws_access_key_id = your_id 
aws_secret_access_key = your_key 

〜/ .aws /配置內容:

[default] 
region = us-west-1 

從同一AWS documentation頁,如果你不想硬編碼區域/憑證,你可以把它作爲你的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 
+0

這個答案大部分是正確的,或者至少指出我的方向是正確的。如果我只是創建'〜/ .aws/config'文件並在那裏設置默認區域,那麼'''AmazonS3ClientBuilder.standard()。withPathStyleAccessEnabled(true).build();'''完成工作 –

+0

在環境中定義'AWS_REGION'也可以完成它。 –