

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Programmation asynchrone à l'aide du AWS SDK for Java 2.x
<a name="asynchronous"></a>

 AWS SDK for Java 2.x Il propose des clients asynchrones avec un I/O support non bloquant qui implémentent une simultanéité élevée sur quelques threads. Cependant, le non-blocage total n' I/O est pas garanti. Le client asynchrone peut bloquer les appels dans certains cas, tels que la récupération des informations d'identification, la signature des demandes à l'aide de [AWS Signature Version 4 (SigV4)](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html) ou la découverte des terminaux. 

Les méthodes synchrones bloquent l'exécution du thread jusqu'à ce que le client reçoive une réponse du service. Les méthodes asynchrones renvoient immédiatement, en rendant le contrôle au thread appelant sans attendre de réponse.

Dans la mesure où une méthode asynchrone renvoie avant qu'une réponse ne soit disponible, vous avez besoin d'une solution pour obtenir la réponse quand elle est prête. Les méthodes pour le client asynchrone dans la version 2.x des *CompletableFuture objets* de AWS SDK pour Java retour qui vous permettent d'accéder à la réponse lorsqu'elle est prête.

## Utiliser un client asynchrone APIs
<a name="basics-async-non-streaming"></a>

*Les signatures des méthodes client asynchrones sont les mêmes que leurs homologues synchrones, mais les méthodes asynchrones renvoient un [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/CompletableFuture.html)objet contenant les résultats de l'opération asynchrone à venir.* Si une erreur est renvoyée pendant l'exécution de la méthode asynchrone du SDK, l'erreur est renvoyée sous la forme. `CompletionException` 

Une approche que vous pouvez utiliser pour obtenir le résultat consiste à enchaîner une `whenComplete()` méthode sur celle `CompletableFuture` renvoyée par l'appel de méthode du SDK. La `whenComplete()` méthode reçoit le résultat ou un objet Throwable de type `CompletionException` dépendant de la façon dont l'appel asynchrone s'est terminé. Vous fournissez une action pour `whenComplete()` traiter ou vérifier les résultats avant qu'ils ne soient renvoyés au code d'appel.

Si vous souhaitez renvoyer autre chose que l'objet renvoyé par la méthode SDK, utilisez plutôt la `handle()` méthode. La `handle()` méthode prend les mêmes paramètres que`whenComplete()`, mais vous pouvez traiter le résultat et renvoyer un objet.

Pour attendre la fin de la chaîne asynchrone et récupérer les résultats d'achèvement, vous pouvez appeler la `join()` méthode. Si l'`Throwable`objet n'a pas été traité dans la chaîne, la `join()` méthode renvoie une valeur non cochée `CompletionException` qui enveloppe l'exception d'origine. Vous accédez à l'exception d'origine avec`CompletionException#getCause()`. Vous pouvez également appeler la `CompletableFuture#get()` méthode pour obtenir les résultats d'achèvement. La `get()` méthode peut toutefois générer des exceptions vérifiées.

L'exemple suivant montre deux variantes de la façon dont vous pouvez utiliser la `listTables()` méthode du client asynchrone DynamoDB. L'action passée à enregistre `whenComplete()` simplement une réponse réussie, tandis que la `handle()` version extrait la liste des noms de tables et renvoie la liste. Dans les deux cas, si une erreur est générée dans la chaîne asynchrone, l'erreur est renvoyée afin que le code client ait une chance de la gérer.

 **Importations** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import software.amazon.awssdk.services.dynamodb.model.ListTablesRequest;
import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse;

import java.util.List;
import java.util.concurrent.CompletableFuture;
```

 **Code** 

------
#### [ whenComplete() variation ]

```
public class DynamoDbAsyncListTables {

    public static void main(String[] args) {
        Region region = Region.US_EAST_1;
        DynamoDbAsyncClient dynamoDbAsyncClient = DynamoDbAsyncClient.builder().region(region).build();
        try {
            ListTablesResponse listTablesResponse = listTablesWhenComplete(dynamoDbAsyncClient).join();  // The join() method may throw a CompletionException.
            if (listTablesResponse.hasTableNames()){
                System.out.println("Table exist in this region: " + region.id());
            }
        } catch (RuntimeException e) {
            // Handle as needed. Here we simply print out the class names.
            System.out.println(e.getClass()); // Prints 'class java.util.concurrent.CompletionException'.
            System.out.println(e.getCause().getClass()); // Prints 'class software.amazon.awssdk.services.dynamodb.model.DynamoDbException'.
        }
    }

