Skip to content
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 @@ -15,14 +15,18 @@

package foo.bar;

import com.amazonaws.HttpMethod;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import software.amazon.awssdk.core.async.AsyncRequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GeneratePresignedUrlRequest;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.UploadRequest;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

public class S3Transforms {

void upload(S3TransferManager tm, String bucket, String key) {
Expand All @@ -31,4 +35,19 @@ void upload(S3TransferManager tm, String bucket, String key) {
.build();
/*AWS SDK for Java v2 migration: When using InputStream to upload with TransferManager, you must specify Content-Length and ExecutorService.*/tm.upload(UploadRequest.builder().putObjectRequest(requestWithInputStream).requestBody(AsyncRequestBody.fromInputStream(inputStream, -1L, newExecutorServiceVariableToDefine)).build());
}

private void generatePresignedUrl(S3Client s3, String bucket, String key, Date expiration) {
URL urlHead = /*AWS SDK for Java v2 migration: S3 generatePresignedUrl() with HEAD HTTP method is not supported in v2. Only GET, PUT, and DELETE are supported - https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/presigner/S3Presigner.html*/s3.generatePresignedUrl(bucket, key, expiration, HttpMethod.HEAD);

URL urlPatch = /*AWS SDK for Java v2 migration: S3 generatePresignedUrl() with PATCH HTTP method is not supported in v2. Only GET, PUT, and DELETE are supported - https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/presigner/S3Presigner.html*/s3.generatePresignedUrl(bucket, key, expiration, HttpMethod.PATCH);

URL urlPost = /*AWS SDK for Java v2 migration: S3 generatePresignedUrl() with POST HTTP method is not supported in v2. Only GET, PUT, and DELETE are supported - https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/presigner/S3Presigner.html*/s3.generatePresignedUrl(bucket, key, expiration, HttpMethod.POST);


HttpMethod httpMethod = HttpMethod.PUT;
URL urlWithHttpMethodVariable = /*AWS SDK for Java v2 migration: Transform for S3 generatePresignedUrl() with an assigned variable for HttpMethod is not supported. Please manually migrate your code - https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/presigner/S3Presigner.html*/s3.generatePresignedUrl(bucket, key, expiration, httpMethod);

GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucket, key);
/*AWS SDK for Java v2 migration: Transforms are not supported for GeneratePresignedUrlRequest, please manually migrate your code - https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/presigner/S3Presigner.html*/s3.generatePresignedUrl(request);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,15 @@

package foo.bar;

import com.amazonaws.HttpMethod;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.transfer.TransferManager;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;

public class S3Transforms {

Expand All @@ -28,4 +33,19 @@ void upload(TransferManager tm, String bucket, String key) {
requestWithInputStream.setInputStream(inputStream);
tm.upload(requestWithInputStream);
}

private void generatePresignedUrl(AmazonS3 s3, String bucket, String key, Date expiration) {
URL urlHead = s3.generatePresignedUrl(bucket, key, expiration, HttpMethod.HEAD);

URL urlPatch = s3.generatePresignedUrl(bucket, key, expiration, HttpMethod.PATCH);

URL urlPost = s3.generatePresignedUrl(bucket, key, expiration, HttpMethod.POST);


HttpMethod httpMethod = HttpMethod.PUT;
URL urlWithHttpMethodVariable = s3.generatePresignedUrl(bucket, key, expiration, httpMethod);

GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucket, key);
s3.generatePresignedUrl(request);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
package foo.bar;

import java.net.URI;
import java.net.URL;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
Expand Down Expand Up @@ -110,6 +114,7 @@
import software.amazon.awssdk.services.s3.model.UploadPartCopyRequest;
import software.amazon.awssdk.services.s3.model.UploadPartCopyResponse;
import software.amazon.awssdk.services.s3.model.WebsiteConfiguration;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;

public class S3 {

Expand Down Expand Up @@ -402,4 +407,26 @@ private void s3Uri(URI uri, String uriAsString) {

S3Uri s3UriFromStringWithUrlEncodeFalse = S3Utilities.builder().build().parseUri(URI.create(uriAsString));
}

private void generatePresignedUrl(S3Client s3, String bucket, String key, Date expiration) {
URL urlGet1 = /*AWS SDK for Java v2 migration: If generating multiple pre-signed URLs, it is recommended to create a single instance of S3Presigner, since creating a presigner can be expensive. If applicable, please manually refactor the transformed code.*/S3Presigner.builder().s3Client(s3).build()
.presignGetObject(p -> p.getObjectRequest(r -> r.bucket(bucket).key(key))
.signatureDuration(Duration.between(Instant.now(), expiration.toInstant())))
.url();

URL urlPut = /*AWS SDK for Java v2 migration: If generating multiple pre-signed URLs, it is recommended to create a single instance of S3Presigner, since creating a presigner can be expensive. If applicable, please manually refactor the transformed code.*/S3Presigner.builder().s3Client(s3).build()
.presignPutObject(p -> p.putObjectRequest(r -> r.bucket(bucket).key(key))
.signatureDuration(Duration.between(Instant.now(), expiration.toInstant())))
.url();

URL urlGet2 = /*AWS SDK for Java v2 migration: If generating multiple pre-signed URLs, it is recommended to create a single instance of S3Presigner, since creating a presigner can be expensive. If applicable, please manually refactor the transformed code.*/S3Presigner.builder().s3Client(s3).build()
.presignGetObject(p -> p.getObjectRequest(r -> r.bucket(bucket).key(key))
.signatureDuration(Duration.between(Instant.now(), expiration.toInstant())))
.url();

URL urlDelete = /*AWS SDK for Java v2 migration: If generating multiple pre-signed URLs, it is recommended to create a single instance of S3Presigner, since creating a presigner can be expensive. If applicable, please manually refactor the transformed code.*/S3Presigner.builder().s3Client(s3).build()
.presignDeleteObject(p -> p.deleteObjectRequest(r -> r.bucket(bucket).key(key))
.signatureDuration(Duration.between(Instant.now(), expiration.toInstant())))
.url();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package foo.bar;

import com.amazonaws.HttpMethod;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3URI;
import com.amazonaws.services.s3.model.AbortMultipartUploadRequest;
Expand Down Expand Up @@ -59,7 +60,9 @@
import com.amazonaws.services.s3.model.metrics.MetricsConfiguration;
import com.amazonaws.services.s3.model.ownership.OwnershipControls;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class S3 {
Expand Down Expand Up @@ -259,4 +262,14 @@ private void s3Uri(URI uri, String uriAsString) {

AmazonS3URI s3UriFromStringWithUrlEncodeFalse = new AmazonS3URI(uriAsString, false);
}

private void generatePresignedUrl(AmazonS3 s3, String bucket, String key, Date expiration) {
URL urlGet1 = s3.generatePresignedUrl(bucket, key, expiration);

URL urlPut = s3.generatePresignedUrl(bucket, key, expiration, HttpMethod.PUT);

URL urlGet2 = s3.generatePresignedUrl(bucket, key, expiration, HttpMethod.GET);

URL urlDelete = s3.generatePresignedUrl(bucket, key, expiration, HttpMethod.DELETE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,28 @@
package software.amazon.awssdk.v2migration;

import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.V2_S3_MODEL_PKG;
import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.V2_S3_PKG;
import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.assignedVariableHttpMethodNotSupportedComment;
import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.httpMethodNotSupportedComment;
import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.isCompleteMpuRequestMultipartUploadSetter;
import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.isGeneratePresignedUrl;
import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.isUnsupportedHttpMethod;
import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.presignerSingleInstanceSuggestion;
import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.requestPojoTransformNotSupportedComment;
import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.v2S3MethodMatcher;
import static software.amazon.awssdk.v2migration.internal.utils.SdkTypeUtils.fullyQualified;

import java.util.List;
import java.util.Locale;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.java.AddImport;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.JavaTemplate;
import org.openrewrite.java.MethodMatcher;
import org.openrewrite.java.RemoveImport;
import org.openrewrite.java.tree.Expression;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JavaType;
import org.openrewrite.java.tree.TypeUtils;
import software.amazon.awssdk.annotations.SdkInternalApi;

/**
Expand Down Expand Up @@ -74,58 +83,100 @@ private static final class Visitor extends JavaIsoVisitor<ExecutionContext> {
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext executionContext) {

if (isCompleteMpuRequestMultipartUploadSetter(method)) {
method = transformCompleteMpuRequestCompletedPartsArg(method);
return super.visitMethodInvocation(method, executionContext);
return transformCompleteMpuRequestCompletedPartsArg(method);
}
if (isGeneratePresignedUrl(method)) {
return maybeAutoFormat(method, transformGeneratePresignedUrl(method), executionContext);
}

if (DISABLE_REQUESTER_PAYS.matches(method, false)) {
method = transformSetRequesterPays(method, false);
return super.visitMethodInvocation(method, executionContext);
return transformSetRequesterPays(method, false);
}
if (ENABLE_REQUESTER_PAYS.matches(method, false)) {
method = transformSetRequesterPays(method, true);
return super.visitMethodInvocation(method, executionContext);
return transformSetRequesterPays(method, true);
}
if (IS_REQUESTER_PAYS_ENABLED.matches(method, false)) {
method = transformIsRequesterPays(method);
return super.visitMethodInvocation(method, executionContext);
return transformIsRequesterPays(method);
}
if (GET_OBJECT_AS_STRING.matches(method, false)) {
method = transformGetObjectAsString(method);
return super.visitMethodInvocation(method, executionContext);
return transformGetObjectAsString(method);
}
if (GET_URL.matches(method, false)) {
method = transformGetUrl(method);
return super.visitMethodInvocation(method, executionContext);
return transformGetUrl(method);
}
if (LIST_BUCKETS.matches(method, false)) {
method = transformListBuckets(method);
return super.visitMethodInvocation(method, executionContext);
return transformListBuckets(method);
}
if (RESTORE_OBJECT.matches(method, false)) {
method = transformRestoreObject(method);
return super.visitMethodInvocation(method, executionContext);
return transformRestoreObject(method);
}
if (SET_OBJECT_REDIRECT_LOCATION.matches(method, false)) {
method = transformSetObjectRedirectLocation(method);
return super.visitMethodInvocation(method, executionContext);
return transformSetObjectRedirectLocation(method);
}
if (CHANGE_OBJECT_STORAGE_CLASS.matches(method, false)) {
method = transformChangeObjectStorageClass(method);
return super.visitMethodInvocation(method, executionContext);
return transformChangeObjectStorageClass(method);
}
if (CREATE_BUCKET.matches(method, false)) {
method = transformCreateBucket(method);
return super.visitMethodInvocation(method, executionContext);
return transformCreateBucket(method);
}
return super.visitMethodInvocation(method, executionContext);
}

private boolean isCompleteMpuRequestMultipartUploadSetter(J.MethodInvocation method) {
JavaType.FullyQualified completeMpuRequest =
fullyQualified("software.amazon.awssdk.services.s3.model.CompleteMultipartUploadRequest.Builder");
return "multipartUpload".equals(method.getSimpleName()) &&
TypeUtils.isAssignableTo(completeMpuRequest, method.getSelect().getType());
private J.MethodInvocation transformGeneratePresignedUrl(J.MethodInvocation method) {
List<Expression> args = method.getArguments();
if (args.size() == 1) {
return method.withComments(requestPojoTransformNotSupportedComment());
}

String httpMethod = determineHttpMethod(args);

if (isUnsupportedHttpMethod(httpMethod)) {
return method.withComments(httpMethodNotSupportedComment(httpMethod));
}
if (httpMethod == null) {
return method.withComments(assignedVariableHttpMethodNotSupportedComment());
}

String v2Method = String.format("S3Presigner.builder().s3Client(#{any()}).build()%n"
+ ".presign%sObject(p -> p.%sObjectRequest(r -> r.bucket(#{any()}).key(#{any()}))%n"
+ ".signatureDuration(Duration.between(Instant.now(), #{any()}.toInstant())))%n"
+ ".url()",
httpMethod, httpMethod.toLowerCase(Locale.ROOT));

removeV1HttpMethodImport();
addInstantImport();
addDurationImport();
addS3PresignerImport();

return JavaTemplate.builder(v2Method).build()
.apply(getCursor(), method.getCoordinates().replace(), method.getSelect(),
args.get(0), args.get(1), args.get(2))
.withComments(presignerSingleInstanceSuggestion());
}

private String determineHttpMethod(List<Expression> args) {
if (args.size() == 3) {
return "Get";
}
Expression argVal = args.get(3);
String httpMethod = argVal.printTrimmed(getCursor());

switch (httpMethod) {
case "HttpMethod.GET":
return "Get";
case "HttpMethod.PUT":
return "Put";
case "HttpMethod.DELETE":
return "Delete";
case "HttpMethod.HEAD":
return "Head";
case "HttpMethod.POST":
return "Post";
case "HttpMethod.PATCH":
return "Patch";
default:
// enum value assigned to variable
return null;
}
}

private J.MethodInvocation transformCompleteMpuRequestCompletedPartsArg(J.MethodInvocation method) {
Expand Down Expand Up @@ -251,6 +302,25 @@ private J.MethodInvocation transformSetRequesterPays(J.MethodInvocation method,
return method;
}

private void removeV1HttpMethodImport() {
doAfterVisit(new RemoveImport<>("com.amazonaws.HttpMethod", true));
}

private void addInstantImport() {
String fqcn = "java.time.Instant";
doAfterVisit(new AddImport<>(fqcn, null, false));
}

private void addDurationImport() {
String fqcn = "java.time.Duration";
doAfterVisit(new AddImport<>(fqcn, null, false));
}

private void addS3PresignerImport() {
String fqcn = V2_S3_PKG + "presigner.S3Presigner";
doAfterVisit(new AddImport<>(fqcn, null, false));
}

private void addImport(String pojoName) {
String fqcn = V2_S3_MODEL_PKG + pojoName;
doAfterVisit(new AddImport<>(fqcn, null, false));
Expand Down
Loading
Loading