Skip to content

Commit 35cdd26

Browse files
committed
Add null checks and use fromContentProvider if content length not set
1 parent 13aa1f8 commit 35cdd26

File tree

4 files changed

+42
-16
lines changed

4 files changed

+42
-16
lines changed

test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven/after/src/main/java/foo/bar/S3Streaming.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,15 @@ void putObject_bucketKeyFile(String bucket, String key, File file) {
5252
}
5353

5454
void putObject_bucketKeyStreamMetadata(String bucket, String key, InputStream stream) {
55-
HeadObjectResponse metadata = HeadObjectResponse.builder()
55+
HeadObjectResponse metadataWithLength = HeadObjectResponse.builder()
5656
.build();
5757
s3.putObject(PutObjectRequest.builder().bucket(bucket).key(key).contentLength(22L)
5858
.build(), RequestBody.fromInputStream(stream, 22L));
59+
60+
61+
HeadObjectResponse metadataWithoutLength = HeadObjectResponse.builder()
62+
.build();
63+
/*AWS SDK for Java v2 migration: When using InputStream to upload with S3Client, Content-Length should be specified and used with RequestBody.fromInputStream(). Otherwise, the entire stream will be buffered in memory.*/s3.putObject(PutObjectRequest.builder().bucket(bucket).key(key).build(), RequestBody.fromContentProvider(() -> stream, "application/octet-stream"));
5964
}
6065

6166
/**

test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven/before/src/main/java/foo/bar/S3Streaming.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,13 @@ void putObject_bucketKeyFile(String bucket, String key, File file) {
4646
}
4747

4848
void putObject_bucketKeyStreamMetadata(String bucket, String key, InputStream stream) {
49-
ObjectMetadata metadata = new ObjectMetadata();
50-
metadata.setContentLength(22);
51-
s3.putObject(bucket, key, stream, metadata);
49+
ObjectMetadata metadataWithLength = new ObjectMetadata();
50+
metadataWithLength.setContentLength(22);
51+
s3.putObject(bucket, key, stream, metadataWithLength);
52+
53+
54+
ObjectMetadata metadataWithoutLength = new ObjectMetadata();
55+
s3.putObject(bucket, key, stream, metadataWithoutLength);
5256
}
5357

5458
/**

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

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.ArrayDeque;
3434
import java.util.Arrays;
3535
import java.util.HashMap;
36+
import java.util.List;
3637
import java.util.Map;
3738
import java.util.Queue;
3839
import java.util.regex.Pattern;
@@ -43,6 +44,7 @@
4344
import org.openrewrite.java.JavaTemplate;
4445
import org.openrewrite.java.JavaVisitor;
4546
import org.openrewrite.java.MethodMatcher;
47+
import org.openrewrite.java.tree.Comment;
4648
import org.openrewrite.java.tree.Expression;
4749
import org.openrewrite.java.tree.J;
4850
import org.openrewrite.java.tree.TypeUtils;
@@ -290,15 +292,13 @@ private J.MethodInvocation addInputStreamToPutObject(J.MethodInvocation method,
290292
String v2Method;
291293

292294
if (contentLen == null) {
293-
String comment = "When using InputStream to upload with S3Client, Content-Length should be specified and used "
294-
+ "with RequestBody.fromInputStream(). Otherwise, the entire stream will be buffered in memory.";
295295
// CHECKSTYLE:OFF: Regexp
296296
v2Method = "#{any()}, RequestBody.fromContentProvider(() -> #{any()}, \"application/octet-stream\")";
297297
// CHECKSTYLE:ON: Regexp
298298
return JavaTemplate.builder(v2Method).build()
299299
.apply(getCursor(), method.getCoordinates().replaceArguments(),
300300
method.getArguments().get(0), inputStream)
301-
.withComments(createComments(comment));
301+
.withComments(inputStreamBufferingWarningComment());
302302
}
303303

304304
StringBuilder sb = new StringBuilder("#{any()}, RequestBody.fromInputStream(#{any()}, #{any()}");
@@ -327,18 +327,23 @@ private J.MethodInvocation transformPutObjectWithStreamAndMetadata(J.MethodInvoc
327327
method.getArguments().get(2)};
328328

329329
if (contentLen == null) {
330-
sb.append(".build(), RequestBody.fromInputStream(#{any()}, -1L)");
331-
} else {
332-
sb.append(".build(), RequestBody.fromInputStream(#{any()}, #{any()}");
330+
// CHECKSTYLE:OFF: Regexp
331+
sb.append(".build(), RequestBody.fromContentProvider(() -> #{any()}, \"application/octet-stream\")");
332+
// CHECKSTYLE:ON: Regexp
333+
return JavaTemplate.builder(sb.toString()).build()
334+
.apply(getCursor(), method.getCoordinates().replaceArguments(), params)
335+
.withComments(inputStreamBufferingWarningComment());
336+
}
333337

334-
if (contentLen instanceof J.Literal) {
335-
sb.append("L");
336-
}
337-
sb.append(")");
338+
sb.append(".build(), RequestBody.fromInputStream(#{any()}, #{any()}");
338339

339-
params = Arrays.copyOf(params, 4);
340-
params[3] = contentLen;
340+
if (contentLen instanceof J.Literal) {
341+
sb.append("L");
341342
}
343+
sb.append(")");
344+
345+
params = Arrays.copyOf(params, 4);
346+
params[3] = contentLen;
342347

343348
return JavaTemplate.builder(sb.toString()).build()
344349
.apply(getCursor(), method.getCoordinates().replaceArguments(), params);
@@ -401,6 +406,9 @@ private String getMetadataForRequest(J.MethodInvocation method) {
401406

402407
private Expression retrieveContentLengthForMetadataIfSet(String metadataName) {
403408
Map<String, Expression> map = metadataMap.get(metadataName);
409+
if (map == null) {
410+
return null;
411+
}
404412
return map.get("contentLength");
405413
}
406414

@@ -496,5 +504,11 @@ private void addTmImport(String pojoName) {
496504
String fqcn = V2_TM_MODEL_PKG + pojoName;
497505
doAfterVisit(new AddImport<>(fqcn, null, false));
498506
}
507+
508+
private List<Comment> inputStreamBufferingWarningComment() {
509+
String warning = "When using InputStream to upload with S3Client, Content-Length should be specified and used "
510+
+ "with RequestBody.fromInputStream(). Otherwise, the entire stream will be buffered in memory.";
511+
return createComments(warning);
512+
}
499513
}
500514
}

v2-migration/src/main/java/software/amazon/awssdk/v2migration/internal/utils/S3TransformUtils.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ public static MethodMatcher v2TmMethodMatcher(String methodSignature) {
7777
public static void addMetadataFields(StringBuilder sb, String metadataName,
7878
Map<String, Map<String, Expression>> metadataMap) {
7979
Map<String, Expression> map = metadataMap.get(metadataName);
80+
if (map == null) {
81+
return;
82+
}
8083

8184
Expression contentLen = map.get("contentLength");
8285
if (contentLen != null) {

0 commit comments

Comments
 (0)