    public static CompletableFuture<ListTablesResponse> listTablesWhenComplete(DynamoDbAsyncClient client) {
        return client.listTables(ListTablesRequest.builder().build())
            .whenComplete((listTablesResponse, throwable) -> {
                if (listTablesResponse != null) {  // Consume the response.
                    System.out.println("The SDK's listTables method completed successfully.");
                } else {
                    RuntimeException cause = (RuntimeException) throwable.getCause(); // If an error was thrown during the SDK's listTables method it is wrapped in a CompletionException.
                                                                                      // The SDK throws only RuntimeExceptions, so this is a safe cast.
                    System.out.println(cause.getMessage());  // Log error here, but rethrow so the calling code can handle as needed.
                    throw cause;
                }
            });
    }
```

------
#### [ handle() variation ]

```
public class DynamoDbAsyncListTables {

    public static void main(String[] args) {
        Region region = Region.US_EAST_1;
        DynamoDbAsyncClient dynamoDbAsyncClient = DynamoDbAsyncClient.builder().region(region).build();
        try {
            List<String> tableNames = listTablesHandle(dynamoDbAsyncClient).join(); // The join() method may throw a CompletionException.
            tableNames.forEach(System.out::println);
        } catch (RuntimeException e) {
            // Handle as needed. Here we simply print out the class names.
            System.out.println(e.getClass()); // Prints 'class java.util.concurrent.CompletionException'.
            System.out.println(e.getCause().getClass()); // Prints 'class software.amazon.awssdk.services.dynamodb.model.DynamoDbException'.
        }
    }

