step-by-step Instruções de migração com exemplo - AWS SDK for Java 2.x

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

step-by-step Instruções de migração com exemplo

Esta seção fornece um step-by-step guia para migrar seu aplicativo que atualmente usa o SDK for Java v1.x para o SDK for Java 2.x. A primeira parte apresenta uma visão geral das etapas seguidas por um exemplo detalhado de uma migração.

As etapas abordadas aqui descrevem a migração de um caso de uso normal, em que o aplicativo chama Serviços da AWS usando clientes de serviço orientados por modelos. Se você precisar migrar código que usa APIs de nível superior, como o S3 Transfer Manager ou a CloudFrontpré-assinatura, consulte a seção abaixo O que há de diferente entre AWS SDK for Java 1.x e 2.x do sumário.

A abordagem descrita aqui é uma sugestão. Você pode usar outras técnicas e aproveitar os recursos de edição de código do seu IDE para alcançar o mesmo resultado.

Visão geral das etapas

1. Comece adicionando o SDK for Java 2.x BOM

Ao adicionar o elemento Maven BOM (Lista de materiais) do SDK for Java 2.x ao seu arquivo POM, você garante que todas as dependências v2 necessárias sejam da mesma versão. Seu POM pode conter dependências v1 e v2. Isso permite que você migre seu código de forma incremental em vez de alterá-lo de uma só vez.

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

Você pode encontrar a versão mais recente no Repositório Central do Maven.

2. Pesquisar arquivos para instruções de importação da classe v1

Ao escanear os arquivos em seu aplicativo em busca de Service_IDs usados nas importações v1, você encontrará os Service_IDs exclusivos usados. Um SERVICE_ID é um nome curto e exclusivo para um. AWS service (Serviço da AWS) Por exemplo, cognitoidentity é o SERVICE_ID para o Amazon Cognito Identity.

3. Determine as dependências do Maven v2 a partir das instruções de importação da v1

Depois de encontrar todos os Service_IDs v1 exclusivos, você pode determinar o artefato Maven correspondente para a dependência v2 consultando a. Nome do pacote para mapeamentos Maven ArtifactiD

4. Adicione elementos de dependência v2 ao arquivo POM

Atualize o arquivo POM do Maven com os elementos de dependência determinados na etapa 3.

5. Nos arquivos Java, altere incrementalmente as classes v1 para as classes v2

Ao substituir classes v1 por classes v2, faça as alterações necessárias para dar suporte à API v2, como usar construtores em vez de construtores e usar getters e setters fluentes.

6. Remova as dependências v1 do Maven das importações POM e v1 dos arquivos

Depois de migrar seu código para usar classes v2, remova todas as importações v1 restantes dos arquivos e todas as dependências do seu arquivo de compilação.

7. Refatore o código para usar os aprimoramentos da API v2

Depois que o código for compilado e aprovado nos testes, você poderá aproveitar os aprimoramentos da v2, como usar um cliente HTTP diferente ou paginadores para simplificar o código. Esta é uma etapa opcional.

Exemplo de migração

Neste exemplo, migramos um aplicativo que usa o SDK for Java v1 e acessa vários. Serviços da AWS Trabalhamos detalhadamente com o seguinte método v1 na etapa 5. Esse é um método em uma classe que contém oito métodos e há 32 classes no aplicativo.

Somente as importações do SDK v1 estão listadas abaixo no arquivo Java.

