step-by-step Instructions de migration avec exemple - AWS SDK for Java 2.x

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

step-by-step Instructions de migration avec exemple

Cette section fournit un step-by-step guide pour migrer votre application qui utilise actuellement le SDK pour Java v1.x vers le SDK pour Java 2.x. La première partie présente un aperçu des étapes suivies par un exemple détaillé de migration.

Les étapes décrites ici décrivent une migration d'un cas d'utilisation normal, dans lequel l'application appelle à l' Services AWS aide de clients de service pilotés par un modèle. Si vous devez migrer du code qui utilise des API de niveau supérieur, telles que S3 Transfer Manager ou CloudFrontPresigning, reportez-vous à la section sous la Quelle est la différence entre la version AWS SDK for Java 1.x et la version 2.x table des matières.

L'approche décrite ici est une suggestion. Vous pouvez utiliser d'autres techniques et tirer parti des fonctionnalités d'édition de code de votre IDE pour obtenir le même résultat.

Présentation des étapes

1. Commencez par ajouter le SDK pour Java 2.x BOM

En ajoutant l'élément Maven BOM (Bill of Materials) pour le SDK pour Java 2.x à votre fichier POM, vous vous assurez que toutes les dépendances v2 dont vous avez besoin proviennent de la même version. Votre POM peut contenir à la fois des dépendances v1 et v2. Cela vous permet de migrer votre code progressivement plutôt que de le modifier en une seule fois.

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

Vous pouvez trouver la dernière version sur le référentiel central de Maven.

2. Rechercher dans les fichiers les instructions d'importation de classe v1

En scannant les fichiers de votre application à la recherche des Service_ID utilisés dans les importations de la version 1, vous trouverez les Service_ID uniques utilisés. Un SERVICE_ID est un nom court et unique pour un. Service AWScognitoidentityC'est le cas par exemple du SERVICE_ID pour Amazon Cognito Identity.

3. Déterminez les dépendances Maven de la version 2 à partir des instructions d'importation de la version 1

Une fois que vous avez trouvé tous les Service_ID uniques de la v1, vous pouvez déterminer l'artefact Maven correspondant à la dépendance v2 en vous référant à. Nom du package vers les mappages Artifactid Maven

4. Ajouter des éléments de dépendance v2 au fichier POM

Mettez à jour le fichier Maven POM avec les éléments de dépendance déterminés à l'étape 3.

5. Dans les fichiers Java, passez progressivement des classes v1 aux classes v2

Lorsque vous remplacez les classes v1 par des classes v2, apportez les modifications nécessaires pour prendre en charge l'API v2, par exemple en utilisant des générateurs plutôt que des constructeurs et en utilisant des getters et des setters fluides.

6. Supprimer les dépendances Maven v1 du POM et les importations v1 des fichiers

Après avoir migré votre code pour utiliser les classes v2, supprimez toutes les importations v1 restantes des fichiers et toutes les dépendances de votre fichier de compilation.

7. Refactorisez le code pour utiliser les améliorations de l'API v2

Une fois le code compilé et passé avec succès les tests, vous pouvez tirer parti des améliorations apportées à la version 2, telles que l'utilisation d'un autre client HTTP ou de différents paginateurs pour simplifier le code. Il s'agit d'une étape facultative.

Exemple de migration

Dans cet exemple, nous migrons une application qui utilise le SDK pour Java v1 et accède Services AWSà plusieurs d'entre eux. Nous travaillons en détail sur la méthode v1 suivante à l'étape 5. Il s'agit d'une méthode dans une classe qui contient huit méthodes et l'application compte 32 classes.

Seules les importations du SDK v1 sont répertoriées ci-dessous à partir du fichier 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. Ajouter la version v2 de Maven BOM

Ajoutez la nomenclature Maven pour le SDK pour Java 2.x au POM avec toutes les autres dépendances de la section. dependencyManagement Si votre fichier POM contient la nomenclature de la version 1 du SDK, laissez-la pour le moment. Il sera supprimé ultérieurement.

<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. Rechercher dans les fichiers les instructions d'importation de classe v1

Recherchez dans le code de l'application les occurrences uniques deimport com.amazonaws.services. Cela nous aide à déterminer les dépendances v1 utilisées par le projet. Si votre application possède un fichier Maven POM dont les dépendances v1 sont répertoriées, vous pouvez utiliser ces informations à la place.

Dans cet exemple, nous utilisons la commande ripgrep(rg) pour effectuer une recherche dans la base de code.

À la racine de votre base de code, exécutez la ripgrep commande suivante. Une fois ripgrep les instructions d'importation trouvées, elles sont redirigées vers les uniq commandes cutsort, et pour isoler les Service_ID.

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

Pour cette application, les Service_ID suivants sont enregistrés sur la console.

autoscaling cloudformation ec2 identitymanagement

Cela indique qu'au moins une occurrence de chacun des noms de package suivants a été utilisée dans les import instructions. Quatre de nos objectifs, les noms de classe individuels n'ont pas d'importance. Il suffit de trouver les Service_ID utilisés.

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

3. Déterminez les dépendances Maven de la version 2 à partir des instructions d'importation de la version 1

Les Service_ID de la v1 que nous avons isolés à l'étape 2, par exemple autoscaling et, cloudformation peuvent être mappés sur le même SERVICE_ID de la version v2 pour la plupart. Étant donné que l'artifactid Maven v2 correspond au SERVICE_ID dans la plupart des cas, vous disposez des informations dont vous avez besoin pour ajouter des blocs de dépendance à votre fichier POM.

Le tableau suivant montre comment déterminer les dépendances de la v2.

v1 SERVICE_ID correspond à...