    public static CompletableFuture<List<String>> listTablesHandle(DynamoDbAsyncClient client) {
        return client.listTables(ListTablesRequest.builder().build())
            .handle((listTablesResponse, throwable) -> {
                if (listTablesResponse != null) {
                    return listTablesResponse.tableNames(); // Return the list of table names.
                } else {
                    RuntimeException cause = (RuntimeException) throwable.getCause(); // If an error was thrown during the SDK's listTables method it is wrapped in a CompletionException.
                                                                                      // The SDK throws only RuntimeExceptions, so this is a safe cast.
                    System.out.println(cause.getMessage());  // Log error here, but rethrow so the calling code can handle as needed.
                    throw cause;
                }
            });
    }
}
```

------

## Gérez le streaming dans des méthodes asynchrones
<a name="basics-async-streaming"></a>

Pour les méthodes asynchrones avec du contenu en streaming, vous devez fournir un [AsyncRequestBody](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncRequestBody.html)pour fournir le contenu de manière incrémentielle, ou un [AsyncResponseTransformer](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncResponseTransformer.html)pour recevoir et traiter la réponse.

L'exemple suivant télécharge un fichier de Amazon S3 manière asynchrone en utilisant la forme asynchrone de l'opération. `PutObject`

 **Importations** 

```
import software.amazon.awssdk.core.async.AsyncRequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
import java.nio.file.Paths;
import java.util.concurrent.CompletableFuture;
```

 **Code** 

```
/**
 * To run this AWS code example, ensure that you have setup your development environment, including your AWS credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class S3AsyncOps {

     public static void main(String[] args) {

         final String USAGE = "\n" +
                 "Usage:\n" +
                 "    S3AsyncOps <bucketName> <key> <path>\n\n" +
                 "Where:\n" +
                 "    bucketName - the name of the Amazon S3 bucket (for example, bucket1). \n\n" +
                 "    key - the name of the object (for example, book.pdf). \n" +
                 "    path - the local path to the file (for example, C:/AWS/book.pdf). \n" ;

        if (args.length != 3) {
            System.out.println(USAGE);
             System.exit(1);
        }

        String bucketName = args[0];
        String key = args[1];
        String path = args[2];

        Region region = Region.US_WEST_2;
        S3AsyncClient client = S3AsyncClient.builder()
                .region(region)
                .build();

        PutObjectRequest objectRequest = PutObjectRequest.builder()
                .bucket(bucketName)
                .key(key)
                .build();

        // Put the object into the bucket
        CompletableFuture<PutObjectResponse> future = client.putObject(objectRequest,
                AsyncRequestBody.fromFile(Paths.get(path))
        );
        future.whenComplete((resp, err) -> {
            try {
                if (resp != null) {
                    System.out.println("Object uploaded. Details: " + resp);
                } else {
                    // Handle error
                    err.printStackTrace();
                }
            } finally {
                // Only close the client when you are completely done with it
                client.close();
            }
        });

        future.join();
    }
}
```

L'exemple suivant extrait un fichier à l'aide Amazon S3 de la forme asynchrone de l'`GetObject`opération.

 **Importations** 

```
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import java.nio.file.Paths;
import java.util.concurrent.CompletableFuture;
```

 **Code** 

```
/**
 * To run this AWS code example, ensure that you have setup your development environment, including your AWS credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class S3AsyncStreamOps {

    public static void main(String[] args) {

        final String USAGE = "\n" +
                "Usage:\n" +
                "    S3AsyncStreamOps <bucketName> <objectKey> <path>\n\n" +
                "Where:\n" +
                "    bucketName - the name of the Amazon S3 bucket (for example, bucket1). \n\n" +
                "    objectKey - the name of the object (for example, book.pdf). \n" +
                "    path - the local path to the file (for example, C:/AWS/book.pdf). \n" ;

        if (args.length != 3) {
            System.out.println(USAGE);
            System.exit(1);
         }

        String bucketName = args[0];
        String objectKey = args[1];
        String path = args[2];

        Region region = Region.US_WEST_2;
        S3AsyncClient client = S3AsyncClient.builder()
                .region(region)
                .build();

        GetObjectRequest objectRequest = GetObjectRequest.builder()
                .bucket(bucketName)
                .key(objectKey)
                .build();

        CompletableFuture<GetObjectResponse> futureGet = client.getObject(objectRequest,
                AsyncResponseTransformer.toFile(Paths.get(path)));

        futureGet.whenComplete((resp, err) -> {
            try {
                if (resp != null) {
                    System.out.println("Object downloaded. Details: "+resp);
                } else {
                    err.printStackTrace();
                }
            } finally {
               // Only close the client when you are completely done with it
                client.close();
            }
        });
        futureGet.join();
    }
}
```

## Configuration des options asynchrones avancées
<a name="advanced-operations"></a>

La version AWS SDK pour Java 2.x utilise [Netty](https://netty.io), un framework d'applications réseau asynchrone piloté par des événements, pour gérer les threads. I/O Le AWS SDK pour Java 2.x crée un `ExecutorService` Behind Netty, pour compléter les futures renvoyés par la demande du client HTTP jusqu'au client Netty. Cette abstraction réduit le risque qu'une application interrompe le processus asynchrone si les développeurs choisissent d'arrêter ou de mettre des threads en veille. Par défaut, chaque client asynchrone crée un pool de threads basé sur le nombre de processeurs et gère les tâches d'une file d'attente au sein du. `ExecutorService`

Vous pouvez spécifier une implémentation JDK spécifique `ExecutorService` lorsque vous créez votre client asynchrone. L'extrait suivant crée un `ExecutorService` avec un nombre fixe de threads.

 **Code** 

```
S3AsyncClient clientThread = S3AsyncClient.builder()
  .asyncConfiguration(
    b -> b.advancedOption(SdkAdvancedAsyncClientOption
      .FUTURE_COMPLETION_EXECUTOR,
      Executors.newFixedThreadPool(10)
    )
  )
  .build();
```

Pour optimiser les performances, vous pouvez gérer votre propre exécuteur de pool de threads et l'inclure lorsque vous configurez votre client.

```
ThreadPoolExecutor executor = new ThreadPoolExecutor(50, 50,
    10, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(<custom_value>),
    new ThreadFactoryBuilder()
      .threadNamePrefix("sdk-async-response").build());

// Allow idle core threads to time out
executor.allowCoreThreadTimeOut(true);

S3AsyncClient clientThread = S3AsyncClient.builder()
  .asyncConfiguration(
    b -> b.advancedOption(SdkAdvancedAsyncClientOption
      .FUTURE_COMPLETION_EXECUTOR,
      executor
    )
  )
  .build();
```