

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Usando o AWS SDK for Java 2.x
<a name="using"></a>

Este capítulo mostra como usar o de AWS SDK for Java 2.x forma eficaz. Aprenda a criar clientes de serviço, fazer solicitações, processar respostas e gerenciar erros. O capítulo aborda programação síncrona e assíncrona, resultados paginados, esperas para monitoramento de recursos e otimização de desempenho. 

Você também poderá consultar as práticas recomendadas para reutilização de clientes, orientação para solução de problemas, otimização de inicialização do Lambda, suporte a HTTP/2 e configuração de DNS.

**Contents**
+ [

# Fazendo AWS service (Serviço da AWS) solicitações usando o AWS SDK for Java 2.x
](work-witih-clients.md)
  + [

## Usar clientes de serviço para fazer solicitações
](work-witih-clients.md#using-service-client)
    + [

### Crie um cliente de serviço
](work-witih-clients.md#work-with-clients-create)
    + [

### Configuração padrão de cliente
](work-witih-clients.md#using-default-client)
    + [

### Configurar clientes de serviço
](work-witih-clients.md#using-configure-service-clients)
    + [

### Feche o cliente de serviço
](work-witih-clients.md#using-closing-client)
  + [

## Fazer solicitações.
](work-witih-clients.md#using-making-requests)
    + [

### Usar solicitações para substituir a configuração do cliente
](work-witih-clients.md#using-override-client-config-request)
  + [

## Manipulador de resposta
](work-witih-clients.md#using-handling-responses)
+ [

# Programação assíncrona usando o AWS SDK for Java 2.x
](asynchronous.md)
  + [

## Usar APIs de cliente assíncrono
](asynchronous.md#basics-async-non-streaming)
  + [

## Gerenciar o streaming em métodos assíncronos
](asynchronous.md#basics-async-streaming)
  + [

## Configurar opções assíncronas avançadas
](asynchronous.md#advanced-operations)
+ [

# Melhores práticas para usar o AWS SDK for Java 2.x
](best-practices.md)
  + [

## Evitar solicitações suspensas configurando os tempos limite da API
](best-practices.md#bestpractice5)
  + [

## Melhorar o desempenho reutilizando clientes de serviço
](best-practices.md#bestpractice1)
  + [

## Evitar vazamentos de recursos fechando clientes de serviços não utilizados
](best-practices.md#bestpractice-close-client)
  + [

## Evitar o esgotamento do pool de conexões fechando os fluxos de entrada
](best-practices.md#bestpractice2)
  + [

## Otimizar o desempenho HTTP para a workload da aplicação
](best-practices.md#bestpractice3)
  + [

## Melhore o desempenho do SSL com o OpenSSL para clientes assíncronos
](best-practices.md#bestpractice4)
  + [

## Monitorar o desempenho de aplicações com métricas de SDK
](best-practices.md#bestpractice6)
+ [

# Tratamento de erros no AWS SDK for Java 2.x
](handling-exceptions.md)
  + [

## Por que exceções desmarcadas?
](handling-exceptions.md#why-unchecked-exceptions)
  + [

## AwsServiceException (e subclasses)
](handling-exceptions.md#sdkserviceexception-and-subclasses)
  + [

## SdkClientException
](handling-exceptions.md#sdkclientexception)
  + [

## Exceções e comportamento de nova tentativa
](handling-exceptions.md#retried-exceptions)
+ [

# Usando resultados paginados no 2.x AWS SDK para Java
](pagination.md)
  + [

## Paginação síncrona
](pagination.md#synchronous-pagination)
    + [

### Iterar sobre páginas
](pagination.md#iterate-pages)
    + [

### Iterar sobre objetos
](pagination.md#iterate-objects)
      + [

#### Usar um stream
](pagination.md#use-a-stream)
      + [

#### Usar um loop for-each
](pagination.md#for-loop)
    + [

### Paginação manual
](pagination.md#manual-pagination)
  + [

## Paginação assíncrona
](pagination.md#asynchronous-pagination)
    + [

### Iterar sobre páginas de nomes de tabelas
](pagination.md#iterate-pages-async)
      + [

#### Usar um `Subscriber`
](pagination.md#use-a-subscriber)
      + [

#### Usar um `Consumer`
](pagination.md#id1pagination)
    + [

### Iterar sobre nomes de tabela
](pagination.md#iterate-objects-async)
      + [

#### Usar um `Subscriber`
](pagination.md#id2)
      + [

#### Usar um `Consumer`
](pagination.md#for-loop-async)
    + [

### Usar bibliotecas de terceiros
](pagination.md#use-third-party-library)
+ [

# Usando garçons no AWS SDK for Java 2.x
](waiters.md)
  + [

## Pré-requisitos
](waiters.md#prerequisiteswaiters)
  + [

## Usar agentes de espera
](waiters.md#id1waiters)
    + [

### Programação síncrona
](waiters.md#synchronous-programming)
    + [

### Programação assíncrona
](waiters.md#asynchronous-programming)
  + [

## Configurar waiters
](waiters.md#configuring-waiters)
    + [

### Configurar um waiter
](waiters.md#configure-a-waiter)
    + [

### Substituir configuração para uma solicitação específica
](waiters.md#override-configuration-for-a-specific-request)
  + [

## Exemplos de código
](waiters.md#code-examples)
+ [

# Solução de problemas FAQs
](troubleshooting.md)
  + [

## Como faço para corrigir o erro "`java.net.SocketException`: reinicialização da conexão” ou “falha no servidor ao concluir a resposta”?
](troubleshooting.md#faq-socketexception)
  + [

## Como corrigir o erro de “tempo limite de conexão”?
](troubleshooting.md#faq-connection-timeout)
  + [

## Como corrigir o “`java.net.SocketTimeoutException`: tempo limite de leitura”?
](troubleshooting.md#faq-socket-timeout)
  + [

## Como corrigir o erro “Não foi possível executar a solicitação HTTP: tempo limite da espera para conexão do grupo”?
](troubleshooting.md#faq-pool-timeout)
  + [

## Como corrigir um `NoClassDefFoundError`, `NoSuchMethodError` ou `NoSuchFieldError`?
](troubleshooting.md#faq-classpath-errors)
  + [

## Como corrigir um erro “`SignatureDoesNotMatch`” ou “A assinatura da solicitação que calculamos não corresponde à assinatura que você forneceu”?
](troubleshooting.md#faq-signature-does-not-match-error)
  + [

## Como corrigir o erro “`java.lang.IllegalStateException`: encerramento do pool de conexões”?
](troubleshooting.md#faq-connection-pool-shutdown-exception)
  + [

## Como faço para corrigir “Não é possível carregar credenciais de nenhum dos provedores da cadeia AwsCredentialsProviderChain “?
](troubleshooting.md#faq-credentials-provider-chain)
    + [

### Causas comuns e soluções
](troubleshooting.md#faq-cred-provider-chain-common-causes-and-solutions)
      + [

#### Analisar a configuração de credenciais
](troubleshooting.md#faq-cred-provider-chain-check-config)
        + [

##### Para instâncias do Amazon EC2
](troubleshooting.md#faq-cred-check-ec2)
        + [

##### Para ambientes de contêiner
](troubleshooting.md#faq-cred-check-container-env)
        + [

##### Para desenvolvimento local
](troubleshooting.md#faq-cred-check-local-dev)
        + [

##### Para federação de identidades da web
](troubleshooting.md#faq-cred-check-web-id-federation)
      + [

#### Problemas de conectividade de rede ou proxy
](troubleshooting.md#faq-credentials-provider-chain-network-issues)
+ [

# Reduza o tempo de inicialização do SDK para AWS Lambda
](lambda-optimize-starttime.md)
  + [

## Use um cliente HTTP AWS baseado em CRT
](lambda-optimize-starttime.md#lambda-quick-url)
  + [

## Remover dependências não utilizadas do cliente HTTP
](lambda-optimize-starttime.md#lambda-quick-remove-deps)
  + [

## Configurar clientes de serviço para reduzir as pesquisas
](lambda-optimize-starttime.md#lambda-quick-clients)
  + [

## Inicializar o cliente SDK fora do manipulador da função do Lambda
](lambda-optimize-starttime.md#lambda-quick-initialize)
  + [

## Minimize a injeção de dependência
](lambda-optimize-starttime.md#lambda-quick-di)
  + [

## Use uma mira do Maven Archetype AWS Lambda
](lambda-optimize-starttime.md#lambda-quick-maven)
  + [

## Considere o Lambda SnapStart para Java
](lambda-optimize-starttime.md#lambda-quick-snapstart)
  + [

## Alterações na versão 2.x que afetam o tempo de inicialização
](lambda-optimize-starttime.md#example-client-configuration)
  + [

## Recursos adicionais do
](lambda-optimize-starttime.md#lambda-quick-resources)
+ [

# Implemente `ContentStreamProvider` no AWS SDK for Java 2.x
](content-stream-provider.md)
  + [

## Utilizar `mark()` e `reset()`
](content-stream-provider.md#csp-impl-mark-reset)
  + [

## Use o buffer se `mark()` e `reset()` não estiverem disponíveis
](content-stream-provider.md#csp-impl-unsupported-streams)
  + [

## Criar fluxos
](content-stream-provider.md#csp-impl-new-stream)
+ [

# Definir o JVM TTL para pesquisas de nome DNS
](jvm-ttl-dns.md)
  + [

## Como definir o TTL da JVM
](jvm-ttl-dns.md#how-to-set-the-jvm-ttl)
    + [

### Opção 1: defina-o programaticamente em seu aplicativo
](jvm-ttl-dns.md#set-ttl-programmatically)
    + [

### Opção 2: defina-o no arquivo java.security
](jvm-ttl-dns.md#set-ttl-java-security-file)
    + [

### Opção 3: usar o fallback de propriedades do sistema JDK (linha de comando)
](jvm-ttl-dns.md#set-ttl-system-property)
+ [

# Trabalhar com o HTTP/2 no AWS SDK para Java
](http2.md)

# Fazendo AWS service (Serviço da AWS) solicitações usando o AWS SDK for Java 2.x
<a name="work-witih-clients"></a>

## Usar clientes de serviço para fazer solicitações
<a name="using-service-client"></a>

Depois de concluir as etapas em [Configurar o SDK](setup.md) e entender como [configurar clientes de serviço](configuring-service-clients.md), você estará pronto para fazer solicitações para AWS serviços como Amazon S3, Amazon DynamoDB AWS Identity and Access Management, Amazon EC2 e muito mais.

### Crie um cliente de serviço
<a name="work-with-clients-create"></a>

Para fazer uma solicitação a um AWS service (Serviço da AWS), você deve primeiro instanciar um cliente de serviço para esse serviço usando o método estático de fábrica,. `builder()` O método `builder()` retorna um objeto `builder` que permite personalizar o cliente de serviço. Os métodos setter fluentes retornam o objeto `builder`, de maneira que você possa vincular as chamadas ao método por conveniência e obter um código mais legível. Após configurar as propriedades desejadas, você poderá chamar o método `build()` para criar o cliente.

Como exemplo, o trecho de código a seguir instancia um objeto `Ec2Client` como um cliente de serviço para o Amazon EC2.

```
Region region = Region.US_WEST_2;
Ec2Client ec2Client = Ec2Client.builder()
        .region(region)
        .build();
```

**nota**  
Os clientes de serviço no SDK devem ser livres de thread. Para obter uma melhor performance, trate-os como objetos de longa duração. Cada cliente tem o próprio recurso do grupo de conexões, que é liberado quando o lixo do cliente é coletado.  
Um objeto cliente de serviço é imutável, então você deve criar um novo cliente para cada serviço para o qual você faz solicitações ou se quiser usar uma configuração diferente para fazer solicitações para o mesmo serviço.  
Não é necessário especificar o `Region` no Service Client Builder para todos os AWS serviços; no entanto, é uma prática recomendada definir a região para as chamadas de API que você faz em seus aplicativos. Consulte a [seleção da região da AWS](region-selection.md) para obter mais informações.

### Configuração padrão de cliente
<a name="using-default-client"></a>

Os compiladores de cliente têm outro método de fábrica chamado `create()`. Esse método cria um cliente de serviço com a configuração padrão. Ele usa a [cadeia de provedores padrão](credentials-chain.md) para carregar as credenciais e a [cadeia de Região da AWS provedores padrão](region-selection.md#automatically-determine-the-aws-region-from-the-environment). Se as credenciais ou a região não puderem ser determinadas pelo ambiente no qual o aplicativo estiver em execução, a chamada a `create` falhará. Consulte [Como usar credenciais](credentials.md) e [Seleção de região](region-selection.md) para obter mais informações sobre como o SDK determina as credenciais e a região a ser usada.

Por exemplo, o seguinte trecho de código instancia um objeto `DynamoDbClient` como um cliente de serviço para o Amazon DynamoDB:

```
DynamoDbClient dynamoDbClient = DynamoDbClient.create();
```

### Configurar clientes de serviço
<a name="using-configure-service-clients"></a>

Consulte detalhes sobre como configurar clientes de serviço em [Configurar cliente externamente](configuring-service-clients-ext.md) e [Configurar cliente no código](configuring-service-clients-code.md).

### Feche o cliente de serviço
<a name="using-closing-client"></a>

Como prática recomendada, você deve usar um cliente de serviço para múltiplas chamadas de serviço de API durante a vida de um aplicativo. No entanto, se você precisar de um cliente de serviço para uso único ou não precisar mais do cliente de serviço, feche-o.

Chame o método `close()` quando o cliente de serviço não for mais necessário para liberar recursos.

```
ec2Client.close();
```

Se precisar de um cliente de serviço para uso único, você pode instanciar o cliente de serviço como um recurso em uma declaração `try`-com recursos. Os clientes de serviço implementam a interface `[Autoclosable](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/AutoCloseable.html)`, então o JDK chama automaticamente o método `close()` no fim da instrução.

O exemplo a seguir demonstra como usar um cliente de serviço para uma chamada única. O `StsClient` que chama o AWS Security Token Service é fechado após retornar o ID da conta.

```
import software.amazon.awssdk.services.sts.StsClient;

String getAccountID() {
    try (StsClient stsClient = StsClient.create()) {
       return stsClient.getCallerIdentity().account();
    }
}
```

## Fazer solicitações.
<a name="using-making-requests"></a>

Use o cliente de serviço para fazer solicitações ao correspondente AWS service (Serviço da AWS).

Por exemplo, este trecho de código mostra como criar um objeto `RunInstancesRequest` para criar uma nova instância do Amazon EC2:

```
// Create the request by using the fluid setter methods of the request builder.
RunInstancesRequest runInstancesRequest = RunInstancesRequest.builder()
        .imageId(amiId)
        .instanceType(InstanceType.T1_MICRO)
        .maxCount(1)
        .minCount(1)
        .build();

// Use the configured request with the service client.
RunInstancesResponse response = ec2Client.runInstances(runInstancesRequest);
```

Em vez de criar uma solicitação e transmitir a instância, o SDK fornece uma API fluente que você pode usar para criar uma solicitação. Com a API fluente, é possível usar expressões do lambda em Java para criar a solicitação “em linha”.

O exemplo a seguir reescreve o exemplo anterior usando a versão de `runInstances` [método que usa um criador](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#runInstances(java.util.function.Consumer)) para criar a solicitação.

```
// Create the request by using a lambda expression.
RunInstancesResponse response = ec2.runInstances(r -> r
                .imageId(amiId)
                .instanceType(InstanceType.T1_MICRO)
                .maxCount(1)
                .minCount(1));
```

### Usar solicitações para substituir a configuração do cliente
<a name="using-override-client-config-request"></a>

Embora um cliente de serviço seja imutável, é possível substituir muitas de suas configurações no nível da solicitação. Ao criar uma solicitação, você pode fornecer uma [AwsRequestOverrideConfiguration](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.html)instância para fornecer as configurações substituídas. Alguns dos métodos que você pode usar para substituir as configurações do cliente são:
+ `apiCallAttemptTimeout`
+ `apiCallTimeout`
+ `credentialProvider`
+ `compressionConfiguration`
+ `putHeader`

Em um exemplo de substituição de uma configuração de cliente por uma solicitação, suponha que você tenha o seguinte cliente do S3 que usa configurações padrão.

```
S3Client s3Client = S3Client.create();
```

Você deseja baixar um arquivo grande e garantir que a solicitação não atinja o tempo limite antes que o download termine. Para isso, aumente os valores de tempo limite para uma única solicitação `GetObject`, conforme mostrado no código a seguir.

------
#### [ Standard API ]

```
AwsRequestOverrideConfiguration overrideConfiguration = AwsRequestOverrideConfiguration.builder()
    .apiCallTimeout(Duration.ofSeconds(100L))
    .apiCallAttemptTimeout(Duration.ofSeconds(25L))
    .build();

GetObjectRequest request = GetObjectRequest.builder()
    .bucket("amzn-s3-demo-bucket")
    .key("demo-key")
    .overrideConfiguration(overrideConfiguration)
    .build();

s3Client.getObject(request, myPath);
```

------
#### [ Fluent API ]

```
s3Client.getObject(b -> b
        .bucket("amzn-s3-demo-bucket")
        .key("demo-key")
        .overrideConfiguration(c -> c
            .apiCallTimeout(Duration.ofSeconds(100L))
            .apiCallAttemptTimeout(Duration.ofSeconds(25L))),
    myPath);
```

------

## Manipulador de resposta
<a name="using-handling-responses"></a>

O SDK retorna um objeto de resposta para a maioria das operações de serviço. Seu código pode processar as informações no objeto da resposta de acordo com suas necessidades.

Por exemplo, o trecho de código a seguir imprime o ID da primeira instância retornado com o objeto [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/RunInstancesResponse.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/RunInstancesResponse.html) da solicitação anterior.

```
RunInstancesResponse runInstancesResponse = ec2Client.runInstances(runInstancesRequest);
System.out.println(runInstancesResponse.instances().get(0).instanceId());
```

No entanto, nem todas as operações retornam um objeto de resposta com dados específicos do serviço. Nessas situações, é possível consultar o status da resposta HTTP para saber se a operação foi bem-sucedida.

Por exemplo, o código no trecho a seguir verifica a resposta HTTP para ver se a operação [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sesv2/SesV2Client.html#deleteContactList(software.amazon.awssdk.services.sesv2.model.DeleteContactListRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sesv2/SesV2Client.html#deleteContactList(software.amazon.awssdk.services.sesv2.model.DeleteContactListRequest)) do Amazon Simple Email Service foi bem-sucedida. 

```
SesV2Client sesv2Client = SesV2Client.create();

DeleteContactListRequest request = DeleteContactListRequest.builder()
    .contactListName("ExampleContactListName")
    .build();

DeleteContactListResponse response = sesv2Client.deleteContactList(request);
if (response.sdkHttpResponse().isSuccessful()) {
    System.out.println("Contact list deleted successfully");
} else {
    System.out.println("Failed to delete contact list. Status code: " + response.sdkHttpResponse().statusCode());
}
```

# Programação assíncrona usando o AWS SDK for Java 2.x
<a name="asynchronous"></a>

O AWS SDK for Java 2.x apresenta clientes assíncronos com suporte a E/S sem bloqueio, que implementam alta simultaneidade usando apenas algumas threads. No entanto, a E/S total sem bloqueio não é garantida. O cliente assíncrono pode fazer chamadas de bloqueio em alguns casos, como recuperação de credenciais, assinatura de solicitações usando o [AWS Signature Version 4 (SigV4)](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html) ou a descoberta de endpoints. 

Os métodos síncronos bloqueiam a execução do seu thread até o cliente receber uma resposta do serviço. Os métodos assíncronos retornam imediatamente, devolvendo o controle ao thread de chamada sem aguardar uma resposta.

Como um método assíncrono retorna antes de uma resposta estar disponível, você precisa de uma maneira de obter a resposta quando ela estiver pronta. Os métodos de cliente assíncrono no 2.x do AWS SDK para Java retornam *objetos CompletableFuture* que permitem acessar a resposta quando ela está pronta.

## Usar APIs de cliente assíncrono
<a name="basics-async-non-streaming"></a>

As assinaturas dos métodos do cliente assíncrono são iguais às dos síncronos, mas os métodos assíncronos retornam um objeto [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/CompletableFuture.html) que contém os resultados da operação assíncrona *no futuro*. Se um erro for gerado durante a execução do método assíncrono do SDK, o erro será lançado como `CompletionException`. 

Uma abordagem que você pode usar para obter o resultado é encadear um método `whenComplete()` no `CompletableFuture` retornado pela chamada do método de SDK. O método `whenComplete()` recebe o resultado ou um objeto Throwable do tipo `CompletionException`, dependendo de como a chamada assíncrona foi concluída. Você fornece uma ação `whenComplete()` para processar ou verificar os resultados antes que eles retornem ao código de chamada.

Se você quiser retornar algo diferente do objeto retornado pelo método de SDK, use o método `handle()`. O método `handle()` usa os mesmos parâmetros que `whenComplete()`, mas você pode processar o resultado e retornar um objeto.

Para aguardar a conclusão da cadeia assíncrona e recuperar os resultados da conclusão, você pode chamar o método `join()`. Se o objeto `Throwable` não foi gerenciado na cadeia, o método `join()` lança um `CompletionException` não verificado que envolve a exceção original. Você acessa a exceção original com `CompletionException#getCause()`. Você também pode chamar o método `CompletableFuture#get()` para obter os resultados da conclusão. No entanto, o método `get()` pode gerar exceções verificadas.

O exemplo a seguir mostra duas variações de como você pode trabalhar com o método `listTables()` do cliente assíncrono do DynamoDB. A ação passada para `whenComplete()` simplesmente registra uma resposta bem-sucedida, enquanto a versão `handle()` extrai a lista de nomes de tabelas e retorna a lista. Em ambos os casos, se um erro for gerado na cadeia assíncrona, ele será relançado para que o código do cliente tenha a chance de gerenciá-lo.

 **Importações** 

```
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;
```

 **Código da** 

------
#### [ 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;
                }
            });
    }
}
```

------

## Gerenciar o streaming em métodos assíncronos
<a name="basics-async-streaming"></a>

Para métodos assíncronos com streaming de conteúdo, é necessário fornecer um [AsyncRequestBody](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncRequestBody.html) para entregar o conteúdo de forma incremental ou um [AsyncResponseTransformer](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncResponseTransformer.html) para receber e processar a resposta.

O exemplo a seguir faz upload de um arquivo para o Amazon S3 de forma assíncrona usando a forma assíncrona da operação `PutObject`.

 **Importações** 

```
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;
```

 **Código da** 

```
/**
 * 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();
    }
}
```

O exemplo a seguir obtém um arquivo do Amazon S3 usando a forma assíncrona da operação `GetObject`.

 **Importações** 

```
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;
```

 **Código da** 

```
/**
 * 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();
    }
}
```

## Configurar opções assíncronas avançadas
<a name="advanced-operations"></a>

O AWS SDK para Java 2.x usa [Netty](https://netty.io), uma estrutura de aplicativo de rede assíncrona orientada por eventos, para lidar com threads de E/S. O AWS SDK para Java 2.x cria um `ExecutorService` por trás do Netty para concluir os futuros retornos da solicitação do cliente HTTP para o cliente Netty. Essa abstração reduz o risco de um aplicativo interromper o processo assíncrono se os desenvolvedores optarem por suspender ou desabilitar threads. Por padrão, cada cliente assíncrono cria um threadpool com base no número de processadores e gerencia as tarefas em uma fila dentro do `ExecutorService`.

Você pode especificar uma implementação específica do JDK de `ExecutorService` ao criar o cliente assíncrono. O trecho a seguir cria um `ExecutorService` com um número fixo de threads.

 **Código da** 

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

Para otimizar o desempenho, você pode gerenciar seu próprio executor de grupo de threads e incluí-lo ao configurar o cliente.

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

# Melhores práticas para usar o AWS SDK for Java 2.x
<a name="best-practices"></a>

## Evitar solicitações suspensas configurando os tempos limite da API
<a name="bestpractice5"></a>

O SDK fornece [valores padrão](https://github.com/aws/aws-sdk-java-v2/blob/a0c8a0af1fa572b16b5bd78f310594d642324156/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java#L134) para algumas opções de tempos limite, como tempo limite de conexão e tempo limite de soquete, mas não para tempos limite de chamadas de API ou tempos limite de tentativas de chamadas de API individuais. É uma boa prática definir tempos limite para as tentativas individuais e para toda a solicitação. Isso garantirá que seu aplicativo se antecipe à falha de maneira ideal quando houver problemas transitórios que podem fazer com que as tentativas de solicitação demorem mais para serem concluídas ou problemas fatais na rede.

Você pode configurar tempos limite para todas as solicitações feitas por clientes de um serviço usando `[ClientOverrideConfiguration\$1apiCallAttemptTimeout](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html#apiCallAttemptTimeout())` e `[ClientOverrideConfiguration\$1apiCallTimeout](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html#apiCallTimeout())`.

O exemplo a seguir mostra a configuração de um cliente do Amazon S3 com valores de tempo limite personalizados.

```
S3Client.builder()
        .overrideConfiguration(
             b -> b.apiCallTimeout(Duration.ofSeconds(<custom value>))
                   .apiCallAttemptTimeout(Duration.ofMillis(<custom value>)))
        .build();
```

**`apiCallAttemptTimeout`**  
Essa configuração define a quantidade de tempo para uma única tentativa de HTTP, após o qual a chamada de API pode ser repetida.

**`apiCallTimeout`**  
O valor dessa propriedade configura a quantidade de tempo para toda a execução, incluindo todas as novas tentativas.

Como alternativa para definir esses valores de tempo limite no cliente de serviço, você pode usar [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/RequestOverrideConfiguration.html#apiCallTimeout()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/RequestOverrideConfiguration.html#apiCallTimeout()) e `[RequestOverrideConfiguration\$1apiCallAttemptTimeout()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/RequestOverrideConfiguration.html#apiCallAttemptTimeout())` para configurar uma única solicitação.

O exemplo a seguir configura uma única solicitação `listBuckets` com valores de tempo limite personalizados.

```
s3Client.listBuckets(lbr -> lbr.overrideConfiguration(
        b -> b.apiCallTimeout(Duration.ofSeconds(<custom value>))
               .apiCallAttemptTimeout(Duration.ofMillis(<custom value>))));
```

Ao usar essas propriedades em conjunto, você define um limite rígido para o tempo total gasto em todas as tentativas das repetições. Você também configura uma solicitação HTTP individual para se antecipar à falha rapidamente em uma solicitação lenta.

## Melhorar o desempenho reutilizando clientes de serviço
<a name="bestpractice1"></a>

Cada [cliente de serviço](work-witih-clients.md) mantém seu próprio grupo de conexões HTTP. Uma conexão que já existe no grupo pode ser reutilizada por uma nova solicitação para reduzir o tempo de estabelecimento de uma nova conexão. Recomendamos compartilhar uma única instância do cliente para evitar a sobrecarga de ter muitos grupos de conexão que não são usados de forma eficaz. Todos os clientes de serviço são seguros para os threads.

Se você não quiser compartilhar uma instância do cliente, chame `close()` na instância para liberar os recursos quando o cliente não for necessário.

## Evitar vazamentos de recursos fechando clientes de serviços não utilizados
<a name="bestpractice-close-client"></a>

Feche um [cliente de serviço](work-witih-clients.md) para liberar recursos, como threads, se ele não for mais necessário. Se você não quiser compartilhar uma instância do cliente, chame `close()` na instância para liberar os recursos quando o cliente não for necessário.

## Evitar o esgotamento do pool de conexões fechando os fluxos de entrada
<a name="bestpractice2"></a>

Para operações de streaming, como `[S3Client\$1getObject](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#getObject(java.util.function.Consumer,java.nio.file.Path))`, se você estiver trabalhando diretamente com `[ResponseInputStream](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/ResponseInputStream.html)`, recomendamos fazer o seguinte:
+ Leia todos os dados do stream de entrada o mais rápido possível.
+ Feche o stream de entrada o mais rápido possível.

Fazemos essas recomendações porque o stream de entrada é um stream direto de dados da conexão HTTP e a conexão HTTP subjacente não pode ser reutilizada até que todos os dados do stream tenham sido lidos e o stream seja fechado. Se essas regras não forem seguidas, o cliente poderá ficar sem recursos alocando muitas conexões HTTP abertas, mas não utilizadas.

## Otimizar o desempenho HTTP para a workload da aplicação
<a name="bestpractice3"></a>

O SDK fornece um conjunto de [configurações http padrão](https://github.com/aws/aws-sdk-java-v2/blob/master/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java) que se aplicam a casos de uso gerais. Recomendamos que os clientes ajustem as configurações HTTP para seus aplicativos com base em seus casos de uso. 

Como um bom ponto de partida, o SDK oferece um atributo [de padrões de configuração inteligentes](http-configuration.md#http-config-smart-defaults). Esse atributo está disponível somente na versão 2.17.102. Escolha um modo de acordo com seu caso de uso que forneça valores de configuração sensatos. 

## Melhore o desempenho do SSL com o OpenSSL para clientes assíncronos
<a name="bestpractice4"></a>

Por padrão, o [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html) do SDK usa a implementação SSL padrão do JDK como o `SslProvider`. Nossos testes descobriram que o OpenSSL tem um desempenho melhor do que a implementação padrão do JDK. A comunidade do Netty também [recomenda o uso do OpenSSL](https://netty.io/wiki/requirements-for-4.x.html#tls-with-openssl). 

Para usar o OpenSSL, adicione `netty-tcnative` às suas dependências. Para obter detalhes de configuração, consulte a [Documentação do projeto Netty](https://netty.io/wiki/forked-tomcat-native.html).

Depois de configurar `netty-tcnative` para seu projeto, a instância `NettyNioAsyncHttpClient` selecionará automaticamente o OpenSSL. Você também pode definir o `SslProvider` explicitamente usando o construtor `NettyNioAsyncHttpClient`, conforme mostrado no trecho a seguir.

```
NettyNioAsyncHttpClient.builder()
                        .sslProvider(SslProvider.OPENSSL)
                        .build();
```

## Monitorar o desempenho de aplicações com métricas de SDK
<a name="bestpractice6"></a>

O SDK para Java pode [coletar métricas](metrics.md) para os clientes de serviço em seu aplicativo. Você pode usar essas métricas para identificar problemas de desempenho, analisar as tendências gerais de uso, analisar as exceções retornadas pelos clientes de serviços ou se aprofundar para entender um problema específico.

Recomendamos que você colete métricas e, em seguida, analise os Amazon CloudWatch Logs para obter uma compreensão mais profunda do desempenho do seu aplicativo.

# Tratamento de erros no AWS SDK for Java 2.x
<a name="handling-exceptions"></a>

Entender como e quando AWS SDK for Java 2.x as exceções são lançadas é importante para criar aplicativos de alta qualidade usando o SDK. As seções a seguir descrevem os casos diferentes de exceções lançadas pelo SDK e como processá-las da maneira apropriada.

## Por que exceções desmarcadas?
<a name="why-unchecked-exceptions"></a>

 AWS SDK para Java Ele usa exceções de tempo de execução (ou não verificadas) em vez de exceções verificadas pelos seguintes motivos:
+ Como permitir que desenvolvedores controlem os erros que desejam processar sem forçá-los a processar casos excepcionais com os quais não estão preocupados (e tornar o código excessivamente detalhado)
+ Para evitar problemas de escalabilidade inerentes a exceções marcadas em aplicativos grandes

Em geral, as exceções marcadas funcionam bem em escalas pequenas, mas podem se tornar problemáticas à medida que os aplicativos crescem e se tornam mais complexos.

## AwsServiceException (e subclasses)
<a name="sdkserviceexception-and-subclasses"></a>

 [AwsServiceException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsServiceException.html)é a exceção mais comum que você enfrentará ao usar AWS SDK para Java o. `AwsServiceException`é uma subclasse das mais gerais [SdkServiceException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html). `AwsServiceException`s representam uma resposta de erro de um AWS service (Serviço da AWS). Por exemplo, se você tentar encerrar uma Amazon EC2 instância que não existe, Amazon EC2 retornará uma resposta de erro e todos os detalhes dessa resposta de erro serão incluídos na `AwsServiceException` resposta lançada. 

Ao encontrar um`AwsServiceException`, você sabe que sua solicitação foi enviada com sucesso para o AWS service (Serviço da AWS) , mas não pôde ser processada com sucesso. Isso pode ocorrer devido a erros nos parâmetros da solicitação ou problemas no lado do serviço.

 `AwsServiceException` fornece informações como:
+ Código de status HTTP retornado
+ Código de AWS erro retornado
+ Mensagem de erro detalhada do serviço na [AwsErrorDetails](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsErrorDetails.html)classe
+  AWS ID de solicitação para a solicitação que falhou

Para alguns casos, uma subclasse de `AwsServiceException` específica do serviço é lançada para permitir que os desenvolvedores tenham o controle refinado do tratamento dos casos de erro nos blocos catch. A referência da API Java SDK para [AwsServiceException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsServiceException.html)exibe o grande número de `AwsServiceException` subclasses. Use os links da subclasse para detalhar e ver as exceções granulares lançadas por um serviço.

Por exemplo, os links a seguir para a referência da API do SDK mostram as hierarquias de exceções de alguns Serviços da AWS comuns. A lista de subclasses mostrada em cada página mostra as exceções específicas que seu código pode capturar.
+ [Amazon S3](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/model/S3Exception.html)
+ [DynamoDB](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html)
+ [Amazon SQS](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/model/SqsException.html)

Para saber mais sobre uma exceção, inspecione `errorCode` o [AwsErrorDetails](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsErrorDetails.html)objeto. Você pode usar o valor do `errorCode` para pesquisar informações na API do guia de serviços. Por exemplo, se uma `S3Exception` for detectada e o valor de `AwsErrorDetails#errorCode()` for `InvalidRequest`, use a [lista de códigos de erro](https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) na Referência da API do Amazon S3 para ver mais detalhes.

## SdkClientException
<a name="sdkclientexception"></a>

 [SdkClientException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkClientException.html)indica que ocorreu um problema dentro do código do cliente Java, ao tentar enviar uma solicitação para AWS ou ao tentar analisar uma resposta de AWS. Um geralmente `SdkClientException` é mais grave do que um `SdkServiceException` e indica um grande problema que está impedindo o cliente de fazer chamadas de serviço para AWS os serviços. Por exemplo, AWS SDK para Java ele lança uma, `SdkClientException` se nenhuma conexão de rede estiver disponível, quando você tenta chamar uma operação em um dos clientes.

## Exceções e comportamento de nova tentativa
<a name="retried-exceptions"></a>

O SDK for Java repete solicitações para [várias exceções do lado do cliente](https://github.com/aws/aws-sdk-java-v2/blob/13985e0668a9a0b12ad331644e3c4fd1385c2cd7/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/retry/SdkDefaultRetrySetting.java#L79C41-L79C41) e [para códigos de status HTTP](https://github.com/aws/aws-sdk-java-v2/blob/13985e0668a9a0b12ad331644e3c4fd1385c2cd7/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/retry/SdkDefaultRetrySetting.java#L72C31-L72C31) que ele recebe das respostas. AWS service (Serviço da AWS) Esses erros são tratados como parte do `RetryMode` legado que os clientes de serviço usam por padrão. A referência da API Java para `[RetryMode](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/RetryMode.html)` descreve as várias maneiras pelas quais você pode configurar o modo.

Para personalizar as exceções e os códigos de status HTTP que acionam novas tentativas automáticas, configure seu cliente de serviço com uma `[RetryPolicy](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/RetryPolicy.html)` que adicione instâncias `[RetryOnExceptionsCondition](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryOnExceptionsCondition.html)` e `[RetryOnStatusCodeCondition](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/retry/conditions/RetryOnErrorCodeCondition.html)`.

# Usando resultados paginados no 2.x AWS SDK para Java
<a name="pagination"></a>

Muitas AWS operações retornam resultados paginados quando o objeto de resposta é muito grande para ser retornado em uma única resposta. Na AWS SDK para Java versão 1.0, a resposta contém um token que você usa para recuperar a próxima página de resultados. Por outro lado, o AWS SDK para Java 2.x tem métodos de autopaginação que fazem várias chamadas de serviço para obter automaticamente a próxima página de resultados para você. Você precisa somente escrever um código que processa os resultados. A autopaginação está disponível para clientes síncronos e assíncronos.

**nota**  
Esses trechos de código pressupõem que você entenda [os conceitos básicos do uso do SDK](using.md) e tenha configurado seu ambiente com [acesso de login único](get-started-auth.md#setup-credentials).

## Paginação síncrona
<a name="synchronous-pagination"></a>

Os exemplos a seguir demonstram métodos de paginação síncrona para listar objetos em um bucket do Amazon S3 .

### Iterar sobre páginas
<a name="iterate-pages"></a>

O primeiro exemplo demonstra o uso de um objeto paginador `listRes`, uma instância [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/paginators/ListObjectsV2Iterable.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/paginators/ListObjectsV2Iterable.html) para iterar todas as páginas de resposta com o método `stream`. O código é transmitido pelas páginas de resposta, converte o fluxo de resposta em um fluxo de `[S3Object](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/model/S3Object.html)` conteúdo e, em seguida, processa o conteúdo do Amazon S3 objeto.

As importações a seguir se aplicam a todos os exemplos nesta seção de paginação síncrona.

#### Importações
<a name="synchronous-pagination-ex-import"></a>

```
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Random;

import software.amazon.awssdk.core.waiters.WaiterResponse;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.paginators.ListObjectsV2Iterable;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Response;
import software.amazon.awssdk.services.s3.model.S3Object;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
import software.amazon.awssdk.services.s3.model.DeleteBucketRequest;
import software.amazon.awssdk.services.s3.model.CreateMultipartUploadRequest;
import software.amazon.awssdk.services.s3.model.CreateMultipartUploadResponse;
import software.amazon.awssdk.services.s3.model.CompletedMultipartUpload;
import software.amazon.awssdk.services.s3.model.CreateBucketRequest;
import software.amazon.awssdk.services.s3.model.CompletedPart;
import software.amazon.awssdk.services.s3.model.CreateBucketConfiguration;
import software.amazon.awssdk.services.s3.model.UploadPartRequest;
import software.amazon.awssdk.services.s3.model.CompleteMultipartUploadRequest;
import software.amazon.awssdk.services.s3.waiters.S3Waiter;
import software.amazon.awssdk.services.s3.model.HeadBucketRequest;
import software.amazon.awssdk.services.s3.model.HeadBucketResponse;
```

```
        ListObjectsV2Request listReq = ListObjectsV2Request.builder()
            .bucket(bucketName)
            .maxKeys(1)
            .build();

        ListObjectsV2Iterable listRes = s3.listObjectsV2Paginator(listReq);
        // Process response pages
        listRes.stream()
            .flatMap(r -> r.contents().stream())
            .forEach(content -> System.out
                .println(" Key: " + content.key() + " size = " + content.size()));
```

Veja o [exemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L112) em GitHub.

### Iterar sobre objetos
<a name="iterate-objects"></a>

Os exemplos a seguir mostram maneiras de iterar sobre os objetos retornados na resposta e não nas páginas de resposta. O método `contents` da classe `ListObjectsV2Iterable` retorna um [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/pagination/sync/SdkIterable.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/pagination/sync/SdkIterable.html) que fornece vários métodos para processar os elementos do conteúdo subjacente.

#### Usar um stream
<a name="use-a-stream"></a>

O seguinte trecho usa o método `stream` no conteúdo de resposta para iterar sobre a coleção de itens paginados.

```
        // Helper method to work with paginated collection of items directly.
        listRes.contents().stream()
            .forEach(content -> System.out
                .println(" Key: " + content.key() + " size = " + content.size()));
```

Veja o [exemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L127) em GitHub.

#### Usar um loop for-each
<a name="for-loop"></a>

Como `SdkIterable` estende a interface `Iterable`, você pode processar o conteúdo como qualquer outro `Iterable`. O trecho a seguir usa um loop `for-each` padrão para percorrer o conteúdo da resposta.

```
        for (S3Object content : listRes.contents()) {
            System.out.println(" Key: " + content.key() + " size = " + content.size());
        }
```

Veja o [exemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L133) em GitHub.

### Paginação manual
<a name="manual-pagination"></a>

Se seu caso de uso exigir isto, a paginação manual ainda estará disponível. Use o próximo token no objeto de resposta para as solicitações subsequentes. O exemplo a seguir usa o loop `while`.

```
        ListObjectsV2Request listObjectsReqManual = ListObjectsV2Request.builder()
            .bucket(bucketName)
            .maxKeys(1)
            .build();

        boolean done = false;
        while (!done) {
            ListObjectsV2Response listObjResponse = s3.listObjectsV2(listObjectsReqManual);
            for (S3Object content : listObjResponse.contents()) {
                System.out.println(content.key());
            }

            if (listObjResponse.nextContinuationToken() == null) {
                done = true;
            }

            listObjectsReqManual = listObjectsReqManual.toBuilder()
                .continuationToken(listObjResponse.nextContinuationToken())
                .build();
        }
```

Veja o [exemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L90) em GitHub.

## Paginação assíncrona
<a name="asynchronous-pagination"></a>

Os exemplos a seguir demonstram métodos de paginação assíncrona para listar tabelas. DynamoDB 

### Iterar sobre páginas de nomes de tabelas
<a name="iterate-pages-async"></a>

Os dois exemplos a seguir usam um cliente assíncrono do DynamoDB que chama o método `listTablesPaginator` com uma solicitação para obter implementos [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/paginators/ListTablesPublisher.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/paginators/ListTablesPublisher.html). O `ListTablesPublisher` implementa duas interfaces, que oferecem muitas opções para processar respostas. Examinaremos os métodos de cada interface.

#### Usar um `Subscriber`
<a name="use-a-subscriber"></a>

O exemplo de código a seguir demonstra como processar resultados paginados usando a interface `org.reactivestreams.Publisher` implementada pelo `ListTablesPublisher`. Para saber mais sobre o modelo de fluxos reativos, consulte o repositório [Reactive](https://github.com/reactive-streams/reactive-streams-jvm/blob/v1.0.2/README.md) Streams. GitHub 

As importações a seguir se aplicam a todos os exemplos nesta seção de paginação assíncrona.

##### Importações
<a name="use-a-subscriber-ex-imports"></a>

```
import io.reactivex.rxjava3.core.Flowable;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import reactor.core.publisher.Flux;
import software.amazon.awssdk.core.async.SdkPublisher;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import software.amazon.awssdk.services.dynamodb.model.ListTablesRequest;
import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse;
import software.amazon.awssdk.services.dynamodb.paginators.ListTablesPublisher;

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

O código a seguir adquire uma instância `ListTablesPublisher`.

```
        // Creates a default client with credentials and region loaded from the
        // environment.
        final DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.create();

        ListTablesRequest listTablesRequest = ListTablesRequest.builder().limit(3).build();
        ListTablesPublisher publisher = asyncClient.listTablesPaginator(listTablesRequest);
```

O código a seguir usa uma implementação anônima de `org.reactivestreams.Subscriber` para processar os resultados de cada página.

O método `onSubscribe` chama o método `Subscription.request` para iniciar solicitações de dados do editor. Esse método deve ser chamado para iniciar a obtenção de dados do editor. 

O método `onNext` do assinante processa uma página de resposta acessando todos os nomes das tabelas e imprimindo cada um. Depois que a página é processada, outra página é solicitada ao publicador. Este método é chamado repetidamente até que todas as páginas sejam recuperadas.

O método `onError` será acionado se ocorrer um erro durante a recuperação de dados. Por fim, o método `onComplete` será chamado quando todas as páginas tiverem sido solicitadas.

```
        // A Subscription represents a one-to-one life-cycle of a Subscriber subscribing
        // to a Publisher.
        publisher.subscribe(new Subscriber<ListTablesResponse>() {
            // Maintain a reference to the subscription object, which is required to request
            // data from the publisher.
            private Subscription subscription;

            @Override
            public void onSubscribe(Subscription s) {
                subscription = s;
                // Request method should be called to demand data. Here we request a single
                // page.
                subscription.request(1);
            }

            @Override
            public void onNext(ListTablesResponse response) {
                response.tableNames().forEach(System.out::println);
                // After you process the current page, call the request method to signal that
                // you are ready for next page.
                subscription.request(1);
            }

            @Override
            public void onError(Throwable t) {
                // Called when an error has occurred while processing the requests.
            }

            @Override
            public void onComplete() {
                // This indicates all the results are delivered and there are no more pages
                // left.
            }
        });
```

Veja o [exemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L83) em GitHub.

#### Usar um `Consumer`
<a name="id1pagination"></a>

A interface do `SdkPublisher` que `ListTablesPublisher` implementa tem um método `subscribe` que pega um `Consumer` e retorna um `CompletableFuture<Void>`. 

O método `subscribe` dessa interface pode ser usado para casos de uso simples, quando um `org.reactivestreams.Subscriber` pode ser uma sobrecarga. Como o código abaixo consome cada página, ele chama o método `tableNames` em cada uma. O método `tableNames` retorna um `java.util.List` dos nomes de tabela do DynamoDB que são processados com o método `forEach`.

```
        // Use a Consumer for simple use cases.
        CompletableFuture<Void> future = publisher.subscribe(
                response -> response.tableNames()
                        .forEach(System.out::println));
```

Veja o [exemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L96) em GitHub.

### Iterar sobre nomes de tabela
<a name="iterate-objects-async"></a>

Os exemplos a seguir mostram maneiras de iterar sobre os objetos retornados na resposta e não nas páginas de resposta. Semelhante ao exemplo síncrono do Amazon S3 mostrado anteriormente com seu método `contents`, a classe de resultados assíncronos do DynamoDB, `ListTablesPublisher` tem o método conveniente `tableNames` para interagir com a coleção de itens subjacente. O tipo de retorno do método `tableNames` é um [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/SdkPublisher.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/SdkPublisher.html) que pode ser usado para solicitar itens em todas as páginas.

#### Usar um `Subscriber`
<a name="id2"></a>

O código a seguir adquire um `SdkPublisher` da coleção subjacente de nomes de tabelas.

```
        // Create a default client with credentials and region loaded from the
        // environment.
        final DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.create();

        ListTablesRequest listTablesRequest = ListTablesRequest.builder().limit(3).build();
        ListTablesPublisher listTablesPublisher = asyncClient.listTablesPaginator(listTablesRequest);
        SdkPublisher<String> publisher = listTablesPublisher.tableNames();
```

O código a seguir usa uma implementação anônima de `org.reactivestreams.Subscriber` para processar os resultados de cada página.

O método `onNext` do assinante processa um elemento individual da coleção. Nesse caso, é um nome de tabela. Depois que o nome da tabela é processado, outro nome de tabela é solicitado ao publicador. Este método é chamado repetidamente até que todos os nomes de tabelas sejam recuperados.

```
        // Use a Subscriber.
        publisher.subscribe(new Subscriber<String>() {
            private Subscription subscription;

            @Override
            public void onSubscribe(Subscription s) {
                subscription = s;
                subscription.request(1);
            }

            @Override
            public void onNext(String tableName) {
                System.out.println(tableName);
                subscription.request(1);
            }

            @Override
            public void onError(Throwable t) {
            }

            @Override
            public void onComplete() {
            }
        });
```

Veja o [exemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L147) em GitHub.

#### Usar um `Consumer`
<a name="for-loop-async"></a>

O exemplo a seguir usa o método `subscribe` do `SdkPublisher` que utiliza um `Consumer` para processar cada item.

```
        // Use a Consumer.
        CompletableFuture<Void> future = publisher.subscribe(System.out::println);
        future.get();
```

Veja o [exemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L161) em GitHub.

### Usar bibliotecas de terceiros
<a name="use-third-party-library"></a>

Você pode usar outras bibliotecas de terceiros em vez de implementar um assinante personalizado. Este exemplo demonstra o uso de RxJava, mas qualquer biblioteca que implemente as interfaces de fluxo reativo pode ser usada. Consulte a [página RxJava wiki GitHub](https://github.com/ReactiveX/RxJava/wiki) para obter mais informações sobre essa biblioteca.

Para usar a biblioteca, adicione-a como uma dependência. Se estiver usando o Maven, o exemplo mostra o trecho POM a ser usado.

 **Entrada POM** 

```
<dependency>
      <groupId>io.reactivex.rxjava3</groupId>
      <artifactId>rxjava</artifactId>
      <version>3.1.6</version>
</dependency>
```

 **Código** 

```
        DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.create();
        ListTablesPublisher publisher = asyncClient.listTablesPaginator(ListTablesRequest.builder()
                .build());

        // The Flowable class has many helper methods that work with
        // an implementation of an org.reactivestreams.Publisher.
        List<String> tables = Flowable.fromPublisher(publisher)
                .flatMapIterable(ListTablesResponse::tableNames)
                .toList()
                .blockingGet();
        System.out.println(tables);
```

Veja o [exemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L198) em GitHub.

# Usando garçons no AWS SDK for Java 2.x
<a name="waiters"></a>

O utilitário waiters do AWS SDK para Java 2.x permite que você valide se AWS os recursos estão em um estado especificado antes de realizar operações nesses recursos.

Um *garçom* é uma abstração usada para pesquisar AWS recursos, como DynamoDB tabelas ou Amazon S3 compartimentos, até que o estado desejado seja alcançado (ou até que seja determinado que o recurso nunca alcançará o estado desejado). Em vez de escrever uma lógica para pesquisar continuamente seus AWS recursos, o que pode ser complicado e propenso a erros, você pode usar garçons para pesquisar um recurso e fazer com que seu código continue sendo executado depois que o recurso estiver pronto.

## Pré-requisitos
<a name="prerequisiteswaiters"></a>

Antes de usar garçons em um projeto com o AWS SDK para Java, você deve concluir as etapas em [Configurando](setup.md) o 2.x. AWS SDK para Java 

Você também deve configurar as dependências do projeto (por exemplo, no seu arquivo `pom.xml` ou `build.gradle`) para usar a versão `2.15.0` ou posterior do AWS SDK para Java.

Por exemplo:

```
<project>
  <dependencyManagement>
   <dependencies>
      <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>bom</artifactId>
        <version>2.27.21</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
   </dependencies>
  </dependencyManagement>
</project>
```

## Usar agentes de espera
<a name="id1waiters"></a>

Para instanciar um objeto de waiters, primeiro crie um cliente de serviço. Defina o método `waiter()` do cliente de serviço como o valor do objeto waiter. Quando a instância do waiter existir, defina suas opções de resposta para executar o código apropriado.

### Programação síncrona
<a name="synchronous-programming"></a>

O trecho de código a seguir mostra como esperar que uma DynamoDB tabela exista e esteja em um estado **ATIVO**.

```
DynamoDbClient dynamo = DynamoDbClient.create();
DynamoDbWaiter waiter = dynamo.waiter();

WaiterResponse<DescribeTableResponse> waiterResponse =
  waiter.waitUntilTableExists(r -> r.tableName("myTable"));

// print out the matched response with a tableStatus of ACTIVE
waiterResponse.matched().response().ifPresent(System.out::println);
```

### Programação assíncrona
<a name="asynchronous-programming"></a>

O trecho de código a seguir mostra como esperar que uma DynamoDB tabela não exista mais.

```
DynamoDbAsyncClient asyncDynamo = DynamoDbAsyncClient.create();
DynamoDbAsyncWaiter asyncWaiter = asyncDynamo.waiter();

CompletableFuture<WaiterResponse<DescribeTableResponse>> waiterResponse =
          asyncWaiter.waitUntilTableNotExists(r -> r.tableName("myTable"));

waiterResponse.whenComplete((r, t) -> {
  if (t == null) {
   // print out the matched ResourceNotFoundException
   r.matched().exception().ifPresent(System.out::println);
  }
}).join();
```

## Configurar waiters
<a name="configuring-waiters"></a>

Você pode personalizar a configuração de um waiter usando o `overrideConfiguration()` em seu construtor. Para algumas operações, você pode aplicar uma configuração personalizada ao fazer a solicitação.

### Configurar um waiter
<a name="configure-a-waiter"></a>

O trecho de código a seguir mostra como substituir a configuração em um waiter.

```
// sync
DynamoDbWaiter waiter =
   DynamoDbWaiter.builder()
          .overrideConfiguration(b -> b.maxAttempts(10))
          .client(dynamoDbClient)
          .build();
// async
DynamoDbAsyncWaiter asyncWaiter =
   DynamoDbAsyncWaiter.builder()
          .client(dynamoDbAsyncClient)
          .overrideConfiguration(o -> o.backoffStrategy(
               FixedDelayBackoffStrategy.create(Duration.ofSeconds(2))))
          .scheduledExecutorService(Executors.newScheduledThreadPool(3))
          .build();
```

### Substituir configuração para uma solicitação específica
<a name="override-configuration-for-a-specific-request"></a>

O trecho de código a seguir mostra como substituir a configuração de um waiter por solicitação. Observe que somente algumas operações têm configurações personalizáveis.

```
waiter.waitUntilTableNotExists(b -> b.tableName("myTable"),
               o -> o.maxAttempts(10));

asyncWaiter.waitUntilTableExists(b -> b.tableName("myTable"),
                 o -> o.waitTimeout(Duration.ofMinutes(1)));
```

## Exemplos de código
<a name="code-examples"></a>

Para ver um exemplo completo do uso de garçons com DynamoDB, consulte [CreateTable.java](https://github.com/awsdocs/aws-doc-sdk-examples/blob/869b7ddbc7c8f66c7c45acd5b813429aff37003e/javav2/example_code/dynamodb/src/main/java/com/example/dynamodb/CreateTable.java) no Repositório de exemplos de AWS código.

Para ver um exemplo completo do uso de garçons com Amazon S3, consulte [S3 BucketOps .java](https://github.com/awsdocs/aws-doc-sdk-examples/blob/869b7ddbc7c8f66c7c45acd5b813429aff37003e/javav2/example_code/s3/src/main/java/com/example/s3/S3BucketOps.java) no Repositório de exemplos de código. AWS 

# Solução de problemas FAQs
<a name="troubleshooting"></a>

Ao usar o AWS SDK for Java 2.x em seus aplicativos, você pode encontrar os erros de tempo de execução listados neste tópico. Use as sugestões indicadas aqui para ajudar a descobrir a causa raiz e resolver o erro.

## Como faço para corrigir o erro "`java.net.SocketException`: reinicialização da conexão” ou “falha no servidor ao concluir a resposta”?
<a name="faq-socketexception"></a>

Um erro de redefinição de conexão indica que seu host AWS service (Serviço da AWS), o ou qualquer intermediário (por exemplo, um gateway NAT, um proxy, um balanceador de carga) fechou a conexão antes que a solicitação fosse concluída. Como há muitas causas, encontrar uma solução exige que você saiba por que a conexão está sendo fechada. Os itens a seguir geralmente fazem com que uma conexão seja fechada.
+ **A conexão está inativa.**Isso é comum em operações de streaming, onde nenhum dado é enviado ou recebido pela rede por certo período, então uma parte intermediária detecta a conexão como inativa e a fecha. Para evitar isso, certifique-se de que a aplicação baixe ou carregue dados ativamente.
+ **Você fechou o cliente HTTP ou SDK.** Não feche os recursos enquanto eles estiverem em uso.
+ **Um proxy configurado incorretamente.** Ignore todos os proxies que você configurou para ver se isso resolve o problema. Se isso resolver o problema, o proxy está fechando sua conexão por algum motivo. Pesquise seu proxy específico para determinar por que ele está fechando a conexão.

Se você não conseguir identificar o problema, execute um TCP dump para uma conexão afetada na borda do cliente da rede (por exemplo, depois de qualquer proxy que você controla). 

Se você perceber que o AWS endpoint está enviando uma `TCP RST` (redefinição), [entre em contato com o serviço afetado](https://aws.amazon.com/contact-us/) para ver se eles conseguem determinar por que a redefinição está ocorrendo. Esteja preparado para fornecer solicitações IDs e registros de data e hora de quando o problema ocorreu. A equipe de AWS suporte também pode se beneficiar [de registros](logging-slf4j.md#sdk-java-logging-verbose) eletrônicos que mostram exatamente quais bytes seu aplicativo está enviando e recebendo e quando.

## Como corrigir o erro de “tempo limite de conexão”?
<a name="faq-connection-timeout"></a>

Um erro de tempo limite de conexão indica que seu host AWS service (Serviço da AWS), o ou qualquer intermediário (por exemplo, um gateway NAT, um proxy, um balanceador de carga) falhou ao estabelecer uma nova conexão com o servidor dentro do tempo limite de conexão configurado. Os itens a seguir descrevem as causas comuns para esse problema.
+ **O tempo limite de conexão configurado é muito baixo.** Por padrão, o tempo limite da conexão é de 2 segundos no AWS SDK for Java 2.x. Se você definir o tempo limite de conexão muito baixo, poderá receber esse erro. O tempo limite de conexão recomendado é de 1 segundo se você faz chamadas apenas na região e de 3 segundos se faz solicitações entre regiões.
+ **Um proxy configurado incorretamente.** Ignore todos os proxies que você configurou para ver se isso resolve o problema. Se isso resolver o problema, o proxy é o motivo do tempo limite de conexão. Pesquise seu proxy específico para determinar por que isso está ocorrendo

Se você não conseguir identificar o problema, execute um TCP dump para uma conexão afetada na borda do cliente da rede (por exemplo, depois de qualquer proxy que você controla) para investigar qualquer problema de rede.

## Como corrigir o “`java.net.SocketTimeoutException`: tempo limite de leitura”?
<a name="faq-socket-timeout"></a>

Um erro de tempo limite de leitura indica que a JVM tentou ler dados do sistema operacional subjacente, mas os dados não foram retornados dentro do tempo configurado por meio do SDK. Esse erro pode ocorrer se o sistema operacional AWS service (Serviço da AWS), o ou qualquer parte intermediária (por exemplo, um gateway NAT, um proxy, um balanceador de carga) falhar em enviar dados dentro do tempo esperado pela JVM. Como há muitas causas, encontrar uma solução exige que você saiba por que os dados não estão sendo retornados.

Execute um TCP dump para uma conexão afetada na borda do cliente da rede (por exemplo, depois de qualquer proxy que você controla). 

Se você perceber que o AWS endpoint está enviando uma `TCP RST` (redefinição), [entre em contato com o serviço afetado](https://aws.amazon.com/contact-us/). Esteja preparado para fornecer solicitações IDs e registros de data e hora de quando o problema ocorreu. A equipe de AWS suporte também pode se beneficiar [de registros](logging-slf4j.md#sdk-java-logging-verbose) eletrônicos que mostram exatamente quais bytes seu aplicativo está enviando e recebendo e quando.

## Como corrigir o erro “Não foi possível executar a solicitação HTTP: tempo limite da espera para conexão do grupo”?
<a name="faq-pool-timeout"></a>

Esse erro indica que uma solicitação não pode obter uma conexão do grupo dentro do tempo máximo especificado. Para solucionar o problema, recomendamos que você [habilite as métricas do SDK do lado do cliente para publicar métricas](metrics.md) na Amazon. CloudWatch As métricas HTTP podem ajudar a identificar a causa raiz. Os itens a seguir descrevem as causas comuns desse erro.
+ **Vazamento de conexão.** Você pode investigar isso verificando as métricas `LeasedConcurrency`, `AvailableConcurrency` e `MaxConcurrency`. Se `LeasedConcurrency` aumenta até atingir `MaxConcurrency`. mas nunca diminui, pode haver um vazamento de conexão. Uma causa comum de vazamento é porque uma operação de streaming, como um método `getObject` do S3, não está fechada. Recomendamos que a aplicação leia todos os dados do fluxo de entrada o mais rápido possível e [feche o fluxo de entrada depois](best-practices.md#bestpractice2). O gráfico a seguir mostra como podem ser as métricas do SDK referente ao vazamento de conexão.  
![\[Uma captura de tela das CloudWatch métricas que mostram um provável vazamento de conexão.\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/images/JavaDevGuide-connection-leak-metrics-chart.png)
+ **Escassez no pool de conexões.**Isso poderá acontecer se a taxa de solicitação for muito alta e o tamanho do pool de conexões que foi configurado não puder atender à demanda da solicitação. O tamanho padrão do pool de conexões é 50 e, quando as conexões no grupo atingem o máximo, o cliente HTTP enfileira as solicitações recebidas até que as conexões estejam disponíveis. O gráfico a seguir mostra como podem ser as métricas do SDK referente à escassez do grupo de conexão.  
![\[Uma captura de tela das CloudWatch métricas que mostra como pode ser a falta de um pool de conexões.\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/images/JavaDevGuide-connection-pool-starvation-chart.png)

  Para mitigar esse problema, realize qualquer uma das ações a seguir.
  + Aumente o tamanho do pool de conexões
  + Aumente o tempo limite de aquisição.
  + Diminua a taxa de solicitações.

  Ao aumentar o número máximo de conexões, o throughput do cliente pode aumentar (a menos que a interface de rede já esteja totalmente utilizada). No entanto, você pode eventualmente atingir as limitações do sistema operacional quanto ao número de descritores de arquivo usados pelo processo. Se você já usa totalmente sua interface de rede ou não consegue aumentar a contagem de conexões, tente aumentar o tempo limite de aquisição. Com o aumento, você ganha tempo extra para que as solicitações adquiram uma conexão antes do tempo limite. Se as conexões não forem liberadas, as solicitações subsequentes ainda atingirão o tempo limite. 

  Se você não conseguir corrigir o problema usando os dois primeiros mecanismos, diminua a taxa de solicitações tentando as seguintes opções.
  + Suavize suas requisições para que grandes picos de tráfego não sobrecarreguem o cliente.
  + Seja mais eficiente com chamadas para Serviços da AWS.
  + Aumente o número de hosts enviando solicitações.
+ **As threads de E/S estão muito ocupados.** Isso só se aplica se você estiver usando um cliente assíncrono do SDK com o [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html). Se a `AvailableConcurrency` métrica não for baixa, indicando que as conexões estão disponíveis no pool, mas alta, talvez `ConcurrencyAcquireDuration` seja porque I/O os threads não conseguem lidar com as solicitações. Certifique-se de não se passar por `Runnable:run` [executor de conclusão futura](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/SdkAdvancedAsyncClientOption.html#FUTURE_COMPLETION_EXECUTOR) e realizar tarefas demoradas na cadeia de conclusão futura da resposta, pois isso pode bloquear um I/O encadeamento. Se não for esse o caso, considere aumentar o número de I/O threads usando o `[eventLoopGroupBuilder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.Builder.html#eventLoopGroupBuilder(software.amazon.awssdk.http.nio.netty.SdkEventLoopGroup.Builder))` método. Para referência, o número padrão de threads de E/S para uma instância `NettyNioAsyncHttpClient` é o dobro do número de núcleos de CPU do host.
+ **Alta latência de handshake TLS.** Se a métrica `AvailableConcurrency` estiver próxima de 0 e `LeasedConcurrency` estiver menor que `MaxConcurrency`, isso pode indicar que a latência do handshake TLS está alta. O gráfico a seguir mostra como seriam as métricas do SDK para alta latência de handshake TLS.  
![\[Uma captura de tela das CloudWatch métricas que podem indicar alta latência de handshake do TLS.\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/images/JavaDevGuide-high-tls-latency-chart.png)

  Para clientes HTTP oferecidos pelo Java SDK que não são baseados no CRT, tente habilitar os [logs de TLS](security-java-tls.md) para solucionar problemas de TLS. Para o cliente HTTP baseado no AWS CRT, tente habilitar [logs do AWS CRT](logging-slf4j.md#sdk-java-logging-verbose). Se você perceber que o AWS endpoint parece levar muito tempo para realizar um handshake TLS, [entre em contato com o](https://aws.amazon.com/contact-us/) serviço afetado.

## Como corrigir um `NoClassDefFoundError`, `NoSuchMethodError` ou `NoSuchFieldError`?
<a name="faq-classpath-errors"></a>

Um `NoClassDefFoundError` indica que não foi possível carregar uma classe no runtime. As duas causas comuns para esse erro são:
+ a classe não existe no classpath porque o JAR está ausente ou a versão errada do JAR está no classpath.
+ a classe falhou ao carregar porque seu inicializador estático gerou uma exceção.

Da mesma forma, `NoSuchMethodError`s e `NoSuchFieldError`s normalmente resultam de uma versão JAR incompatível. Recomendamos seguir as seguintes etapas:

1. **Verifique suas dependências** para ter certeza de que você está usando a *mesma versão de todos os jars do SDK*. O motivo mais comum pelo qual uma classe, um método ou um campo não pode ser encontrado é quando você atualiza para uma nova versão do cliente, mas continua usando uma versão antiga de dependência do SDK “compartilhada”. A nova versão do cliente pode tentar usar classes que existem somente nas dependências “compartilhadas” mais recentes do SDK. Tente executar `mvn dependency:tree` ou `gradle dependencies` (para Gradle) para verificar se todas as versões da biblioteca do SDK coincidem. Para evitar totalmente esse problema no futuro, recomendamos o uso de [BOM (Bill of Materials)](setup-project-maven.md#sdk-as-dependency) para gerenciar as versões do módulo do SDK.

   O exemplo a seguir mostra um exemplo de versões mistas do SDK.

   ```
   [INFO] +- software.amazon.awssdk:dynamodb:jar:2.20.00:compile
   [INFO] |  +- software.amazon.awssdk:aws-core:jar:2.13.19:compile
   [INFO] +- software.amazon.awssdk:netty-nio-client:jar:2.20.00:compile
   ```

   A versão de `dynamodb` é 2.20.00 e a versão de `aws-core` é 2.13.19. A versão do artefato `aws-core` também deve ser 2.20.00.

1. **Verifique as declarações logo no início de seus logs** para ver se uma classe está falhando no carregamento devido a uma falha de inicialização estática. Na primeira vez em que a classe falha ao carregar, ela pode lançar uma exceção diferente e mais útil que especifica *por que* a classe não pode ser carregada. Essa exceção potencialmente útil ocorre apenas uma vez, portanto, as declarações de log posteriores relatarão apenas que a classe não foi encontrada.

1. **Verifique seu processo de implantação** para ter certeza de que ele realmente implementa os arquivos JAR necessários junto com a aplicação. É possível que você esteja criando com a versão correta, mas o processo que cria o classpath para a aplicação está excluindo uma dependência necessária.

## Como corrigir um erro “`SignatureDoesNotMatch`” ou “A assinatura da solicitação que calculamos não corresponde à assinatura que você forneceu”?
<a name="faq-signature-does-not-match-error"></a>

Um `SignatureDoesNotMatch` erro indica que a assinatura gerada pelo AWS SDK para Java e a assinatura gerada pelo AWS service (Serviço da AWS) não coincidem. Os itens a seguir descrevem as possíveis causas.
+ Um proxy ou intermediário modifica a solicitação. Por exemplo, um proxy ou balanceador de carga pode modificar um cabeçalho, um caminho ou uma string de consulta que o SDK assinou.
+ O serviço e o SDK diferem na forma como codificam a solicitação quando cada um gera a string para assinar.

Para depurar esse problema, recomendamos que você [habilite o registro em log de depuração](logging-slf4j.md#sdk-debug-level-logging) para o SDK. Tente reproduzir o erro e encontrar a solicitação canônica gerada pelo SDK. No log, a solicitação canônica é rotulada com `AWS4 Canonical Request: ...` e a string a ser assinada é rotulada com `AWS4 String to sign: ...`. 

Se você não puder habilitar a depuração, por exemplo, porque ela só pode ser reproduzida na produção, adicione uma lógica à aplicação que registre as informações sobre a solicitação quando o erro ocorre. Depois, você pode usar essas informações para tentar replicar o erro fora da produção em um teste de integração com o registro em log de depuração habilitado.

Depois de coletar a solicitação canônica e a string para assinar, compare-as com a [especificação do AWS Signature versão 4](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html) para determinar se há algum problema na forma como o SDK gerou a string para assinar. Se algo parecer errado, você pode criar um [relatório de GitHub bug](https://github.com/aws/aws-sdk-java-v2/issues/new/choose) para AWS SDK para Java o. 

Se nada parecer errado, você pode comparar a string do SDK para assinar com a string para indicar que algumas Serviços da AWS retornam como parte da resposta à falha (Amazon S3, por exemplo). Se isso não estiver disponível, [entre em contato com o serviço afetado](https://aws.amazon.com/contact-us/) para ver qual solicitação canônica e string para assinar foram geradas para comparação. Essas comparações podem ajudar a identificar partes intermediárias que podem ter modificado a solicitação ou as diferenças de codificação entre o serviço e o cliente.

Para obter mais informações básicas sobre solicitações de assinatura, consulte [Assinatura de solicitações da AWS API](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html) no Guia AWS Identity and Access Management do usuário.

**Example da solicitação canônica**  

```
PUT
/Example-Bucket/Example-Object
partNumber=19&uploadId=string
amz-sdk-invocation-id:f8c2799d-367c-f024-e8fa-6ad6d0a1afb9
amz-sdk-request:attempt=1; max=4
content-encoding:aws-chunked
content-length:51
content-type:application/octet-stream
host:xxxxx
x-amz-content-sha256:STREAMING-UNSIGNED-PAYLOAD-TRAILER
x-amz-date:20240308T034733Z
x-amz-decoded-content-length:10
x-amz-sdk-checksum-algorithm:CRC32
x-amz-trailer:x-amz-checksum-crc32
```

**Example de uma string para assinar**  

```
AWS4-HMAC-SHA256
20240308T034435Z
20240308/us-east-1/s3/aws4_request
5f20a7604b1ef65dd89c333fd66736fdef9578d11a4f5d22d289597c387dc713
```

## Como corrigir o erro “`java.lang.IllegalStateException`: encerramento do pool de conexões”?
<a name="faq-connection-pool-shutdown-exception"></a>

Esse erro indica que o pool de conexões HTTP Apache subjacente foi fechado. Os itens a seguir descrevem as possíveis causas.
+ **O cliente SDK foi fechado prematuramente.**O SDK só fecha o pool de conexões quando o cliente associado é fechado. Não feche os recursos enquanto eles estiverem em uso.
+ **Um `java.lang.Error` foi lançado.** Erros como `OutOfMemoryError` fazem com que um pool de conexões HTTP do Apache seja [encerrado](https://github.com/apache/httpcomponents-client/blob/6a741b4f8f23e6c5c7cc42c36c2acabfac19c3d6/httpclient/src/main/java/org/apache/http/impl/execchain/MainClientExec.java#L368). Examine seus logs em busca de rastreamentos de pilha de erros. Além disso, revise seu código em busca de locais em que ele captura `Throwable`s ou `Error`s, mas suprime a saída que impede que o erro apareça. Se o código não relatar erros, reescreva-o para que as informações sejam registradas em log. As informações registradas em log ajudam a determinar a causa raiz do erro.
+ **Você tentou usar o provedor de credenciais retornado de `DefaultCredentialsProvider#create()` depois que ele foi fechado**. [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/DefaultCredentialsProvider.html#create()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/DefaultCredentialsProvider.html#create()) retorna uma instância singleton. Portanto, se ela estiver fechada e o código chamar o método `resolveCredentials`, a exceção será lançada após a expiração das credenciais (ou token) em cache. 

  Verifique se há locais no código em que `DefaultCredentialsProvider` esteja fechado, conforme mostrado nos exemplos a seguir.
  + A instância singleton é fechada chamando `DefaultCredentialsProvider#close().`

    ```
    DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create(); // Singleton instance returned.
    AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials();
    
    // Make calls to Serviços da AWS.
    
    defaultCredentialsProvider.close();  // Explicit close.
    
    // Make calls to Serviços da AWS.
    
    // After the credentials expire, either of the following calls eventually results in a "Connection pool shut down" exception.
    credentials = defaultCredentialsProvider.resolveCredentials();
    // Or
    credentials = DefaultCredentialsProvider.create().resolveCredentials();
    ```
  + Invoque `DefaultCredentialsProvider#create()` em um try-with-resources bloco.

    ```
    try (DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create()) {
        AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials();
        
        // Make calls to Serviços da AWS.
    
    } // After the try-with-resources block exits, the singleton DefaultCredentialsProvider is closed.
    
    // Make calls to Serviços da AWS.
    
    DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create(); // The closed singleton instance is returned.
    // If the credentials (or token) has expired, the following call results in the error.
    AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials();
    ```

  Crie uma instância que não seja singleton chamando `DefaultCredentialsProvider.builder().build()` se o código fechou a instância singleton e você precisa resolver as credenciais usando um `DefaultCredentialsProvider`.

## Como faço para corrigir “Não é possível carregar credenciais de nenhum dos provedores da cadeia AwsCredentialsProviderChain “?
<a name="faq-credentials-provider-chain"></a>

Esse erro indica que não AWS SDK for Java 2.x foi possível encontrar AWS credenciais válidas por meio de nenhum dos provedores de credenciais na cadeia de provedores de credenciais padrão. O SDK pesquisa automaticamente as credenciais em uma ordem específica, e esse erro ocorre quando todos os provedores da cadeia não fornecem credenciais válidas.

A mensagem de erro completa geralmente se parece com isto (quebras de linha e indentações adicionadas para melhorar a legibilidade):

```
Unable to load credentials from any of the providers in the chain AwsCredentialsProviderChain(
    credentialsProviders=[
        SystemPropertyCredentialsProvider(),
        EnvironmentVariableCredentialsProvider(), 
        WebIdentityTokenCredentialsProvider(), 
        ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[])), 
        ContainerCredentialsProvider(), 
        InstanceProfileCredentialsProvider()
    ]) : [
        SystemPropertyCredentialsProvider(): Unable to load credentials from system settings.
        Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) 
        or system property (aws.accessKeyId)., 

        EnvironmentVariableCredentialsProvider(): Unable to load credentials from system settings. 
        Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) 
        or system property (aws.accessKeyId)., 

        WebIdentityTokenCredentialsProvider(): To use web identity tokens, the 'sts' service module 
        must be on the class path., 

        ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[])): 
        Profile file contained no credentials for profile 'default': ProfileFile(sections=[]), 

        ContainerCredentialsProvider(): Cannot fetch credentials from container - neither 
        AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment 
        variables are set., 

        InstanceProfileCredentialsProvider(): Failed to load credentials from IMDS.]
```

### Causas comuns e soluções
<a name="faq-cred-provider-chain-common-causes-and-solutions"></a>

#### Analisar a configuração de credenciais
<a name="faq-cred-provider-chain-check-config"></a>

Quando você usa o provedor de credenciais padrão (chamando `ServiceClient.create()` sem configurar explicitamente as credenciais), o SDK pesquisa as credenciais em uma ordem específica. Analise [como a cadeia de provedores de credenciais padrão funciona](credentials-chain.md) para entender quais origens de credenciais o SDK verifica e em que ordem.

Certifique-se de que o método de configuração de credenciais que você pretende usar esteja configurado corretamente em seu ambiente:

##### Para instâncias do Amazon EC2
<a name="faq-cred-check-ec2"></a>
+ **Verifique o perfil do IAM:** verifique se um perfil do IAM está anexado à instância.
+ **Falhas intermitentes do IMDS:** se estiverem ocorrendo falhas intermitentes (geralmente com duração de algumas centenas de milissegundos), isso geralmente indica problemas transitórios de rede que atingem o serviço de metadados de instância (IMDS).

  Soluções:
  + Habilite o [registro em log de depuração](logging-slf4j.md#sdk-debug-level-logging) para analisar o tempo e a frequência das falhas
  + Considere implementar a lógica de novas tentativas na aplicação para falhas relacionadas a credenciais
  + Verifique se há problemas de conectividade de rede entre a instância e o endpoint do IMDS

##### Para ambientes de contêiner
<a name="faq-cred-check-container-env"></a>

Confirme se os perfis de tarefa (Amazon ECS) ou as contas de serviço (Amazon EKS) estão configurados e se as variáveis de ambiente necessárias estão definidas.

##### Para desenvolvimento local
<a name="faq-cred-check-local-dev"></a>

Verifique se as variáveis de ambiente, os arquivos de credenciais ou a configuração do Centro de Identidade do IAM estão em vigor.

##### Para federação de identidades da web
<a name="faq-cred-check-web-id-federation"></a>
+ **Verifique a configuração: **verifique se o arquivo de token de identidade da web existe e se as variáveis de ambiente necessárias estão configuradas.
+ **Dependência ausente do módulo do STS:** se ocorrer o erro `To use web identity tokens, the 'sts' service module must be on the class path`, será necessário adicionar o módulo do STS como uma dependência. Isso é comum ao usar a Identidade de Pods do Amazon EKS ou outra autenticação de token de identidade da web.

  Solução: adicione o módulo do STS às dependências do projeto:
  + 

    ```
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>sts</artifactId>
    </dependency>
    ```

    Para alguns serviços, talvez você também precise da dependência `aws-query-protocol`:

    ```
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>aws-query-protocol</artifactId>
    </dependency>
    ```

#### Problemas de conectividade de rede ou proxy
<a name="faq-credentials-provider-chain-network-issues"></a>

Se ocorrerem erros `Connection refused` na cadeia de provedores de credenciais, isso normalmente indica problemas de conectividade de rede quando o SDK tenta alcançar endpoints AWS .

**Soluções:**
+ Verifique a configuração do proxy se você estiver usando um servidor proxy
+ Verifique se sua rede permite conexões HTTPS de saída para endpoints AWS 
+ Habilite o [registro em log de depuração](logging-slf4j.md#sdk-debug-level-logging) para ver as tentativas de conexão detalhadas
+ Teste a conectividade usando ferramentas como `curl` para verificar o acesso da rede aos endpoints AWS 

# Reduza o tempo de inicialização do SDK para AWS Lambda
<a name="lambda-optimize-starttime"></a>

Um dos objetivos do AWS SDK for Java 2.x é reduzir a latência de inicialização AWS Lambda das funções. O SDK contém alterações que reduzem o tempo de inicialização, que são discutidas no final deste tópico.

Primeiro, este tópico se concentra nas mudanças que você pode fazer para reduzir os tempos de inicialização a frio. Isso inclui fazer alterações na estrutura do código e na configuração dos clientes de serviço.

## Use um cliente HTTP AWS baseado em CRT
<a name="lambda-quick-url"></a>

Para trabalhar com AWS Lambda, recomendamos o [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtHttpClient.html)para cenários síncronos e o [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtAsyncHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtAsyncHttpClient.html)para cenários assíncronos.

O tópico [Configurar clientes AWS HTTP baseados em CRT](http-configuration-crt.md) deste guia descreve os benefícios de usar os clientes HTTP, como adicionar a dependência e como configurar seu uso pelos clientes de serviço. 

## Remover dependências não utilizadas do cliente HTTP
<a name="lambda-quick-remove-deps"></a>

Além do uso explícito de um cliente AWS baseado em CRT, você pode remover outros clientes HTTP que o SDK traz por padrão. O tempo de inicialização do Lambda é reduzido quando menos bibliotecas precisam ser carregadas, então você deve remover quaisquer artefatos não utilizados que a JVM precise carregar.

O seguinte trecho de um arquivo `pom.xml` do Maven mostra a exclusão do cliente HTTP baseado em Apache e do cliente HTTP baseado em Netty. (Esses clientes não são necessários quando você usa um cliente AWS baseado em CRT.) Este exemplo exclui os artefatos do cliente HTTP da dependência do cliente S3 e adiciona o `aws-crt-client` artefato para permitir o acesso aos clientes HTTP baseados em CRT. AWS 

```
<project>
    <properties>
        <aws.java.sdk.version>2.27.21</aws.java.sdk.version>
    <properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>${aws.java.sdk.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>aws-crt-client</artifactId>
        </dependency>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>software.amazon.awssdk</groupId>
                    <artifactId>netty-nio-client</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>software.amazon.awssdk</groupId>
                    <artifactId>apache-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</project>
```

**nota**  
Adicione o elemento `<exclusions>` a todas as dependências do cliente de serviço em seu arquivo `pom.xml`.

## Configurar clientes de serviço para reduzir as pesquisas
<a name="lambda-quick-clients"></a>

**Especificar uma região**  
Ao criar um cliente de serviço, chame o método `region` no builder do cliente de serviço. Isso reduz o [processo de pesquisa de região](region-selection.md#default-region-provider-chain) padrão do SDK, que verifica as Região da AWS informações em vários locais.  
Para manter o código Lambda independente da região, use o código a seguir dentro do método `region`. Esse código acessa a variável de ambiente `AWS_REGION` definida pelo contêiner Lambda.  

```
Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable()))
```

**Usar a `EnvironmentVariableCredentialProvider`**  
Assim como o comportamento padrão de pesquisa das informações da região, o SDK procura credenciais em vários lugares. Ao especificar o [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/EnvironmentVariableCredentialsProvider.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/EnvironmentVariableCredentialsProvider.html) quando cria um cliente de serviço, você economiza tempo no processo de pesquisa de credenciais feito pelo SDK.  
O uso desse provedor de credenciais permite que o código seja usado em Lambda funções, mas pode não funcionar em Amazon EC2 ou em outros sistemas.  
Se você pretende usar o [Lambda SnapStart para Java](#lambda-quick-snapstart) em algum momento, você deve confiar na cadeia de fornecedores de credenciais padrão para pesquisar as credenciais. Se você especificar o`EnvironmentVariableCredentialsProvider`, a pesquisa inicial de credenciais funcionará, mas quando SnapStart for ativada, [o Java Runtime definirá as variáveis de ambiente das credenciais do contêiner](https://docs.aws.amazon.com/lambda/latest/dg/snapstart-activate.html#snapstart-credentials). Na ativação, as variáveis de ambiente usadas pelo `EnvironmentVariableCredentialsProvider`, ou seja, variáveis de ambiente da chave de acesso, não estão disponíveis para o Java SDK.

O trecho de código a seguir mostra um cliente de serviço do S3 configurado adequadamente para uso em um ambiente Lambda.

```
S3Client s3Client = S3Client.builder()
    .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())))
    .credentialsProvider(EnvironmentVariableCredentialsProvider.create())
    .httpClient(AwsCrtHttpClient.builder().build())
    .build();
```

## Inicializar o cliente SDK fora do manipulador da função do Lambda
<a name="lambda-quick-initialize"></a>

Recomendamos inicializar um cliente SDK fora do método manipulador do Lambda. Dessa forma, se o contexto de execução for reutilizado, a inicialização do cliente de serviço poderá ser ignorada. Ao reutilizar a instância do cliente e suas conexões, as invocações subsequentes do método manipulador ocorrem mais rapidamente.

No exemplo a seguir, a instância `S3Client` é inicializada no construtor usando um método estático de fábrica. Se o contêiner gerenciado pelo ambiente Lambda for reutilizado, a instância `S3Client` inicializada será reutilizada.

```
public class App implements RequestHandler<Object, Object> {
    private final S3Client s3Client;

    public App() {
        s3Client = DependencyFactory.s3Client();
    }

    @Override
    public Object handle Request(final Object input, final Context context) {
         ListBucketResponse response = s3Client.listBuckets();
         // Process the response.
    }
}
```

## Minimize a injeção de dependência
<a name="lambda-quick-di"></a>

As estruturas de injeção de dependência (DI) podem levar mais tempo para concluir o processo de configuração. Elas também podem exigir dependências adicionais, que levam tempo para serem carregadas.

Se uma estrutura de DI for necessária, recomendamos o uso de estruturas de DI leves, como o [Dagger](https://dagger.dev/dev-guide/).

## Use uma mira do Maven Archetype AWS Lambda
<a name="lambda-quick-maven"></a>

A equipe do AWS Java SDK desenvolveu um modelo [Maven Archetype](https://github.com/aws/aws-sdk-java-v2/tree/master/archetypes/archetype-lambda) para iniciar um projeto Lambda com o mínimo de tempo de inicialização. Você pode criar um projeto Maven a partir do arquétipo e saber se as dependências estão configuradas adequadamente para o ambiente Lambda. 

Para saber mais sobre o arquétipo e trabalhar com um exemplo de implantação, consulte esta [postagem no blog](https://aws.amazon.com/blogs/developer/bootstrapping-a-java-lambda-application-with-minimal-aws-java-sdk-startup-time-using-maven/).

## Considere o Lambda SnapStart para Java
<a name="lambda-quick-snapstart"></a>

Se seus requisitos de tempo de execução forem compatíveis, AWS oferece o [Lambda SnapStart para Java](https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html). O Lambda SnapStart é uma solução baseada em infraestrutura que melhora o desempenho de inicialização das funções Java. Quando você publica uma nova versão de uma função, o Lambda a SnapStart inicializa e tira um instantâneo imutável e criptografado da memória e do estado do disco. SnapStart em seguida, armazena o instantâneo em cache para reutilização.

## Alterações na versão 2.x que afetam o tempo de inicialização
<a name="example-client-configuration"></a>

Além das alterações que você faz no seu código, a versão 2.x do SDK para Java inclui três alterações principais que reduzem o tempo de inicialização:
+ Uso de [jackson-jr](https://github.com/FasterXML/jackson-jr), que é uma biblioteca de serialização que melhora o tempo de inicialização
+ Uso das bibliotecas [java.time](https://docs.oracle.com/javase/8/docs/api/index.html?java/time.html) para objetos de data e hora, que faz parte do JDK
+ Uso de [Slf4j](https://www.slf4j.org/) para uma fachada de registro em log

## Recursos adicionais do
<a name="lambda-quick-resources"></a>

O Guia do AWS Lambda desenvolvedor contém uma [seção sobre as melhores práticas](https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html) para o desenvolvimento de funções Lambda que não são específicas de Java.

Para ver um exemplo de criação de um aplicativo nativo da nuvem em Java que usa AWS Lambda, consulte o conteúdo deste [workshop](https://github.com/aws-samples/aws-lambda-java-workshop). O workshop discute a otimização do desempenho e outras práticas recomendadas.

Você pode considerar o uso de imagens estáticas que são compiladas com antecedência para reduzir a latência de inicialização. Por exemplo, você pode usar o SDK for Java 2.x e o Maven para [criar uma imagem nativa do GraalVM](setup-project-graalvm.md).

# Implemente `ContentStreamProvider` no AWS SDK for Java 2.x
<a name="content-stream-provider"></a>

`ContentStreamProvider`é uma abstração usada no AWS SDK for Java 2.x para permitir várias leituras dos dados de entrada. Este tópico explica como implementar um `ContentStreamProvider` corretamente para suas aplicações.

O SDK para Java 2.x usa o método `ContentStreamProvider#newStream()` sempre que precisa ler um fluxo inteiro. Para que isso funcione em todo o fluxo, o fluxo que retornar deve estar sempre no início do conteúdo e conter os mesmos dados. 

Nas seções a seguir, fornecemos três abordagens sobre como implementar esse comportamento corretamente.

## Utilizar `mark()` e `reset()`
<a name="csp-impl-mark-reset"></a>

No exemplo abaixo, usamos `mark(int)` no construtor antes do início da leitura para garantir que possamos redefinir o fluxo de volta ao início. Para cada invocação de `newStream()`, redefinimos o fluxo:

```
public class MyContentStreamProvider implements ContentStreamProvider {  
    private InputStream contentStream;  
  
    public MyContentStreamProvider(InputStream contentStream) {  
        this.contentStream = contentStream;  
        this.contentStream.mark(MAX_LEN);  
    }  
  
    @Override  
    public InputStream newStream() {  
        contentStream.reset();  
        return contentStream;  
    }  
}
```

## Use o buffer se `mark()` e `reset()` não estiverem disponíveis
<a name="csp-impl-unsupported-streams"></a>

 Se o fluxo não comportar `mark()` e `reset()` diretamente, você ainda poderá usar a solução mostrada anteriormente, primeiro agrupando o fluxo em um `BufferedInputStream`:

```
public class MyContentStreamProvider implements ContentStreamProvider {  
    private BufferedReader contentStream;  
  
    public MyContentStreamProvider(InputStream contentStream) {  
        this.contentStream = new BufferedInputStream(contentStream);  
        this.contentStream.mark(MAX_LEN);
    }  
  
    @Override  
    public InputStream newStream() {  
        contentStream.reset();  
        return contentStream;  
    }  
}
```

## Criar fluxos
<a name="csp-impl-new-stream"></a>

Uma abordagem mais simples é simplesmente obter um novo fluxo para seus dados em cada invocação e fechar o anterior:

```
public class MyContentStreamProvider implements ContentStreamProvider {  
    private InputStream contentStream;  
  
    @Override  
    public InputStream newStream() {  
        if (contentStream != null) {  
            contentStream.close();  
        }  
        contentStream = openStream();  
        return contentStream;  
    }  
}
```

# Definir o JVM TTL para pesquisas de nome DNS
<a name="jvm-ttl-dns"></a>

A JVM armazena em cache pesquisas de nome DNS. Quando a JVM resolve um nome de host para um endereço IP, ela armazena o endereço IP em cache por um período de tempo especificado, conhecido como (TTL). *time-to-live*

Como AWS os recursos usam entradas de nome DNS que mudam ocasionalmente, recomendamos que você configure sua JVM com um valor TTL de 5 segundos. Isso garante que, quando o endereço IP de um recurso mudar, o aplicativo poderá receber e usar o novo endereço IP do recurso consultando novamente o DNS.

Em algumas configurações do Java, o TTL padrão da JVM é definido de maneira que *jamais* atualizará entradas DNS até a JVM ser reiniciada. Portanto, se o endereço IP de um AWS recurso mudar enquanto seu aplicativo ainda estiver em execução, ele não poderá usar esse recurso até que você *reinicie manualmente* a JVM e as informações IP em cache sejam atualizadas. Nesse caso, é crucial definir o TTL da JVM, de forma que ele atualize periodicamente as informações de IP armazenadas em cache.

## Como definir o TTL da JVM
<a name="how-to-set-the-jvm-ttl"></a>

Para modificar o TTL da JVM, defina o valor da propriedade de segurança [networkaddress.cache.ttl](https://docs.oracle.com/en/java/javase/17/core/java-networking.html#GUID-A680DADB-C4C1-40F1-B568-D9A97C917F5D). Observe que `networkaddress.cache.ttl` é uma *propriedade de segurança, não uma propriedade* do sistema, ou seja, ela não pode ser definida com o sinalizador de `-D` linha de comando.

### Opção 1: defina-o programaticamente em seu aplicativo
<a name="set-ttl-programmatically"></a>

Ligue [https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/security/Security.html](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/security/Security.html)logo na inicialização do aplicativo, antes que qualquer cliente AWS SDK seja criado e antes que qualquer solicitação de rede seja feita:

```
import java.security.Security;

public class MyApplication {
    public static void main(String[] args) {
        Security.setProperty("networkaddress.cache.ttl", "5");

        // ... create SDK clients and run application
    }
}
```

### Opção 2: defina-o no arquivo java.security
<a name="set-ttl-java-security-file"></a>

Defina a `networkaddress.cache.ttl` propriedade no `$JAVA_HOME/jre/lib/security/java.security` arquivo para Java 8 ou `$JAVA_HOME/conf/security/java.security` arquivo para Java 11 ou superior.

Veja a seguir um trecho de um arquivo `java.security` que mostra o cache de TTL definido para 5 segundos.

```
#
# The Java-level namelookup cache policy for successful lookups:
#
# any negative value: caching forever
# any positive value: the number of seconds to cache an address for
# zero: do not cache
#
...
networkaddress.cache.ttl=5
...
```

Todos os aplicativos executados na JVM representada pela variável de `$JAVA_HOME` ambiente usam essa configuração.

### Opção 3: usar o fallback de propriedades do sistema JDK (linha de comando)
<a name="set-ttl-system-property"></a>

Se você não puder modificar a configuração ou o código de segurança, poderá usar as propriedades do sistema JDK. Eles atuam como substitutos se nenhuma propriedade de segurança for definida.
+ `sun.net.inetaddr.ttl`— Controla pesquisas bem-sucedidas (TTL positivo)
+ `sun.net.inetaddr.negative.ttl`— Controla pesquisas com falha (TTL negativo)

```
java -Dsun.net.inetaddr.ttl=5 -Dsun.net.inetaddr.negative.ttl=1 -jar myapp.jar
```

**nota**  
Essas são propriedades internas do JDK documentadas na referência [Oracle Java 8 Networking Properties](https://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.html) como propriedades privadas que “podem não ser suportadas em futuras versões”. Use as Opções 1-2 quando possível.

# Trabalhar com o HTTP/2 no AWS SDK para Java
<a name="http2"></a>

HTTP/2 é uma revisão importante do protocolo HTTP. Esta nova versão tem vários aprimoramentos para melhorar o desempenho:
+ A codificação de dados binários proporciona uma transferência de dados mais eficiente.
+ A compactação de cabeçalho reduz a sobrecarga de bytes baixados pelo cliente, ajudando a obter o conteúdo para o cliente mais cedo. Isso é especialmente útil para clientes móveis que já tenham restrição na largura de banda.
+ A comunicação assíncrona bidirecional (multiplexação) permite que várias solicitações e mensagens de respostas entre o cliente e a AWS estejam em andamento ao mesmo tempo por meio de uma única conexão, em vez de várias conexões, o que melhora o desempenho.

Os desenvolvedores que atualizarem para os SDKs mais recentes usarão automaticamente HTTP/2 quando ele for compatível com o serviço com que estiverem trabalhando. Novas interfaces de programação aproveitam perfeitamente os recursos do HTTP/2 e fornecem novas maneiras de criar aplicativos.

O AWS SDK para Java 2.x apresenta novas APIs para o streaming de eventos que implementam o protocolo HTTP/2. Para ver exemplos de como usar essas novas APIs, consulte [Como trabalhar com o Kinesis](examples-kinesis.md).