step-by-step Migrationsanweisungen mit Beispiel - AWS SDK for Java 2.x

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

step-by-step Migrationsanweisungen mit Beispiel

Dieser Abschnitt enthält eine step-by-step Anleitung zur Migration Ihrer Anwendung, die derzeit das SDK for Java v1.x verwendet, auf das SDK for Java 2.x. Der erste Teil bietet einen Überblick über die Schritte, gefolgt von einem detaillierten Beispiel für eine Migration.

Die hier beschriebenen Schritte beschreiben die Migration eines normalen Anwendungsfalls, bei dem die Anwendung AWS -Services mithilfe modellgesteuerter Service-Clients aufruft. Wenn Sie Code migrieren müssen, der APIs auf höherer Ebene wie S3 Transfer Manager oder CloudFrontPresigning verwendet, finden Sie weitere Informationen im Abschnitt unter dem Was ist der Unterschied zwischen AWS SDK for Java 1.x und 2.x Inhaltsverzeichnis.

Der hier beschriebene Ansatz ist ein Vorschlag. Sie können andere Techniken verwenden und die Codebearbeitungsfunktionen Ihrer IDE nutzen, um dasselbe Ergebnis zu erzielen.

Übersicht über die Schritte

1. Fügen Sie zunächst das SDK for Java 2.x BOM hinzu

Indem Sie das Maven BOM (Bill of Materials) -Element für das SDK for Java 2.x zu Ihrer POM-Datei hinzufügen, stellen Sie sicher, dass alle benötigten v2-Abhängigkeiten aus derselben Version stammen. Ihr POM kann sowohl v1- als auch v2-Abhängigkeiten enthalten. Auf diese Weise können Sie Ihren Code schrittweise migrieren, anstatt ihn auf einmal zu ändern.

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

Sie finden die neueste Version im Maven Central Repository.

2. Suchen Sie in Dateien nach Anweisungen zum Import der Klasse V1

Wenn Sie die Dateien in Ihrer Anwendung nach Service_IDs durchsuchen, die bei V1-Importen verwendet wurden, finden Sie die verwendeten eindeutigen Service_IDs. Eine SERVICE_ID ist ein kurzer, eindeutiger Name für eine. AWS -Service Zum Beispiel cognitoidentity die SERVICE_ID für Amazon Cognito Identity.

3. Ermitteln Sie die Maven-Abhängigkeiten der Version 2 anhand der V1-Importanweisungen

Nachdem Sie alle eindeutigen v1-Service_IDs gefunden haben, können Sie das entsprechende Maven-Artefakt für die v2-Abhängigkeit ermitteln, indem Sie auf verweisen. Zuordnungen von Paketnamen zu Maven-ArtifactID-Zuordnungen

4. Fügen Sie der POM-Datei v2-Abhängigkeitselemente hinzu

Aktualisieren Sie die Maven-POM-Datei mit den in Schritt 3 festgelegten Abhängigkeitselementen.

5. Wechseln Sie in den Java-Dateien schrittweise von den v1-Klassen zu v2-Klassen

Wenn Sie v1-Klassen durch v2-Klassen ersetzen, nehmen Sie die erforderlichen Änderungen vor, um die v2-API zu unterstützen, z. B. die Verwendung von Buildern anstelle von Konstruktoren und die Verwendung flüssiger Getter und Setter.

6. Entfernen Sie v1-Maven-Abhängigkeiten aus dem POM und v1-Importen aus Dateien

Nachdem Sie Ihren Code zur Verwendung von v2-Klassen migriert haben, entfernen Sie alle übrig gebliebenen v1-Importe aus Dateien und alle Abhängigkeiten aus Ihrer Build-Datei.

7. Refaktorieren Sie den Code, um v2-API-Verbesserungen zu verwenden

Nachdem der Code erfolgreich kompiliert und die Tests bestanden hat, können Sie die Vorteile von v2-Verbesserungen nutzen, z. B. die Verwendung eines anderen HTTP-Clients oder von Paginatoren, um den Code zu vereinfachen. Dieser Schritt ist optional.

Beispiel für eine Migration

In diesem Beispiel migrieren wir eine Anwendung, die das SDK for Java v1 verwendet und auf mehrere AWS -Services zugreift. In Schritt 5 gehen wir die folgende v1-Methode detailliert durch. Dies ist eine Methode in einer Klasse, die acht Methoden enthält, und es gibt 32 Klassen in der Anwendung.

