Skip to content

Commit 1eaf187

Browse files
authored
S3 CreateBucket DeleteBucket single arg overloads (#5438)
* S3 CreateBucket DeleteBucket single arg overload * Address comments
1 parent 672d973 commit 1eaf187

File tree

8 files changed

+283
-37
lines changed

8 files changed

+283
-37
lines changed

test/v2-migration-tests/src/test/resources/maven/after/src/main/java/foo/bar/Application.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
package foo.bar;
1717

1818
import software.amazon.awssdk.services.s3.S3Client;
19+
import software.amazon.awssdk.services.s3.model.CreateBucketRequest;
20+
import software.amazon.awssdk.services.s3.model.DeleteBucketRequest;
1921
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
2022
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
2123
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
@@ -107,4 +109,14 @@ private static PutObjectResponse uploadString(S3Client s3, String bucket, String
107109

108110
return result;
109111
}
112+
113+
private static void createBucket(S3Client s3, String bucket) {
114+
s3.createBucket(CreateBucketRequest.builder().bucket(bucket)
115+
.build());
116+
}
117+
118+
private static void deleteBucket(S3Client s3, String bucket) {
119+
s3.deleteBucket(DeleteBucketRequest.builder().bucket(bucket)
120+
.build());
121+
}
110122
}

test/v2-migration-tests/src/test/resources/maven/before/src/main/java/foo/bar/Application.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@
2323
import com.amazonaws.services.s3.model.PutObjectResult;
2424
import com.amazonaws.services.s3.model.S3Object;
2525
import com.amazonaws.services.sqs.AmazonSQS;
26+
import com.amazonaws.services.sqs.model.QueueDoesNotExistException;
2627
import com.amazonaws.services.sqs.model.AmazonSQSException;
2728
import com.amazonaws.services.sqs.model.ListQueuesRequest;
2829
import com.amazonaws.services.sqs.model.ListQueuesResult;
2930

