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
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)
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
|
ec2
|
|
automatische Skalierung
|
automatische Skalierung
|
|
cloudformation
|
cloudformation
|
|
Identitätsmanagement*
|
ich bin*
|
|
* 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
durchsoftware.amazon.awssdk.services.ec2.Ec2Client
und wechseln SieAmazonEC2Client
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 |
---|---|
|
|
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 |
---|---|
|
|
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
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); } }));