2017-10-11 10 views
1

Le SDK Amazon Java a marqué les constructeurs pour AmazonS3Client désapprouvé au profit de certains AmazonS3ClientBuilder.defaultClient(). Cependant, suivre la recommandation n'aboutit pas à un client AmazonS3 qui fonctionne de la même manière. En particulier, le client n'a pas réussi à rendre compte de la région. Si vous exécutez les tests ci-dessous, le test thisFails montre le problème.AmazonS3ClientBuilder.defaultClient() ne peut pas tenir compte de la région?

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

Est-ce un bogue AWS SDK? Existe-t-il une «chaîne de fournisseurs par défaut dans la région» ou un mécanisme permettant de dériver la région de l'environnement et de la définir dans le client? Il semble vraiment faible que la méthode pour remplacer la dépréciation ne donne pas la même capacité.

+0

Ci-dessous est comment je crée le client s3: AmazonS3 s3client = AmazonS3ClientBuilder.standard(). build(); –

+0

@JohnHanley Je suis un peu réticent à coder le 'withRegion (" us-east-1 ")' comme cette application doit être déployée dans plusieurs régions. J'imagine que je pourrais en tirer des conclusions sur l'environnement, mais je ne connais pas assez le fonctionnement des informations d'identification des instances et je crains que mon travail sur mon bureau échoue lorsqu'il est déployé dans AWS. J'espérais trouver un moyen de tirer parti de DefaultAwsRegionProviderChain. –

+0

La méthode standard consiste à utiliser les "variables d'environnement". Je n'ai pas utilisé DefaultAwsRegionProviderChain car je sais où est mon compartiment et je l'ai mis dans les variables d'environnement. –

Répondre

3

On dirait qu'une région est requise pour le constructeur. Probablement this thread est lié (j'utilise .withRegion(Regions.US_EAST_1) bien que dans la 3ème ligne):

Pour imiter le comportement précédent (aucune région configurée), vous aurez besoin pour permettre également « l'accès seau global forcé » dans la constructeur de client:

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

Cela supprime l'exception que vous avez reçu et réessayer automatiquement la demande dans la région à l'exception. Il est explicite dans le constructeur de sorte que vous êtes conscient de ce comportement inter-région. Remarque: Le SDK mettra en cache la région du compartiment après la première défaillance, de sorte que chaque demande concernant ce compartiment ne doit pas se produire deux fois.


En outre, à partir du AWS documentation si vous voulez utiliser AmazonS3ClientBuilder.defaultClient(); alors vous devez avoir ~/.AWS/pouvoirs et ~/.AWS/fichiers de configuration

~/.AWS/lettres de créance contenu:

[default] 
aws_access_key_id = your_id 
aws_secret_access_key = your_key 

~/.AWS/contenu config:

[default] 
region = us-west-1 

De la même page AWS documentation, si vous ne voulez pas hardcode la région/lettres de créance, vous pouvez l'avoir comme variables d'environnement dans votre machine Linux de la manière habituelle:

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

Cette réponse est la plupart du temps correcte, ou m'a indiqué dans la bonne direction au moins. Si je crée simplement ce fichier '~/.aws/config' et que la région par défaut est configurée, alors' '' AmazonS3ClientBuilder.standard(). WithPathStyleAccessEnabled (true) .build(); '' 'fait le travail –

+0

Définir 'AWS_REGION' dans l'environnement le fait aussi. –