Im Folgenden sind nur die v1-SDK-Importe aus der Java-Datei aufgeführt.

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. Fügen Sie v2 Maven BOM hinzu

Fügen Sie dem POM die Maven-Stückliste für das SDK for Java 2.x zusammen mit allen anderen Abhängigkeiten in diesem Abschnitt hinzu. dependencyManagement Wenn Ihre POM-Datei die BOM für Version 1 des SDK enthält, lassen Sie sie vorerst stehen. Sie wird in einem späteren Schritt entfernt.

<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. Suchen Sie in Dateien nach Importanweisungen der Klasse V1

Durchsuchen Sie den Code der Anwendung nach eindeutigen Vorkommen vonimport com.amazonaws.services. Dies hilft uns, die vom Projekt verwendeten v1-Abhängigkeiten zu ermitteln. Wenn in Ihrer Anwendung eine Maven-POM-Datei mit aufgelisteten V1-Abhängigkeiten vorhanden ist, können Sie stattdessen diese Informationen verwenden.

In diesem Beispiel verwenden wir den Befehl ripgrep(rg), um die Codebasis zu durchsuchen.

Führen Sie im Stammverzeichnis Ihrer Codebasis den folgenden ripgrep Befehl aus. Nachdem die ripgrep Importanweisungen gefunden wurden, werden sie über die Pipeline an die uniq Befehle, und cut übergebensort, um die Service_IDs zu isolieren.

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

Für diese Anwendung werden die folgenden Service_IDs in der Konsole protokolliert.

autoscaling cloudformation ec2 identitymanagement

Dies weist darauf hin, dass jeder der folgenden Paketnamen, die in import Anweisungen verwendet wurden, mindestens einmal vorkommt. Für unsere Zwecke spielen die einzelnen Klassennamen keine Rolle. Wir müssen nur die Service_IDs finden, die verwendet werden.

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

3. Ermitteln Sie die v2-Maven-Abhängigkeiten anhand der v1-Importanweisungen

Die Service_IDs für Version 1, die wir aus Schritt 2 isoliert haben — zum Beispiel autoscaling und cloudformation — können größtenteils derselben v2-SERVICE_ID zugeordnet werden. Da die v2-Maven-ArtifactID in den meisten Fällen mit der SERVICE_ID übereinstimmt, verfügen Sie über die Informationen, die Sie benötigen, um Ihrer POM-Datei Abhängigkeitsblöcke hinzuzufügen.

Die folgende Tabelle zeigt, wie wir die v2-Abhängigkeiten ermitteln können.

v1 SERVICE_ID ist zugeordnet zu...

Name des Pakets

v2 SERVICE_ID ist zugeordnet zu...

Name des Pakets

v2 Maven-Abhängigkeit

ec2

com.amazonaws.services.ec2.*

ec2

software.amazon.awssdk.services.ec2.*

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

automatische Skalierung

com.amazonaws.services.autoscaling.*

automatische Skalierung

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>
Identitätsmanagement*

com.amazonaws.services.identitymanagement.*

ich bin*

software.amazon.awssdk.iam.*

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

* Die iam Zuordnung identitymanagement zu ist eine Ausnahme, bei der sich die SERVICE_ID zwischen den Versionen unterscheidet. In den Zuordnungen von Paketnamen zu Maven-ArtifactID-Zuordnungen finden Sie Ausnahmen, falls Maven oder Gradle die v2-Abhängigkeit nicht auflösen können.

4. Fügen Sie der POM-Datei v2-Abhängigkeitselemente hinzu

In Schritt 3 haben wir die vier Abhängigkeitsblöcke bestimmt, die der POM-Datei hinzugefügt werden müssen. Wir müssen keine Version hinzufügen, da wir die Stückliste in Schritt 1 angegeben haben. Nachdem die Importe hinzugefügt wurden, enthält unsere POM-Datei die folgenden Abhängigkeitselemente.

... <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. Wechseln Sie in den Java-Dateien schrittweise von den v1-Klassen zu v2-Klassen

In der Methode, die wir migrieren, sehen wir

  • Ein EC2-Serviceclient von. com.amazonaws.services.ec2.AmazonEC2Client

  • Es wurden mehrere EC2-Modellklassen verwendet. Zum Beispiel DescribeInstancesRequest und. DescribeInstancesResult

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

Unser Ziel ist es, alle v1-Importe durch v2-Importe zu ersetzen. Wir fahren eine Klasse nach der anderen fort.