30-
import com.amazonaws.services.sqs.model.QueueDoesNotExistException;
3131
import java.io.IOException;
3232
import java.io.InputStream;
3333
import java.nio.file.Files;
@@ -100,4 +100,12 @@ private static PutObjectResult uploadString(AmazonS3 s3, String bucket, String k
100100

101101
return result;
102102
}
103+
104+
private static void createBucket(AmazonS3 s3, String bucket) {
105+
s3.createBucket(bucket);
106+
}
107+
108+
private static void deleteBucket(AmazonS3 s3, String bucket) {
109+
s3.deleteBucket(bucket);
110+
}
103111
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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.v2migration;
17+
18+
import java.util.ArrayList;
19+
import java.util.Collections;
20+
import java.util.List;
21+
import java.util.stream.Collectors;
22+
import org.openrewrite.ExecutionContext;
23+
import org.openrewrite.Recipe;
24+
import org.openrewrite.Tree;
25+
import org.openrewrite.TreeVisitor;
26+
import org.openrewrite.java.JavaIsoVisitor;
27+
import org.openrewrite.java.MethodMatcher;
28+
import org.openrewrite.java.tree.Expression;
29+
import org.openrewrite.java.tree.J;
30+
import org.openrewrite.java.tree.JContainer;
31+
import org.openrewrite.java.tree.JRightPadded;
32+
import org.openrewrite.java.tree.JavaType;
33+
import org.openrewrite.java.tree.Space;
34+
import org.openrewrite.java.tree.TypeUtils;
35+
import org.openrewrite.marker.Markers;
36+
import software.amazon.awssdk.annotations.SdkInternalApi;
37+
import software.amazon.awssdk.v2migration.internal.utils.IdentifierUtils;
38+
39+
@SdkInternalApi
40+
public class S3NonStreamingRequestToV2 extends Recipe {
41+
private static final MethodMatcher CREATE_BUCKET =
42+
new MethodMatcher("com.amazonaws.services.s3.AmazonS3 createBucket(java.lang.String)", true);
43+
private static final MethodMatcher DELETE_BUCKET =
44+
new MethodMatcher("com.amazonaws.services.s3.AmazonS3 deleteBucket(java.lang.String)", true);
45+
private static final JavaType.FullyQualified V1_CREATE_BUCKET_REQUEST =
46+
TypeUtils.asFullyQualified(JavaType.buildType("com.amazonaws.services.s3.model.CreateBucketRequest"));
47+
private static final JavaType.FullyQualified V1_DELETE_BUCKET_REQUEST =
48+
TypeUtils.asFullyQualified(JavaType.buildType("com.amazonaws.services.s3.model.DeleteBucketRequest"));
49+
50+
@Override
51+
public String getDisplayName() {
52+
return "V1 S3 non-streaming requests to V2";
53+
}
54+
55+
@Override
56+
public String getDescription() {
57+
return "Transform usage of V1 S3 non-streaming requests such as CreateBucket and DeleteBucket to V2.";
58+
}
59+
60+
@Override
61+
public TreeVisitor<?, ExecutionContext> getVisitor() {
62+
return new Visitor();
63+
}
64+
65+
private static final class Visitor extends JavaIsoVisitor<ExecutionContext> {
66+
@Override
67+
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext executionContext) {
68+
if (CREATE_BUCKET.matches(method, false)) {
69+
method = transformBucketNameArgOverload(method, V1_CREATE_BUCKET_REQUEST);
70+
} else if (DELETE_BUCKET.matches(method, false)) {
71+
method = transformBucketNameArgOverload(method, V1_DELETE_BUCKET_REQUEST);
72+
}
73+
return super.visitMethodInvocation(method, executionContext);
74+
}
75+
76+
private J.MethodInvocation transformBucketNameArgOverload(J.MethodInvocation method, JavaType.FullyQualified fqcn) {
77+
JavaType.Method methodType = method.getMethodType();
78+
if (methodType == null) {
79+
return method;
80+
}
81+
82+
Expression bucketExpr = method.getArguments().get(0);
83+
List<Expression> newArgs = new ArrayList<>();
84+
Expression getObjectExpr = bucketToPojo(bucketExpr, fqcn);
85+
newArgs.add(getObjectExpr);
86+
87+
List<String> paramNames = Collections.singletonList("request");
88+
List<JavaType> paramTypes = newArgs.stream()
89+
.map(Expression::getType)
90+
.collect(Collectors.toList());
91+
92+
methodType = methodType.withParameterTypes(paramTypes)
93+
.withParameterNames(paramNames);
94+
95+
return method.withMethodType(methodType).withArguments(newArgs);
96+
}
97+
98+
private Expression bucketToPojo(Expression bucketExpr, JavaType.FullyQualified fqcn) {
99+
maybeAddImport(fqcn);
100+
101+
J.Identifier putObjRequestId = IdentifierUtils.makeId(fqcn.getClassName(), fqcn);
102+
103+
JavaType.Method ctorType = new JavaType.Method(
104+
null,
105+
0L,
106+
fqcn,
107+
"<init>",
108+
fqcn,
109+
Collections.singletonList("bucket"),
110+
Collections.singletonList(bucketExpr.getType()),
111+
null,
112+
null
113+
);
114+
115+
return new J.NewClass(
116+
Tree.randomId(),
117+
Space.EMPTY,
118+
Markers.EMPTY,
119+
null,
120+
Space.EMPTY,
121+
putObjRequestId.withPrefix(Space.SINGLE_SPACE),
122+
JContainer.build(Collections.singletonList(JRightPadded.build(bucketExpr))),
123+
null,
124+
ctorType
125+
);
126+
}
127+
}
128+
}

