Skip to content

S3 PutObject String overload #5429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,11 @@ private static PutObjectResponse uploadFile(S3Client s3, String bucket, String k

return result;
}

private static PutObjectResponse uploadString(S3Client s3, String bucket, String key, String content) {
PutObjectResponse result = s3.putObject(PutObjectRequest.builder().bucket(bucket).key(key)
.build(), RequestBody.fromString(content));

return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,10 @@ private static PutObjectResult uploadFile(AmazonS3 s3, String bucket, String key

return result;
}

private static PutObjectResult uploadString(AmazonS3 s3, String bucket, String key, String content) {
PutObjectResult result = s3.putObject(bucket, key, content);

return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,13 @@

@SdkInternalApi
public class S3StreamingRequestToV2 extends Recipe {
private static final MethodMatcher PUT_OBJECT =
private static final MethodMatcher PUT_OBJECT_FILE =
new MethodMatcher("com.amazonaws.services.s3.AmazonS3 "
+ "putObject(java.lang.String, java.lang.String, java.io.File)",
true);
+ "putObject(java.lang.String, java.lang.String, java.io.File)", true);
private static final MethodMatcher PUT_OBJECT_STRING =
new MethodMatcher("com.amazonaws.services.s3.AmazonS3 "
+ "putObject(java.lang.String, java.lang.String, java.lang.String)", true);

private static final JavaType.FullyQualified V1_PUT_OBJECT_REQUEST =
TypeUtils.asFullyQualified(JavaType.buildType("com.amazonaws.services.s3.model.PutObjectRequest"));
private static final JavaType.FullyQualified REQUEST_BODY =
Expand All @@ -66,12 +69,79 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
private static final class Visitor extends JavaIsoVisitor<ExecutionContext> {
@Override
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext executionContext) {
if (PUT_OBJECT.matches(method, false)) {
if (PUT_OBJECT_FILE.matches(method, false)) {
method = transformPutFileOverload(method);
}
if (PUT_OBJECT_STRING.matches(method, false)) {
method = transformPutStringOverload(method);
}
return super.visitMethodInvocation(method, executionContext);
}

private J.MethodInvocation transformPutStringOverload(J.MethodInvocation method) {
JavaType.Method methodType = method.getMethodType();
if (methodType == null) {
return method;
}

List<Expression> originalArgs = method.getArguments();

Expression bucketExpr = originalArgs.get(0);
Expression keyExpr = originalArgs.get(1);
Expression stringExpr = originalArgs.get(2);

List<Expression> newArgs = new ArrayList<>();
Expression getObjectExpr = bucketAndKeyToPutObject(bucketExpr, keyExpr);
newArgs.add(getObjectExpr);

// This is to maintain the formatting/spacing of original code, getPrefix() retrieves the leading whitespace
Space stringArgPrefix = stringExpr.getPrefix();
stringExpr = stringToRequestBody(stringExpr.withPrefix(Space.EMPTY)).withPrefix(stringArgPrefix);
newArgs.add(stringExpr);

List<String> paramNames = Arrays.asList("request", "stringContent");
List<JavaType> paramTypes = newArgs.stream()
.map(Expression::getType)
.collect(Collectors.toList());


methodType = methodType.withParameterTypes(paramTypes)
.withParameterNames(paramNames);

return method.withMethodType(methodType).withArguments(newArgs);
}

private J.MethodInvocation stringToRequestBody(Expression fileExpr) {
maybeAddImport(REQUEST_BODY);

J.Identifier requestBodyId = IdentifierUtils.makeId(REQUEST_BODY.getClassName(), REQUEST_BODY);

JavaType.Method fromStringType = new JavaType.Method(
null,
0L,
REQUEST_BODY,
"fromString",
REQUEST_BODY,
Collections.singletonList("stringContent"),
Collections.singletonList(JavaType.buildType("java.lang.String")),
null,
null
);

J.Identifier fromFileId = IdentifierUtils.makeId("fromString", fromStringType);

return new J.MethodInvocation(
Tree.randomId(),
Space.EMPTY,
Markers.EMPTY,
JRightPadded.build(requestBodyId),
null,
fromFileId,
JContainer.build(Collections.singletonList(JRightPadded.build(fileExpr))),
fromStringType
);
}

private J.MethodInvocation transformPutFileOverload(J.MethodInvocation method) {
JavaType.Method methodType = method.getMethodType();
if (methodType == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public void defaults(RecipeSpec spec) {

@Test
@EnabledOnJre({JRE.JAVA_8})
public void testS3PutObjectOverrideRewrite() {
public void testS3PutObjectOverrideRewrite_file() {
rewriteRun(
java(
"import com.amazonaws.services.s3.AmazonS3Client;\n"
Expand Down Expand Up @@ -78,4 +78,45 @@ public void testS3PutObjectOverrideRewrite() {
)
);
}

@Test
@EnabledOnJre({JRE.JAVA_8})
public void testS3PutObjectOverrideRewrite_string() {
rewriteRun(
java(
"import com.amazonaws.services.s3.AmazonS3Client;\n"
+ "\n"
+ "import java.io.File;\n"
+ "\n"
+ "public class S3PutObjectExample {\n"
+ " private static final String BUCKET = \"my-bucket\";\n"
+ " private static final String KEY = \"key\";\n"
+ " private static final String CONTENT = \"payload\";\n"
+ "\n"
+ " public static void main(String[] args) {\n"
+ " AmazonS3Client s3 = null;\n"
+ "\n"
+ " s3.putObject(BUCKET, KEY, CONTENT);\n"
+ " }\n"
+ "}\n",
"import com.amazonaws.services.s3.AmazonS3Client;\n"
+ "import com.amazonaws.services.s3.model.PutObjectRequest;\n"
+ "import software.amazon.awssdk.core.sync.RequestBody;\n"
+ "\n"
+ "import java.io.File;\n"
+ "\n"
+ "public class S3PutObjectExample {\n"
+ " private static final String BUCKET = \"my-bucket\";\n"
+ " private static final String KEY = \"key\";\n"
+ " private static final String CONTENT = \"payload\";\n"
+ "\n"
+ " public static void main(String[] args) {\n"
+ " AmazonS3Client s3 = null;\n"
+ "\n"
+ " s3.putObject(new PutObjectRequest(BUCKET, KEY), RequestBody.fromString(CONTENT));\n"
+ " }\n"
+ "}"
)
);
}
}
Loading