Skip to content

Commit dfec4ab

Browse files
authored
Various performance improvements (#3175)
* Various performance improvements * Address feedback and fix failed unit test * Fix test
1 parent 99a4a72 commit dfec4ab

File tree

5 files changed

+59
-34
lines changed

5 files changed

+59
-34
lines changed

core/sdk-core/src/main/java/software/amazon/awssdk/core/SdkStandardLogger.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,27 @@ private SdkStandardLogger() {
4949
* Log the response status code and request ID
5050
*/
5151
public static void logRequestId(SdkHttpResponse response) {
52-
String placeholder = "not available";
53-
String requestId = String.format("Request ID: %s, Extended Request ID: %s",
54-
SdkHttpUtils.firstMatchingHeaderFromCollection(response.headers(),
55-
X_AMZN_REQUEST_ID_HEADERS)
56-
.orElse(placeholder),
57-
response.firstMatchingHeader(X_AMZ_ID_2_HEADER)
58-
.orElse(placeholder));
59-
Supplier<String> logStatement = () -> String.format("Received %s response: %s, %s",
60-
response.isSuccessful() ? "successful" : "failed",
61-
response.statusCode(),
62-
requestId);
52+
Supplier<String> logStatement = () -> constructLog(response);
6353
REQUEST_ID_LOGGER.debug(logStatement);
6454
REQUEST_LOGGER.debug(logStatement);
6555
}
56+
57+
private static String constructLog(SdkHttpResponse response) {
58+
String placeholder = "not available";
59+
String requestId = SdkHttpUtils.firstMatchingHeaderFromCollection(response.headers(),
60+
X_AMZN_REQUEST_ID_HEADERS)
61+
.orElse(placeholder);
62+
StringBuilder details = new StringBuilder().append("Received")
63+
.append(response.isSuccessful() ? " successful" : " failed")
64+
.append(" response:")
65+
.append(" Status Code: ")
66+
.append(response.statusCode())
67+
.append(" Request ID: ")
68+
.append(requestId);
69+
70+
response.firstMatchingHeader(X_AMZ_ID_2_HEADER).ifPresent(extendedRequestId ->
71+
details.append(" Extended Request ID: ")
72+
.append(extendedRequestId));
73+
return details.toString();
74+
}
6675
}

core/sdk-core/src/main/java/software/amazon/awssdk/core/checksums/Algorithm.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515

1616
package software.amazon.awssdk.core.checksums;
1717

18-
import java.util.Arrays;
18+
import java.util.Map;
1919
import software.amazon.awssdk.annotations.SdkPublicApi;
2020
import software.amazon.awssdk.utils.StringUtils;
21+
import software.amazon.awssdk.utils.internal.EnumUtils;
2122

2223
/**
2324
* Enum that indicates all the checksums supported by Flexible checksums in a Service Request/Response Header.
@@ -31,6 +32,8 @@ public enum Algorithm {
3132
SHA1("sha1", 28),
3233
;
3334

35+
private static final Map<String, Algorithm> VALUE_MAP = EnumUtils.uniqueIndex(Algorithm.class, Algorithm::toString);
36+
3437
private final String value;
3538
private final int length;
3639

@@ -44,12 +47,18 @@ public static Algorithm fromValue(String value) {
4447
return null;
4548
}
4649
String normalizedValue = StringUtils.lowerCase(value);
47-
return Arrays.stream(values())
48-
.filter(algorithm -> algorithm.value.equals(normalizedValue))
49-
.findFirst()
50-
.orElseThrow(() -> new IllegalArgumentException(String.format("Unknown Algorithm '%s'", normalizedValue)));
50+
Algorithm algorithm = VALUE_MAP.get(normalizedValue);
51+
if (algorithm == null) {
52+
throw new IllegalArgumentException("The provided value is not a valid algorithm " + value);
53+
}
54+
55+
return algorithm;
5156
}
5257

58+
@Override
59+
public String toString() {
60+
return String.valueOf(value);
61+
}
5362

5463
/**
5564
* Length corresponds to Base64Encoded length for a given Checksum.

core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/async/FileAsyncRequestBody.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515

1616
package software.amazon.awssdk.core.internal.async;
1717

18+
import static software.amazon.awssdk.utils.FunctionalUtils.invokeSafely;
1819
import static software.amazon.awssdk.utils.FunctionalUtils.runAndLogError;
1920

2021
import java.io.IOException;
21-
import java.io.UncheckedIOException;
2222
import java.nio.ByteBuffer;
2323
import java.nio.channels.AsynchronousFileChannel;
2424
import java.nio.channels.CompletionHandler;
@@ -59,6 +59,8 @@ public final class FileAsyncRequestBody implements AsyncRequestBody {
5959
*/
6060
private final Path path;
6161

62+
private final long fileLength;
63+
6264
/**
6365
* Size (in bytes) of ByteBuffer chunks read from the file and delivered to the subscriber.
6466
*/
@@ -67,15 +69,12 @@ public final class FileAsyncRequestBody implements AsyncRequestBody {
6769
private FileAsyncRequestBody(DefaultBuilder builder) {
6870
this.path = builder.path;
6971
this.chunkSizeInBytes = builder.chunkSizeInBytes == null ? DEFAULT_CHUNK_SIZE : builder.chunkSizeInBytes;
72+
this.fileLength = invokeSafely(() -> Files.size(path));
7073
}
7174

7275
@Override
7376
public Optional<Long> contentLength() {
74-
try {
75-
return Optional.of(Files.size(path));
76-
} catch (IOException e) {
77-
throw new UncheckedIOException(e);
78-
}
77+
return Optional.of(fileLength);
7978
}
8079

8180
@Override

core/sdk-core/src/test/java/software/amazon/awssdk/core/async/FileAsyncRequestPublisherTckTest.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@
2121
import java.io.OutputStream;
2222
import java.io.UncheckedIOException;
2323
import java.nio.ByteBuffer;
24+
import java.nio.charset.StandardCharsets;
2425
import java.nio.file.FileSystem;
2526
import java.nio.file.Files;
2627
import java.nio.file.Path;
28+
import java.util.UUID;
2729
import org.reactivestreams.Publisher;
2830
import org.reactivestreams.tck.TestEnvironment;
2931
import software.amazon.awssdk.core.internal.async.FileAsyncRequestBody;
32+
import software.amazon.awssdk.utils.FunctionalUtils;
3033

3134
/**
3235
* TCK verification test for {@link FileAsyncRequestBody}.
@@ -64,10 +67,16 @@ public Publisher<ByteBuffer> createPublisher(long elements) {
6467
@Override
6568
public Publisher<ByteBuffer> createFailedPublisher() {
6669
// tests properly failing on non existing files:
67-
return FileAsyncRequestBody.builder()
68-
.chunkSizeInBytes(CHUNK_SIZE)
69-
.path(rootDir.resolve("does-not-exist"))
70-
.build();
70+
Path path = rootDir.resolve("createFailedPublisher" + UUID.randomUUID());
71+
72+
FunctionalUtils.invokeSafely(() -> Files.write(path, "test".getBytes(StandardCharsets.UTF_8)));
73+
FileAsyncRequestBody fileAsyncRequestBody = FileAsyncRequestBody.builder()
74+
.chunkSizeInBytes(CHUNK_SIZE)
75+
.path(path)
76+
.build();
77+
78+
FunctionalUtils.invokeSafely(() -> Files.delete(path));
79+
return fileAsyncRequestBody;
7180
}
7281

7382
private Path fileOfNChunks(long nChunks) {

services-custom/s3-transfer-manager/src/test/java/software/amazon/awssdk/transfer/s3/internal/S3TransferManagerListenerTest.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@
3030
import java.nio.ByteBuffer;
3131
import java.nio.file.FileSystem;
3232
import java.nio.file.Files;
33-
import java.nio.file.NoSuchFileException;
3433
import java.nio.file.Path;
35-
import java.nio.file.Paths;
3634
import java.util.UUID;
3735
import java.util.concurrent.CompletableFuture;
3836
import java.util.concurrent.CompletionException;
@@ -46,6 +44,7 @@
4644
import software.amazon.awssdk.core.async.AsyncRequestBody;
4745
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
4846
import software.amazon.awssdk.core.async.DrainingSubscriber;
47+
import software.amazon.awssdk.core.exception.SdkClientException;
4948
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
5049
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
5150
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
@@ -268,33 +267,33 @@ public void uploadFile_failure_shouldInvokeListener() throws Exception {
268267
UploadFileRequest uploadFileRequest = UploadFileRequest.builder()
269268
.putObjectRequest(r -> r.bucket("bucket")
270269
.key("key"))
271-
.source(Paths.get("/some/nonexistent/path"))
270+
.source(path)
272271
.overrideConfiguration(b -> b.addListener(listener))
273272
.build();
273+
SdkClientException sdkClientException = SdkClientException.create("");
274+
when(s3Crt.putObject(any(PutObjectRequest.class), any(AsyncRequestBody.class)))
275+
.thenThrow(sdkClientException);
274276
FileUpload fileUpload = tm.uploadFile(uploadFileRequest);
275277

276278
CompletableFuture<CompletedFileUpload> future = fileUpload.completionFuture();
277279
assertThatThrownBy(future::join)
278280
.isInstanceOf(CompletionException.class)
279-
.hasCauseInstanceOf(NoSuchFileException.class);
281+
.hasCause(sdkClientException);
280282

281283
ArgumentCaptor<TransferListener.Context.TransferInitiated> captor1 =
282284
ArgumentCaptor.forClass(TransferListener.Context.TransferInitiated.class);
283285
verify(listener, timeout(1000).times(1)).transferInitiated(captor1.capture());
284286
TransferListener.Context.TransferInitiated ctx1 = captor1.getValue();
285287
assertThat(ctx1.request()).isSameAs(uploadFileRequest);
286-
// transferSize is not known since file did not exist
287-
assertThat(ctx1.progressSnapshot().transferSizeInBytes()).isNotPresent();
288288
assertThat(ctx1.progressSnapshot().bytesTransferred()).isZero();
289289

290290
ArgumentCaptor<TransferListener.Context.TransferFailed> captor2 =
291291
ArgumentCaptor.forClass(TransferListener.Context.TransferFailed.class);
292292
verify(listener, timeout(1000).times(1)).transferFailed(captor2.capture());
293293
TransferListener.Context.TransferFailed ctx2 = captor2.getValue();
294294
assertThat(ctx2.request()).isSameAs(uploadFileRequest);
295-
assertThat(ctx2.progressSnapshot().transferSizeInBytes()).isNotPresent();
296295
assertThat(ctx2.progressSnapshot().bytesTransferred()).isZero();
297-
assertThat(ctx2.exception()).isInstanceOf(NoSuchFileException.class);
296+
assertThat(ctx2.exception()).isEqualTo(sdkClientException);
298297

299298
verifyNoMoreInteractions(listener);
300299
}

0 commit comments

Comments
 (0)