v2-migration/src/main/java/software/amazon/awssdk/v2migration/S3StreamingRequestToV2.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ public class S3StreamingRequestToV2 extends Recipe {
5353

5454
@Override
5555
public String getDisplayName() {
56-
return "S3StreamingRequestToV2";
56+
return "V1 S3 streaming requests to V2";
5757
}
5858

5959
@Override
6060
public String getDescription() {
61-
return "S3StreamingRequestToV2.";
61+
return "Transform usage of V1 S3 streaming requests such as PutObject to V2.";
6262
}
6363

6464
@Override
@@ -71,8 +71,7 @@ private static final class Visitor extends JavaIsoVisitor<ExecutionContext> {
7171
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext executionContext) {
7272
if (PUT_OBJECT_FILE.matches(method, false)) {
7373
method = transformPutFileOverload(method);
74-
}
75-
if (PUT_OBJECT_STRING.matches(method, false)) {
74+
} else if (PUT_OBJECT_STRING.matches(method, false)) {
7675
method = transformPutStringOverload(method);
7776
}
7877
return super.visitMethodInvocation(method, executionContext);

v2-migration/src/main/resources/META-INF/rewrite/aws-sdk-java-v1-to-v2.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ recipeList:
2424
- software.amazon.awssdk.v2migration.UpgradeSdkDependencies
2525
- software.amazon.awssdk.v2migration.S3StreamingResponseToV2
2626
- software.amazon.awssdk.v2migration.S3StreamingRequestToV2
27-
- software.amazon.awssdk.v2migration.S3GetObjectConstructorToFluent
28-
- software.amazon.awssdk.v2migration.S3PutObjectConstructorToFluent
27+
- software.amazon.awssdk.v2migration.S3NonStreamingRequestToV2
28+
- software.amazon.awssdk.v2migration.S3MethodsConstructorToFluent
2929
- software.amazon.awssdk.v2migration.EnumGettersToV2
3030
- software.amazon.awssdk.v2migration.ChangeSdkType
3131
- software.amazon.awssdk.v2migration.ChangeSdkCoreTypes

v2-migration/src/main/resources/META-INF/rewrite/s3-getobject-constructor-to-fluent.yml renamed to v2-migration/src/main/resources/META-INF/rewrite/s3-methods-constructor-to-fluent.yml

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
#
1515
---
1616
type: specs.openrewrite.org/v1beta/recipe
17-
name: software.amazon.awssdk.v2migration.S3GetObjectConstructorToFluent
18-
displayName: Change GetObject constructors to fluent builder calls
17+
name: software.amazon.awssdk.v2migration.S3MethodsConstructorToFluent
18+
displayName: Change S3 method constructors to fluent builder calls
1919
recipeList:
2020
- software.amazon.awssdk.v2migration.ConstructorToFluent:
2121
clzzFqcn: com.amazonaws.services.s3.model.GetObjectRequest
@@ -24,4 +24,24 @@ recipeList:
2424
- java.lang.String
2525
fluentNames:
2626
- withBucket
27-
- withKey
27+
- withKey
28+
- software.amazon.awssdk.v2migration.ConstructorToFluent:
29+
clzzFqcn: com.amazonaws.services.s3.model.PutObjectRequest
30+
parameterTypes:
31+
- java.lang.String
32+
- java.lang.String
33+
fluentNames:
34+
- withBucket
35+
- withKey
36+
- software.amazon.awssdk.v2migration.ConstructorToFluent:
37+
clzzFqcn: com.amazonaws.services.s3.model.CreateBucketRequest
38+
parameterTypes:
39+
- java.lang.String
40+
fluentNames:
41+
- withBucket
42+
- software.amazon.awssdk.v2migration.ConstructorToFluent:
43+
clzzFqcn: com.amazonaws.services.s3.model.DeleteBucketRequest
44+
parameterTypes:
45+
- java.lang.String
46+
fluentNames:
47+
- withBucket

v2-migration/src/main/resources/META-INF/rewrite/s3-putobject-constructor-to-fluent.yml

Lines changed: 0 additions & 27 deletions
This file was deleted.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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.v2migration;
17+
18+
import static org.openrewrite.java.Assertions.java;
19+
20+
import org.junit.jupiter.api.Test;
21+
import org.junit.jupiter.api.condition.EnabledOnJre;
22+
import org.junit.jupiter.api.condition.JRE;
23+
import org.openrewrite.java.Java8Parser;
24+
import org.openrewrite.test.RecipeSpec;
25+
import org.openrewrite.test.RewriteTest;
26+
27+
public class S3NonStreamingRequestToV2Test implements RewriteTest {
28+
@Override
29+
public void defaults(RecipeSpec spec) {
30+
spec.recipe(new S3NonStreamingRequestToV2());
31+
spec.parser(Java8Parser.builder().classpath(
32+
"aws-java-sdk-s3",
33+
"aws-java-sdk-core",
34+
"s3",
35+
"sdk-core",
36+
"aws-core"));
37+
}
38+
39+
@Test
40+
@EnabledOnJre({JRE.JAVA_8})
41+
public void testS3CreateBucketOverrideRewrite() {
42+
rewriteRun(
43+
java(
44+
"import com.amazonaws.services.s3.AmazonS3Client;\n"
45+
+ "\n"
46+
+ "public class S3PutObjectExample {\n"
47+
+ " private static final String BUCKET = \"my-bucket\";\n"
48+
+ " private static final String KEY = \"key\";\n"
49+
+ "\n"
50+
+ " public static void main(String[] args) {\n"
51+
+ " AmazonS3Client s3 = null;\n"
52+
+ "\n"
53+
+ " s3.createBucket(\"bucketName\");\n"
54+
+ " }\n"
55+
+ "}\n",
56+
"import com.amazonaws.services.s3.AmazonS3Client;\n"
57+
+ "import com.amazonaws.services.s3.model.CreateBucketRequest;\n"
58+
+ "\n"
59+
+ "public class S3PutObjectExample {\n"
60+
+ " private static final String BUCKET = \"my-bucket\";\n"
61+
+ " private static final String KEY = \"key\";\n"
62+
+ "\n"
63+
+ " public static void main(String[] args) {\n"
64+
+ " AmazonS3Client s3 = null;\n"
65+
+ "\n"
66+
+ " s3.createBucket(new CreateBucketRequest(\"bucketName\"));\n"
67+
+ " }\n"
68+
+ "}"
69+
)
70+
);
71+
}
72+
73+
@Test
74+
@EnabledOnJre({JRE.JAVA_8})
75+
public void testS3DeleteBucketOverrideRewrite() {
76+
rewriteRun(
77+
java(
78+
"import com.amazonaws.services.s3.AmazonS3Client;\n"
79+
+ "\n"
80+
+ "public class S3PutObjectExample {\n"
81+
+ " private static final String BUCKET = \"my-bucket\";\n"
82+
+ " private static final String KEY = \"key\";\n"
83+
+ "\n"
84+
+ " public static void main(String[] args) {\n"
85+
+ " AmazonS3Client s3 = null;\n"
86+
+ "\n"
87+
+ " s3.deleteBucket(\"bucketName\");\n"
88+
+ " }\n"
89+
+ "}\n",
90+
"import com.amazonaws.services.s3.AmazonS3Client;\n"
91+
+ "import com.amazonaws.services.s3.model.DeleteBucketRequest;\n"
92+
+ "\n"
93+
+ "public class S3PutObjectExample {\n"
94+
+ " private static final String BUCKET = \"my-bucket\";\n"
95+
+ " private static final String KEY = \"key\";\n"
96+
+ "\n"
97+
+ " public static void main(String[] args) {\n"
98+
+ " AmazonS3Client s3 = null;\n"
99+
+ "\n"
100+
+ " s3.deleteBucket(new DeleteBucketRequest(\"bucketName\"));\n"
101+
+ " }\n"
102+
+ "}"
103+
)
104+
);
105+
}
106+
}

0 commit comments

Comments
 (0)