import com.amazonaws.ClientConfiguration; import com.amazonaws.regions.Region; import com.amazonaws.regions.RegionUtils; import com.amazonaws.services.ec2.AmazonEC2Client; import com.amazonaws.services.ec2.model.AmazonEC2Exception; import com.amazonaws.services.ec2.model.CreateTagsRequest; import com.amazonaws.services.ec2.model.DescribeInstancesRequest; import com.amazonaws.services.ec2.model.DescribeInstancesResult; import com.amazonaws.services.ec2.model.Instance; import com.amazonaws.services.ec2.model.InstanceStateName; import com.amazonaws.services.ec2.model.Reservation; import com.amazonaws.services.ec2.model.Tag; import com.amazonaws.services.ec2.model.TerminateInstancesRequest; ... private static List<Instance> getRunningInstances(AmazonEC2Client ec2, List<String> instanceIds) { List<Instance> runningInstances = new ArrayList<>(); try { DescribeInstancesRequest request = new DescribeInstancesRequest() .withInstanceIds(instanceIds); DescribeInstancesResult result; do { // DescribeInstancesResponse is a paginated response, so use tokens with multiple requests. result = ec2.describeInstances(request); request.setNextToken(result.getNextToken()); // Prepare request for next page. for (final Reservation r : result.getReservations()) { for (final Instance instance : r.getInstances()) { LOGGER.info("Examining instanceId: "+ instance.getInstanceId()); // if instance is in a running state, add it to runningInstances list. if (RUNNING_STATES.contains(instance.getState().getName())) { runningInstances.add(instance); } } } } while (result.getNextToken() != null); } catch (final AmazonEC2Exception exception) { // if instance isn't found, assume its terminated and continue. if (exception.getErrorCode().equals(NOT_FOUND_ERROR_CODE)) { LOGGER.info("Instance probably terminated; moving on."); } else { throw exception; } } return runningInstances; }

1. Adicionar V2 Maven BOM

Adicione a BOM do Maven para o SDK for Java 2.x ao POM junto com quaisquer outras dependências na seção. dependencyManagement Se o seu arquivo POM tiver a BOM para v1 do SDK, deixe-a por enquanto. Ele será removido em uma etapa posterior.

<dependencyManagement> <dependencies> <dependency> <groupId>org.example</groupId> <!--Existing dependency in POM. --> <artifactId>bom</artifactId> <version>1.3.4</version> <type>pom</type> <scope>import</scope> </dependency> ... <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-bom</artifactId> <!--Existing v1 BOM dependency. --> <version>1.11.1000</version> <type>pom</type> <scope>import</scope> </dependency> ... <dependency> <groupId>software.amazon.awssdk</groupId> <!--Add v2 BOM dependency. --> <artifactId>bom</artifactId> <version>2.24.3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

2. Pesquisar arquivos para instruções de importação da classe v1

Pesquise o código do aplicativo em busca de ocorrências exclusivas deimport com.amazonaws.services. Isso nos ajuda a determinar as dependências v1 usadas pelo projeto. Se seu aplicativo tiver um arquivo Maven POM com dependências v1 listadas, você poderá usar essas informações em vez disso.

Neste exemplo, usamos o comando ripgrep(rg) para pesquisar a base de código.

Da raiz da sua base de código, execute o ripgrep comando a seguir. Depois de ripgrep encontrar as instruções de importação, elas são canalizadas para os uniq comandos cutsort, e para isolar os Service_IDs.

rg --no-filename 'import\s+com\.amazonaws\.services' | cut -d '.' -f 4 | sort | uniq

Para esse aplicativo, os seguintes Service_IDs são registrados no console.

autoscaling cloudformation ec2 identitymanagement

Isso indica que houve pelo menos uma ocorrência de cada um dos seguintes nomes de pacotes usados nas import declarações. Quatro de nossos propósitos, os nomes das classes individuais não importam. Só precisamos encontrar os Service_IDs que são usados.

com.amazonaws.services.autoscaling.* com.amazonaws.services.cloudformation.* com.amazonaws.services.ec2.* com.amazonaws.services.identitymanagement.*

3. Determine as dependências do Maven v2 a partir das instruções de importação da v1

Os Service_IDs da v1 que isolamos da Etapa 2 — por exemplo, autoscaling e cloudformation — podem ser mapeados para o mesmo SERVICE_ID v2 na maior parte. Como o artifactID v2 do Maven corresponde ao SERVICE_ID na maioria dos casos, você tem as informações necessárias para adicionar blocos de dependência ao seu arquivo POM.

A tabela a seguir mostra como podemos determinar as dependências da v2.

v1 SERVICE_ID mapeia para...

nome do pacote

v2 SERVICE_ID mapeia para...

nome do pacote

Dependência do Maven v2

ec2

com.amazonaws.services.ec2.*

ec2

software.amazon.awssdk.services.ec2.*

<dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>ec2</artifactId> </dependency>

escalonamento automático

com.amazonaws.services.autoscaling.*

escalonamento automático

software.amazon.awssdk.services.autoscaling.*

<dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>autoscaling</artifactId> </dependency>
cloudformation

com.amazonaws.services.cloudformation.*

cloudformation

software.amazon.awssdk.cloudformation.*

<dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>cloudformation</artifactId> </dependency>
gerenciamento de identidade*

com.amazonaws.services.identitymanagement.*

eu sou*

software.amazon.awssdk.iam.*

<dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>iam</artifactId> </dependency>

* O iam mapeamento identitymanagement para é uma exceção em que o SERVICE_ID difere entre as versões. Consulte as exceções se Nome do pacote para mapeamentos Maven ArtifactiD o Maven ou o Gradle não conseguirem resolver a dependência v2.

4. Adicione elementos de dependência v2 ao arquivo POM

Na etapa 3, determinamos os quatro blocos de dependência que precisam ser adicionados ao arquivo POM. Não precisamos adicionar uma versão porque especificamos o BOM na etapa 1. Depois que as importações são adicionadas, nosso arquivo POM tem os seguintes elementos de dependência.

... <dependencies> ... <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>autoscaling</artifactId> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>iam</artifactId> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>cloudformation</artifactId> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>ec2</artifactId> </dependency> ... </dependencies> ...

5. Nos arquivos Java, altere incrementalmente as classes v1 para as classes v2

No método que estamos migrando, vemos

  • Um cliente de serviço EC2 dacom.amazonaws.services.ec2.AmazonEC2Client.

  • Várias classes de modelo EC2 usadas. Por exemplo DescribeInstancesRequest DescribeInstancesResult e.

import com.amazonaws.ClientConfiguration; import com.amazonaws.regions.Region; import com.amazonaws.regions.RegionUtils; import com.amazonaws.services.ec2.AmazonEC2Client; import com.amazonaws.services.ec2.model.AmazonEC2Exception; import com.amazonaws.services.ec2.model.CreateTagsRequest; import com.amazonaws.services.ec2.model.DescribeInstancesRequest; import com.amazonaws.services.ec2.model.DescribeInstancesResult; import com.amazonaws.services.ec2.model.Instance; import com.amazonaws.services.ec2.model.InstanceStateName; import com.amazonaws.services.ec2.model.Reservation; import com.amazonaws.services.ec2.model.Tag; import com.amazonaws.services.ec2.model.TerminateInstancesRequest; ... private static List<Instance> getRunningInstances(AmazonEC2Client ec2, List<String> instanceIds) List<Instance> runningInstances = new ArrayList<>(); try { DescribeInstancesRequest request = new DescribeInstancesRequest() .withInstanceIds(instanceIds); DescribeInstancesResult result; do { // DescribeInstancesResponse is a paginated response, so use tokens with multiple re result = ec2.describeInstances(request); request.setNextToken(result.getNextToken()); // Prepare request for next page. for (final Reservation r : result.getReservations()) { for (final Instance instance : r.getInstances()) { LOGGER.info("Examining instanceId: "+ instance.getInstanceId()); // if instance is in a running state, add it to runningInstances list. if (RUNNING_STATES.contains(instance.getState().getName())) { runningInstances.add(instance); } } } } while (result.getNextToken() != null); } catch (final AmazonEC2Exception exception) { // if instance isn't found, assume its terminated and continue. if (exception.getErrorCode().equals(NOT_FOUND_ERROR_CODE)) { LOGGER.info("Instance probably terminated; moving on."); } else { throw exception; } } return runningInstances; } ...

Nosso objetivo é substituir todas as importações v1 por importações v2. Prosseguimos uma aula por vez.

a. Substitua a instrução de importação ou o nome da classe

Vemos que o primeiro parâmetro do describeRunningInstances método é uma AmazonEC2Client instância v1. Execute um destes procedimentos:

  • Substitua a importação com.amazonaws.services.ec2.AmazonEC2Client por software.amazon.awssdk.services.ec2.Ec2Client e altere AmazonEC2Client paraEc2Client.

  • Altere o tipo de parâmetro para Ec2Client e deixe que o IDE solicite a importação correta. Nosso IDE solicitará que importemos a classe v2 porque os nomes dos clientes são diferentes— AmazonEC2Client e. Ec2Client Essa abordagem não funciona se o nome da classe for o mesmo nas duas versões.

b. Substitua as classes do modelo v1 por equivalentes v2

Após a mudança para a v2Ec2Client, se usarmos um IDE, veremos erros de compilação na declaração a seguir.

result = ec2.describeInstances(request);

O erro de compilação resulta do uso de uma instância de v1 DescribeInstancesRequest como parâmetro para o método Ec2Client describeInstances v2. Para corrigir, faça as seguintes declarações de substituição ou importação.

replace with
import com.amazonaws.services.ec2.model.DescribeInstancesRequest
import software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest

c. Mude os construtores v1 para construtores v2.

Ainda vemos erros de compilação porque não há construtores nas classes v2. Para corrigir, faça a seguinte alteração.

alteração para
final DescribeInstancesRequest request = new DescribeInstancesRequest() .withInstanceIds(instanceIdsCopy);
final DescribeInstancesRequest request = DescribeInstancesRequest.builder() .instanceIds(instanceIdsCopy) .build();

d. Substitua objetos de *Result resposta v1 por equivalentes *Response v2

Uma diferença consistente entre v1 e v2 é que todos os objetos de resposta na v2 terminam com *Response em vez de. *Result Substitua a DescribeInstancesResult importação v1 pela importação v2,. DescribeInstancesResponse

d. Faça alterações na API

A declaração a seguir precisa de algumas mudanças.

request.setNextToken(result.getNextToken());

Na v2, os métodos setter não usam o set ou com. prefix Os métodos Getter get prefixados com também foram incluídos no SDK for Java 2.x

Classes de modelo, como a request instância, são imutáveis na v2, então precisamos criar uma nova DescribeInstancesRequest com um construtor.

Na v2, a declaração se torna a seguinte.

request = DescribeInstancesRequest.builder() .nextToken(result.nextToken()) .build();

d. Repita até que o método seja compilado com classes v2

Continue com o resto do código. Substitua as importações v1 pelas importações v2 e corrija os erros de compilação. Consulte a referência da API v2 e a referência What's different, conforme necessário.

Depois de migrarmos esse único método, temos o seguinte código v2.

import com.amazonaws.ClientConfiguration; import com.amazonaws.regions.Region; import com.amazonaws.regions.RegionUtils; import com.amazonaws.services.ec2.AmazonEC2Client; import com.amazonaws.services.ec2.model.AmazonEC2Exception; import com.amazonaws.services.ec2.model.CreateTagsRequest; import com.amazonaws.services.ec2.model.InstanceStateName; import com.amazonaws.services.ec2.model.Tag; import com.amazonaws.services.ec2.model.TerminateInstancesRequest; import software.amazon.awssdk.services.ec2.Ec2Client; import software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest; import software.amazon.awssdk.services.ec2.model.DescribeInstancesResponse; import software.amazon.awssdk.services.ec2.model.Ec2Exception; import software.amazon.awssdk.services.ec2.model.Instance; import software.amazon.awssdk.services.ec2.model.Reservation; ... private static List<Instance> getRunningInstances(Ec2Client ec2, List<String> instanceIds) { List<Instance> runningInstances = new ArrayList<>(); try { DescribeInstancesRequest request = DescribeInstancesRequest.builder() .instanceIds(instanceIds) .build(); DescribeInstancesResponse result; do { // DescribeInstancesResponse is a paginated response, so use tokens with multiple re result = ec2.describeInstances(request); request = DescribeInstancesRequest.builder() // Prepare request for next page. .nextToken(result.nextToken()) .build(); for (final Reservation r : result.reservations()) { for (final Instance instance : r.instances()) { // if instance is in a running state, add it to runningInstances list. if (RUNNING_STATES.contains(instance.state().nameAsString())) { runningInstances.add(instance); } } } } while (result.nextToken() != null); } catch (final Ec2Exception exception) { // if instance isn't found, assume its terminated and continue. if (exception.awsErrorDetails().errorCode().equals(NOT_FOUND_ERROR_CODE)) { LOGGER.info("Instance probably terminated; moving on."); } else { throw exception; } } return runningInstances; } ...

Como estamos migrando um único método em um arquivo Java com oito métodos, temos uma combinação de importações v1 e v2 à medida que trabalhamos no arquivo. Adicionamos as últimas seis instruções de importação à medida que executamos as etapas.

Depois de migrarmos todo o código, não haverá mais instruções de importação v1.

6. Remova as dependências v1 do Maven das importações POM e v1 dos arquivos

Depois de migrarmos todo o código v1 no arquivo, temos as seguintes instruções de importação do SDK v2.

import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.regions.ServiceMetadata; import software.amazon.awssdk.services.ec2.Ec2Client; import software.amazon.awssdk.services.ec2.model.CreateTagsRequest; import software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest; import software.amazon.awssdk.services.ec2.model.DescribeInstancesResponse; import software.amazon.awssdk.services.ec2.model.Ec2Exception; import software.amazon.awssdk.services.ec2.model.Instance; import software.amazon.awssdk.services.ec2.model.InstanceStateName; import software.amazon.awssdk.services.ec2.model.Reservation; import software.amazon.awssdk.services.ec2.model.Tag; import software.amazon.awssdk.services.ec2.model.TerminateInstancesRequest;

Depois de migrarmos todos os arquivos em nosso aplicativo, não precisaremos mais das dependências v1 em nosso arquivo POM. Remova o BOM v1 da dependencyManagement seção, se estiver usando, e todos os blocos de dependência v1.

7. Refatore o código para usar os aprimoramentos da API v2

Para o trecho que estamos migrando, podemos, opcionalmente, usar um paginador v2 e deixar o SDK gerenciar as solicitações baseadas em tokens para obter mais dados.

Podemos substituir toda a do cláusula pela seguinte.

DescribeInstancesIterable responses = ec2.describeInstancesPaginator(request); responses.reservations().stream() .forEach(reservation -> reservation.instances() .forEach(instance -> { if (RUNNING_STATES.contains(instance.state().nameAsString())) { runningInstances.put(instance.instanceId(), instance); } }));