a. Ersetzt die Importanweisung oder den Klassennamen

Wir sehen, dass der erste Parameter der describeRunningInstances Methode eine AmazonEC2Client v1-Instanz ist. Führen Sie eine der folgenden Aktionen aus:

  • Ersetzen Sie den Import für com.amazonaws.services.ec2.AmazonEC2Client durch software.amazon.awssdk.services.ec2.Ec2Client und wechseln Sie AmazonEC2Client zuEc2Client.

  • Ändern Sie den Parametertyp in Ec2Client und lassen Sie uns von der IDE nach dem richtigen Import fragen. Unsere IDE fordert uns auf, die v2-Klasse zu importieren, da sich die Client-Namen unterscheiden — AmazonEC2Client undEc2Client. Dieser Ansatz funktioniert nicht, wenn der Klassenname in beiden Versionen derselbe ist.

b. Ersetzen Sie v1-Modellklassen durch v2-Äquivalente

Wenn wir nach der Umstellung auf Version 2 Ec2Client eine IDE verwenden, werden in der folgenden Anweisung Kompilierungsfehler angezeigt.

result = ec2.describeInstances(request);

Der Kompilierungsfehler resultiert aus der Verwendung einer Instanz von v1 DescribeInstancesRequest als Parameter für die Ec2Client describeInstances v2-Methode. Um das Problem zu beheben, geben Sie die folgenden Ersatz- oder Importanweisungen ein.

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

c. Ändern Sie v1-Konstruktoren in v2-Builder.

Wir sehen immer noch Kompilierungsfehler, da es keine Konstruktoren für v2-Klassen gibt. Um das Problem zu beheben, nehmen Sie die folgende Änderung vor.

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

d. Ersetzen Sie *Result v1-Antwortobjekte durch *Response v2-Äquivalente

Ein konsistenter Unterschied zwischen v1 und v2 besteht darin, dass alle Antwortobjekte in v2 mit *Response statt mit enden. *Result Ersetzen Sie den DescribeInstancesResult v1-Import durch den v2-Import,DescribeInstancesResponse.

d. Nehmen Sie API-Änderungen vor

Die folgende Aussage benötigt einige Änderungen.

request.setNextToken(result.getNextToken());

In Version 2 verwenden Setter-Methoden das set oder mit prefix nicht. Getter-Methoden mit dem Präfix get sind auch im SDK for Java 2.x weg

Modellklassen, wie die request Instanz, sind in Version 2 unveränderlich, daher müssen wir mit einem Builder eine neue DescribeInstancesRequest Klasse erstellen.

In Version 2 lautet die Anweisung wie folgt.

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

d. Wiederholen Sie den Vorgang, bis die Methode mit v2-Klassen kompiliert wurde

Fahren Sie mit dem Rest des Codes fort. Ersetzen Sie v1-Importe durch v2-Importe und beheben Sie die Kompilierungsfehler. Weitere Informationen finden Sie je nach Bedarf in der v2-API-Referenz und der Referenz Was ist anders.

Nachdem wir diese einzelne Methode migriert haben, haben wir den folgenden v2-Code.

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

Da wir eine einzelne Methode in einer Java-Datei mit acht Methoden migrieren, haben wir beim Durcharbeiten der Datei eine Mischung aus v1- und v2-Importen. Wir haben die letzten sechs Importanweisungen hinzugefügt, während wir die Schritte ausgeführt haben.

Nachdem wir den gesamten Code migriert haben, wird es keine v1-Importanweisungen mehr geben.

6. Entfernen Sie v1-Maven-Abhängigkeiten aus dem POM und v1-Importe aus Dateien

Nachdem wir den gesamten v1-Code in der Datei migriert haben, haben wir die folgenden v2-SDK-Importanweisungen.

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;

Nachdem wir alle Dateien in unserer Anwendung migriert haben, benötigen wir die v1-Abhängigkeiten in unserer POM-Datei nicht mehr. Entfernen Sie die v1-BOM aus dem dependencyManagement Abschnitt, falls Sie sie verwenden, und alle v1-Abhängigkeitsblöcke.

7. Refaktorieren Sie den Code, um v2-API-Verbesserungen zu verwenden

Für das Snippet, das wir migriert haben, können wir optional einen v2-Paginator verwenden und das SDK die tokenbasierten Anfragen nach weiteren Daten verwalten lassen.

Wir können die gesamte Klausel durch die folgende ersetzen. do

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