Skip to content

Commit 77efad7

Browse files
authored
Add mapping for core exception types and getters (#5326)
1 parent bbf1287 commit 77efad7

File tree

8 files changed

+293
-29
lines changed

8 files changed

+293
-29
lines changed

migration-tool/src/main/java/software/amazon/awssdk/migration/internal/utils/NamingConversionUtils.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public static String getV2Equivalent(String currentFqcn) {
3737
String v2PackagePrefix = packagePrefix.replace(V1_PACKAGE_PREFIX, V2_PACKAGE_PREFIX);
3838

3939
if (Stream.of("Abstract", "Amazon", "AWS").anyMatch(v1ClassName::startsWith)) {
40-
v2ClassName = getV2ClientEquivalent(v1ClassName);
40+
v2ClassName = getV2ClientOrExceptionEquivalent(v1ClassName);
4141
} else if (v1ClassName.endsWith("Result")) {
4242
int lastIndex = v1ClassName.lastIndexOf("Result");
4343
v2ClassName = v1ClassName.substring(0, lastIndex) + "Response";
@@ -46,7 +46,7 @@ public static String getV2Equivalent(String currentFqcn) {
4646
return v2PackagePrefix + "." + v2ClassName;
4747
}
4848

49-
private static String getV2ClientEquivalent(String className) {
49+
private static String getV2ClientOrExceptionEquivalent(String className) {
5050
if (className.startsWith("Abstract")) {
5151
className = className.substring(8);
5252
}
@@ -58,6 +58,10 @@ private static String getV2ClientEquivalent(String className) {
5858

5959
String v2Style = CodegenNamingUtils.pascalCase(className);
6060

61+
if (className.endsWith("Exception")) {
62+
return v2Style;
63+
}
64+
6165
if (!className.endsWith("Client") && !className.endsWith("Builder")) {
6266
v2Style = v2Style + "Client";
6367
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#
2+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License").
5+
# You may not use this file except in compliance with the License.
6+
# A copy of the License is located at
7+
#
8+
# http://aws.amazon.com/apache2.0
9+
#
10+
# or in the "license" file accompanying this file. This file is distributed
11+
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
# express or implied. See the License for the specific language governing
13+
# permissions and limitations under the License.
14+
#
15+
---
16+
type: specs.openrewrite.org/v1beta/recipe
17+
name: software.amazon.awssdk.ChangeExceptionTypes
18+
displayName: Change SDK Exception types from v1 to v2
19+
recipeList:
20+
- org.openrewrite.java.ChangeType:
21+
oldFullyQualifiedTypeName: com.amazonaws.SdkBaseException
22+
newFullyQualifiedTypeName: software.amazon.awssdk.core.exception.SdkException
23+
- org.openrewrite.java.ChangeType:
24+
oldFullyQualifiedTypeName: com.amazonaws.AmazonClientException
25+
newFullyQualifiedTypeName: software.amazon.awssdk.core.exception.SdkException
26+
- org.openrewrite.java.ChangeType:
27+
oldFullyQualifiedTypeName: com.amazonaws.SdkClientException
28+
newFullyQualifiedTypeName: software.amazon.awssdk.core.exception.SdkClientException
29+
30+
- org.openrewrite.java.ChangeMethodName:
31+
methodPattern: com.amazonaws.AmazonServiceException getRequestId
32+
newMethodName: requestId
33+
- org.openrewrite.java.ChangeMethodName:
34+
methodPattern: com.amazonaws.AmazonServiceException getErrorCode
35+
newMethodName: awsErrorDetails().errorCode
36+
- org.openrewrite.java.ChangeMethodName:
37+
methodPattern: com.amazonaws.AmazonServiceException getServiceName
38+
newMethodName: awsErrorDetails().serviceName
39+
- org.openrewrite.java.ChangeMethodName:
40+
methodPattern: com.amazonaws.AmazonServiceException getErrorMessage
41+
newMethodName: awsErrorDetails().errorMessage
42+
- org.openrewrite.java.ChangeMethodName:
43+
methodPattern: com.amazonaws.AmazonServiceException getStatusCode
44+
newMethodName: awsErrorDetails().sdkHttpResponse().statusCode
45+
### TODO: v2 returns Map<String, List<String>>. Convert it to Map<String, String>
46+
- org.openrewrite.java.ChangeMethodName:
47+
methodPattern: com.amazonaws.AmazonServiceException getHttpHeaders
48+
newMethodName: awsErrorDetails().sdkHttpResponse().headers
49+
- org.openrewrite.java.ChangeMethodName:
50+
methodPattern: com.amazonaws.AmazonServiceException getRawResponse
51+
newMethodName: awsErrorDetails().rawResponse().asByteArray
52+
- org.openrewrite.java.ChangeMethodName:
53+
methodPattern: com.amazonaws.AmazonServiceException getRawResponseContent
54+
newMethodName: awsErrorDetails().rawResponse().asUtf8String
55+
- software.amazon.awssdk.migration.internal.recipe.AddCommentToMethod:
56+
methodPattern: com.amazonaws.AmazonServiceException getErrorType
57+
comment: getErrorType is not supported in v2. AwsServiceException is a service error in v2. Consider removing it.
58+
- software.amazon.awssdk.migration.internal.recipe.AddCommentToMethod:
59+
methodPattern: com.amazonaws.AmazonServiceException getProxyHost
60+
comment: getProxyHost is not supported in v2. Please submit a feature request https://github.com/aws/aws-sdk-java-v2/issues
61+
- org.openrewrite.java.ChangeType:
62+
oldFullyQualifiedTypeName: com.amazonaws.AmazonServiceException
63+
newFullyQualifiedTypeName: software.amazon.awssdk.awscore.exception.AwsServiceException
64+
- org.openrewrite.java.ChangeType:
65+
oldFullyQualifiedTypeName: com.amazonaws.AbortedException
66+
newFullyQualifiedTypeName: software.amazon.awssdk.core.exception.AbortedException
67+
- org.openrewrite.java.ChangeType:
68+
oldFullyQualifiedTypeName: com.amazonaws.http.timers.client.ClientExecutionTimeoutException
69+
newFullyQualifiedTypeName: software.amazon.awssdk.core.exception.ApiCallTimeoutException
70+
- org.openrewrite.java.ChangeType:
71+
oldFullyQualifiedTypeName: com.amazonaws.http.exception.HttpRequestTimeoutException
72+
newFullyQualifiedTypeName: software.amazon.awssdk.core.exception.ApiCallAttemptTimeoutException
73+
- org.openrewrite.java.ChangeType:
74+
oldFullyQualifiedTypeName: com.amazonaws.http.timers.client.SdkInterruptedException
75+
newFullyQualifiedTypeName: software.amazon.awssdk.core.exception.SdkInterruptedException
76+
- org.openrewrite.java.ChangeType:
77+
oldFullyQualifiedTypeName: com.amazonaws.http.timers.client.SdkInterruptedException
78+
newFullyQualifiedTypeName: software.amazon.awssdk.core.exception.SdkInterruptedException
79+
- org.openrewrite.java.ChangeType:
80+
oldFullyQualifiedTypeName: com.amazonaws.internal.CRC32MismatchException
81+
newFullyQualifiedTypeName: software.amazon.awssdk.core.exception.Crc32MismatchException

migration-tool/src/main/resources/META-INF/rewrite/change-sdk-core-types.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
---
1616
type: specs.openrewrite.org/v1beta/recipe
1717
name: software.amazon.awssdk.ChangeSdkCoreTypes
18-
displayName: Change Maven dependency groupId, artifactId and/or the version example
18+
displayName: Change SDK core types from v1 to v2
1919
recipeList:
2020
- software.amazon.awssdk.ChangeRegionTypes
2121
- software.amazon.awssdk.ChangeAuthTypes
22-
- software.amazon.awssdk.ChangeConfigTypes
22+
- software.amazon.awssdk.ChangeConfigTypes
23+
- software.amazon.awssdk.ChangeExceptionTypes

migration-tool/src/test/java/software/amazon/awssdk/migration/internal/utils/NamingConversionUtilsTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,11 @@ void v1AsyncClients_shouldConvertToV2() {
7171
assertThat(NamingConversionUtils.getV2Equivalent("com.amazonaws.services.iot.AWSIotAsyncClientBuilder"))
7272
.isEqualTo("software.amazon.awssdk.services.iot.IotAsyncClientBuilder");
7373
}
74+
75+
@Test
76+
void v1Exception_shouldConvertToV2() {
77+
78+
assertThat(NamingConversionUtils.getV2Equivalent("com.amazonaws.services.iot.AmazonIOTException"))
79+
.isEqualTo("software.amazon.awssdk.services.iot.IotException");
80+
}
7481
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.migration.recipe;
17+
18+
import static org.openrewrite.java.Assertions.java;
19+
20+
import java.io.IOException;
21+
import java.io.InputStream;
22+
import java.net.URI;
23+
import java.util.Properties;
24+
import org.junit.jupiter.api.Test;
25+
import org.junit.jupiter.api.condition.EnabledOnJre;
26+
import org.junit.jupiter.api.condition.JRE;
27+
import org.openrewrite.config.Environment;
28+
import org.openrewrite.config.YamlResourceLoader;
29+
import org.openrewrite.java.Java8Parser;
30+
import org.openrewrite.test.RecipeSpec;
31+
import org.openrewrite.test.RewriteTest;
32+
import software.amazon.awssdk.migration.internal.recipe.HttpSettingsToHttpClient;
33+
34+
public class ChangeExceptionTypesTest implements RewriteTest {
35+
36+
@Override
37+
public void defaults(RecipeSpec spec) {
38+
try (InputStream stream = getClass().getResourceAsStream("/META-INF/rewrite/change-exception-types.yml")) {
39+
spec.recipes(Environment.builder()
40+
.load(new YamlResourceLoader(stream, URI.create("rewrite.yml"), new Properties()))
41+
.build()
42+
.activateRecipes("software.amazon.awssdk.ChangeExceptionTypes"));
43+
} catch (IOException e) {
44+
throw new RuntimeException(e);
45+
}
46+
47+
spec.parser(Java8Parser.builder().classpath("aws-java-sdk-sqs","aws-sdk-java", "sdk-core"));
48+
}
49+
50+
@Test
51+
@EnabledOnJre({JRE.JAVA_8})
52+
void exceptionGetter_shouldRewrite() {
53+
rewriteRun(
54+
java(
55+
"import com.amazonaws.AmazonServiceException;\n"
56+
+ "import java.util.Map;\n"
57+
+ "\n"
58+
+ "public class Example {\n"
59+
+ "\n"
60+
+ " void test() {\n"
61+
+ " AmazonServiceException serviceException = null;\n"
62+
+ " String requestId = serviceException.getRequestId();\n"
63+
+ " String errorCode = serviceException.getErrorCode();\n"
64+
+ " String errorMessage = serviceException.getErrorMessage();\n"
65+
+ " String serviceName = serviceException.getServiceName();\n"
66+
+ " int statusCode = serviceException.getStatusCode();\n"
67+
+ " Map<String, String> httpHeaders = serviceException.getHttpHeaders();\n"
68+
+ " byte[] rawResponse = serviceException.getRawResponse();\n"
69+
+ " String rawResponseContent = serviceException.getRawResponseContent();\n"
70+
+ "\n"
71+
+ " }\n"
72+
+ "}",
73+
"import software.amazon.awssdk.awscore.exception.AwsServiceException;\n"
74+
+ "\n"
75+
+ "import java.util.Map;\n"
76+
+ "\n"
77+
+ "public class Example {\n"
78+
+ "\n"
79+
+ " void test() {\n"
80+
+ " AwsServiceException serviceException = null;\n"
81+
+ " String requestId = serviceException.requestId();\n"
82+
+ " String errorCode = serviceException.awsErrorDetails().errorCode();\n"
83+
+ " String errorMessage = serviceException.awsErrorDetails().errorMessage();\n"
84+
+ " String serviceName = serviceException.awsErrorDetails().serviceName();\n"
85+
+ " int statusCode = serviceException.awsErrorDetails().sdkHttpResponse().statusCode();\n"
86+
+ " Map<String, String> httpHeaders = serviceException.awsErrorDetails().sdkHttpResponse().headers();\n"
87+
+ " byte[] rawResponse = serviceException.awsErrorDetails().rawResponse().asByteArray();\n"
88+
+ " String rawResponseContent = serviceException.awsErrorDetails().rawResponse().asUtf8String();\n"
89+
+ "\n"
90+
+ " }\n"
91+
+ "}"
92+
)
93+
);
94+
}
95+
96+
@Test
97+
@EnabledOnJre({JRE.JAVA_8})
98+
void exceptionGetter_NotSupported_shouldAddComment() {
99+
rewriteRun(
100+
java(
101+
"import com.amazonaws.AmazonServiceException;\n"
102+
+ "\n"
103+
+ "public class Example {\n"
104+
+ "\n"
105+
+ " void test() {\n"
106+
+ " AmazonServiceException serviceException = null;\n"
107+
+ " String proxyHost = serviceException.getProxyHost();\n"
108+
+ " AmazonServiceException.ErrorType errorCode = serviceException.getErrorType();\n"
109+
+ " }\n"
110+
+ "}",
111+
"import software.amazon.awssdk.awscore.exception.AwsServiceException;\n"
112+
+ "\n"
113+
+ "public class Example {\n"
114+
+ "\n"
115+
+ " void test() {\n"
116+
+ " AwsServiceException serviceException = null;\n"
117+
+ " String proxyHost = serviceException/*AWS SDK for Java v2 migration: getProxyHost is not supported in v2. Please submit a feature request https://github.com/aws/aws-sdk-java-v2/issues*/.getProxyHost();\n"
118+
+ " AwsServiceException.ErrorType errorCode = serviceException/*AWS SDK for Java v2 migration: getErrorType is not supported in v2. AwsServiceException is a service error in v2. Consider removing it.*/.getErrorType();\n"
119+
+ " }\n"
120+
+ "}"
121+
)
122+
);
123+
}
124+
}

migration-tool/src/test/java/software/amazon/awssdk/migration/recipe/ChangeSdkTypeTest.java

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,39 +28,46 @@ public class ChangeSdkTypeTest implements RewriteTest {
2828

2929
@Override
3030
public void defaults(RecipeSpec spec) {
31-
spec.recipe(new ChangeSdkType());
31+
spec.recipe(new ChangeSdkType()).parser(Java8Parser.builder().classpath("aws-java-sdk-sqs","sqs"));
3232
}
3333

3434
@Test
3535
@EnabledOnJre({JRE.JAVA_8})
3636
void shouldChangeVariables() {
3737
rewriteRun(
38-
spec -> spec.parser(Java8Parser.builder().classpath("aws-java-sdk-sqs")),
3938
java(
4039
"import com.amazonaws.services.sqs.AmazonSQS;\n" +
4140
"import com.amazonaws.services.sqs.AmazonSQSClient;\n" +
41+
"import com.amazonaws.services.sqs.model.InvalidAttributeNameException;\n" +
42+
"import com.amazonaws.services.sqs.model.AmazonSQSException;\n" +
4243
"import com.amazonaws.services.sqs.model.ListQueuesResult;\n" +
4344
"import com.amazonaws.services.sqs.model.ListQueuesRequest;\n" +
4445
"class Test {\n" +
4546
" static void method() {\n" +
4647
" AmazonSQS sqs = null;\n" +
4748
" ListQueuesRequest request = null;\n" +
4849
" ListQueuesResult result = null;\n" +
50+
" InvalidAttributeNameException exception = null;\n" +
51+
" AmazonSQSException baseException = null;\n" +
4952
" }\n" +
5053
"}\n",
51-
"import software.amazon.awssdk.services.sqs.SqsClient;\n" +
52-
"import software.amazon.awssdk.services.sqs.model.ListQueuesRequest;\n" +
54+
"import software.amazon.awssdk.services.sqs.SqsClient;\n"
5355
// TODO: duplicate import for some reason, fix this
54-
"import software.amazon.awssdk.services.sqs.SqsClient;\n" +
55-
"import software.amazon.awssdk.services.sqs.model.ListQueuesResponse;\n" +
56-
"\n" +
57-
"class Test {\n" +
58-
" static void method() {\n" +
59-
" SqsClient sqs = null;\n" +
60-
" ListQueuesRequest request = null;\n" +
61-
" ListQueuesResponse result = null;\n" +
62-
" }\n" +
63-
"}\n"
56+
+ "import software.amazon.awssdk.services.sqs.SqsClient;\n"
57+
+ "import software.amazon.awssdk.services.sqs.model.InvalidAttributeNameException;\n"
58+
+ "import software.amazon.awssdk.services.sqs.model.ListQueuesRequest;\n"
59+
+ "import software.amazon.awssdk.services.sqs.model.SqsException;\n"
60+
+ "import software.amazon.awssdk.services.sqs.model.ListQueuesResponse;\n"
61+
+ "\n"
62+
+ "class Test {\n"
63+
+ " static void method() {\n"
64+
+ " SqsClient sqs = null;\n"
65+
+ " ListQueuesRequest request = null;\n"
66+
+ " ListQueuesResponse result = null;\n"
67+
+ " InvalidAttributeNameException exception = null;\n"
68+
+ " SqsException baseException = null;\n"
69+
+ " }\n"
70+
+ "}"
6471
)
6572
);
6673
}
@@ -69,7 +76,6 @@ void shouldChangeVariables() {
6976
@EnabledOnJre({JRE.JAVA_8})
7077
void shouldChangeFields() {
7178
rewriteRun(
72-
spec -> spec.parser(Java8Parser.builder().classpath("aws-java-sdk-sqs")),
7379
java(
7480
"import com.amazonaws.services.sqs.model.DeleteQueueRequest;\n" +
7581
"import com.amazonaws.services.sqs.model.DeleteQueueResult;\n" +
@@ -92,7 +98,6 @@ void shouldChangeFields() {
9298
@EnabledOnJre({JRE.JAVA_8})
9399
void shouldChangeFieldsInAList() {
94100
rewriteRun(
95-
spec -> spec.parser(Java8Parser.builder().classpath("aws-java-sdk-sqs")),
96101
java(
97102
"import com.amazonaws.services.sqs.model.DeleteQueueResult;\n" +
98103
"import java.util.List;\n" +
@@ -113,7 +118,6 @@ void shouldChangeFieldsInAList() {
113118
@EnabledOnJre({JRE.JAVA_8})
114119
void shouldChangeMethodParameters() {
115120
rewriteRun(
116-
spec -> spec.parser(Java8Parser.builder().classpath("aws-java-sdk-sqs")),
117121
java(
118122
"import com.amazonaws.services.sqs.model.CreateQueueRequest;\n" +
119123
"class Test {\n" +
@@ -134,7 +138,6 @@ void shouldChangeMethodParameters() {
134138
@EnabledOnJre({JRE.JAVA_8})
135139
void shouldNotChangeExistingV2Types() {
136140
rewriteRun(
137-
spec -> spec.parser(Java8Parser.builder().classpath("aws-java-sdk-sqs", "sqs")),
138141
java(
139142
"import com.amazonaws.services.sqs.model.CreateQueueRequest;\n" +
140143
"import software.amazon.awssdk.services.sqs.model.DeleteQueueRequest;\n" +
@@ -161,7 +164,6 @@ void shouldNotChangeExistingV2Types() {
161164
@EnabledOnJre({JRE.JAVA_8})
162165
void shouldChangeFieldsInInnerClass() {
163166
rewriteRun(
164-
spec -> spec.parser(Java8Parser.builder().classpath("aws-java-sdk-sqs")),
165167
java(
166168
"import com.amazonaws.services.sqs.model.CreateQueueResult;\n" +
167169
"class Test {\n" +

0 commit comments

Comments
 (0)