nom du package

v2 SERVICE_ID correspond à...

nom du package

Dépendance Maven v2

ec2

com.amazonaws.services.ec2.*

ec2

software.amazon.awssdk.services.ec2.*

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

mise à l'échelle automatique

com.amazonaws.services.autoscaling.*

mise à l'échelle automatique

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>
gestion de l'identité*

com.amazonaws.services.identitymanagement.*

je suis*

software.amazon.awssdk.iam.*

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

* Le iam mappage identitymanagement vers est une exception lorsque le SERVICE_ID diffère d'une version à l'autre. Reportez-vous Nom du package vers les mappages Artifactid Maven aux exceptions si Maven ou Gradle ne peuvent pas résoudre la dépendance à la v2.

4. Ajouter des éléments de dépendance v2 au fichier POM

À l'étape 3, nous avons déterminé les quatre blocs de dépendance à ajouter au fichier POM. Nous n'avons pas besoin d'ajouter de version car nous avons spécifié la nomenclature à l'étape 1. Une fois les importations ajoutées, notre fichier POM contient les éléments de dépendance suivants.

... <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. Dans les fichiers Java, passez progressivement des classes v1 aux classes v2

Dans la méthode de migration, nous voyons

  • Un client du service EC2 de. com.amazonaws.services.ec2.AmazonEC2Client

  • Plusieurs classes de modèles EC2 ont été utilisées. Par exemple DescribeInstancesRequest etDescribeInstancesResult.

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; } ...

Notre objectif est de remplacer toutes les importations v1 par des importations v2. Nous procédons un cours à la fois.

a. Remplacer la déclaration d'importation ou le nom de classe

Nous voyons que le premier paramètre de la describeRunningInstances méthode est une AmazonEC2Client instance v1. Effectuez l’une des actions suivantes :

  • Remplacez le fichier d'importation com.amazonaws.services.ec2.AmazonEC2Client par software.amazon.awssdk.services.ec2.Ec2Client et AmazonEC2Client remplacez-le parEc2Client.

  • Changez le type de paramètre en Ec2Client et laissez l'IDE nous demander l'importation correcte. Notre IDE nous demandera d'importer la classe v2 car les noms des clients diffèrent... AmazonEC2Client etEc2Client. Cette approche ne fonctionne pas si le nom de classe est le même dans les deux versions.

b. Remplacer les classes de modèles v1 par des équivalents v2

Après le passage à la v2Ec2Client, si nous utilisons un IDE, nous voyons des erreurs de compilation dans l'instruction suivante.

result = ec2.describeInstances(request);

L'erreur de compilation résulte de l'utilisation d'une instance de v1 DescribeInstancesRequest comme paramètre de la Ec2Client describeInstances méthode v2. Pour résoudre le problème, effectuez les instructions de remplacement ou d'importation suivantes.

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

c. Changez les constructeurs v1 en constructeurs v2.

Nous voyons toujours des erreurs de compilation car il n'y a pas de constructeur sur les classes v2. Pour corriger cela, apportez les modifications suivantes.

modification to
final DescribeInstancesRequest request = new DescribeInstancesRequest() .withInstanceIds(instanceIdsCopy);
final DescribeInstancesRequest request = DescribeInstancesRequest.builder() .instanceIds(instanceIdsCopy) .build();

d. Remplacer les objets de *Result réponse v1 par des *Response équivalents v2

Une différence constante entre la v1 et la v2 est que tous les objets de réponse de la v2 se terminent par *Response au lieu de *Result. Remplacez l'DescribeInstancesResultimportation v1 par l'importation v2,DescribeInstancesResponse.

d. Apporter des modifications à l'API

La déclaration suivante nécessite quelques modifications.

request.setNextToken(result.getNextToken());

Dans la version 2, les méthodes setter n'utilisent pas le set ou avecprefix. Les méthodes Getter préfixées par get ont également disparu dans le SDK pour Java 2.x

Les classes de modèles, telles que l'requestinstance, sont immuables dans la version 2, nous devons donc en créer une nouvelle DescribeInstancesRequest avec un générateur.

Dans la version 2, l'instruction devient la suivante.

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

d. Répétez jusqu'à ce que la méthode soit compilée avec les classes v2

Continuez avec le reste du code. Remplacez les importations v1 par des importations v2 et corrigez les erreurs de compilation. Reportez-vous à la référence de l'API v2 et à la référence What's different si nécessaire.

Après avoir migré cette méthode unique, nous avons le code v2 suivant.

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; } ...

Comme nous migrons une seule méthode dans un fichier Java avec huit méthodes, nous avons un mélange d'importations v1 et v2 au fur et à mesure que nous travaillons sur le fichier. Nous avons ajouté les six dernières instructions d'importation au fur et à mesure de l'exécution des étapes.

Une fois que nous aurons migré tout le code, il n'y aura plus d'instructions d'importation v1.

6. Supprimer les dépendances Maven v1 du POM et les importations v1 des fichiers

Après avoir migré tout le code v1 du fichier, nous avons les instructions d'importation du SDK v2 suivantes.

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;

Après avoir migré tous les fichiers de notre application, nous n'avons plus besoin des dépendances v1 dans notre fichier POM. Supprimez la nomenclature v1 de la dependencyManagement section, si vous en utilisez, ainsi que tous les blocs de dépendance v1.

7. Refactorisez le code pour utiliser les améliorations de l'API v2

Pour l'extrait que nous avons migré, nous pouvons éventuellement utiliser un paginateur v2 et laisser le SDK gérer les demandes de données supplémentaires basées sur des jetons.

Nous pouvons remplacer l'intégralité de la do clause par la suivante.

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