Skip to content

Commit fd966ad

Browse files
committed
Provide HTTP request-level data to PutObjectResponse
1 parent c5ac019 commit fd966ad

File tree

5 files changed

+52
-18
lines changed

5 files changed

+52
-18
lines changed

services-custom/s3-transfer-manager/src/it/java/software/amazon/awssdk/transfer/s3/S3TransferManagerUploadIntegrationTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ public void upload_fileSentCorrectly() throws IOException {
6565
.source(testFile.toPath())
6666
.build());
6767

68-
upload.completionFuture().join();
68+
CompletedUpload completedUpload = upload.completionFuture().join();
69+
assertThat(completedUpload.response().responseMetadata().requestId()).isNotNull();
70+
assertThat(completedUpload.response().sdkHttpResponse()).isNotNull();
6971

7072
ResponseInputStream<GetObjectResponse> obj = s3.getObject(r -> r.bucket(TEST_BUCKET).key(TEST_KEY),
7173
ResponseTransformer.toInputStream());

services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/DefaultS3CrtAsyncClient.java

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

1616
package software.amazon.awssdk.transfer.s3.internal;
1717

18-
19-
import com.amazonaws.s3.RequestDataSupplier;
2018
import com.amazonaws.s3.S3NativeClient;
2119
import com.amazonaws.s3.model.PutObjectOutput;
2220
import java.util.concurrent.CompletableFuture;
2321
import software.amazon.awssdk.annotations.SdkInternalApi;
2422
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
2523
import software.amazon.awssdk.core.async.AsyncRequestBody;
2624
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
25+
import software.amazon.awssdk.http.SdkHttpResponse;
2726
import software.amazon.awssdk.regions.Region;
2827
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
2928
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
@@ -85,14 +84,19 @@ public CompletableFuture<PutObjectResponse> putObject(PutObjectRequest putObject
8584
com.amazonaws.s3.model.PutObjectRequest adaptedRequest = S3CrtPojoConversion.toCrtPutObjectRequest(putObjectRequest);
8685

8786
if (adaptedRequest.contentLength() == null && requestBody.contentLength().isPresent()) {
88-
adaptedRequest = adaptedRequest.toBuilder().contentLength(requestBody.contentLength().get())
89-
.build();
87+
adaptedRequest = adaptedRequest.toBuilder()
88+
.contentLength(requestBody.contentLength().get())
89+
.build();
9090
}
9191

92+
RequestDataSupplierAdapter requestDataSupplier = new RequestDataSupplierAdapter(requestBody);
9293
CompletableFuture<PutObjectOutput> putObjectOutputCompletableFuture = s3NativeClient.putObject(adaptedRequest,
93-
adaptToDataSupplier(requestBody));
94+
requestDataSupplier);
9495

95-
return putObjectOutputCompletableFuture.thenApply(S3CrtPojoConversion::fromCrtPutObjectOutput);
96+
CompletableFuture<SdkHttpResponse> httpResponseFuture = requestDataSupplier.sdkHttpResponseFuture();
97+
return httpResponseFuture.thenCombine(putObjectOutputCompletableFuture,
98+
(header, putObjectOutput) ->
99+
S3CrtPojoConversion.fromCrtPutObjectOutput(putObjectOutput, header));
96100
}
97101

98102
@Override
@@ -106,10 +110,6 @@ public void close() {
106110
configuration.close();
107111
}
108112

109-
private static RequestDataSupplier adaptToDataSupplier(AsyncRequestBody requestBody) {
110-
return new RequestDataSupplierAdapter(requestBody);
111-
}
112-
113113
public static final class DefaultS3CrtClientBuilder implements S3CrtAsyncClientBuilder {
114114
private AwsCredentialsProvider credentialsProvider;
115115
private Region region;

services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/RequestDataSupplierAdapter.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Deque;
2121
import java.util.concurrent.BlockingDeque;
2222
import java.util.concurrent.BlockingQueue;
23+
import java.util.concurrent.CompletableFuture;
2324
import java.util.concurrent.LinkedBlockingDeque;
2425
import java.util.concurrent.LinkedBlockingQueue;
2526
import java.util.concurrent.TimeUnit;
@@ -30,6 +31,7 @@
3031
import org.reactivestreams.Subscription;
3132
import software.amazon.awssdk.annotations.SdkInternalApi;
3233
import software.amazon.awssdk.crt.http.HttpHeader;
34+
import software.amazon.awssdk.http.SdkHttpResponse;
3335
import software.amazon.awssdk.utils.Logger;
3436

3537
/**
@@ -62,6 +64,10 @@ public RequestDataSupplierAdapter(Publisher<ByteBuffer> bodyPublisher) {
6264
this.headersHandler = new ResponseHeadersHandler();
6365
}
6466

67+
public CompletableFuture<SdkHttpResponse> sdkHttpResponseFuture() {
68+
return headersHandler.sdkHttpResponseFuture();
69+
}
70+
6571
@Override
6672
public void onResponseHeaders(final int statusCode, final HttpHeader[] headers) {
6773
headersHandler.onResponseHeaders(statusCode, headers);

services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/S3CrtPojoConversion.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,9 @@ public static com.amazonaws.s3.model.PutObjectRequest toCrtPutObjectRequest(PutO
211211
return putObjectBuilder.build();
212212
}
213213

214-
public static PutObjectResponse fromCrtPutObjectOutput(PutObjectOutput crtPutObjectOutput) {
215-
// TODO: Provide the HTTP request-level data (e.g. response metadata, HTTP response)
214+
public static PutObjectResponse fromCrtPutObjectOutput(PutObjectOutput crtPutObjectOutput,
215+
SdkHttpResponse sdkHttpResponse) {
216+
S3ResponseMetadata s3ResponseMetadata = createS3ResponseMetadata(sdkHttpResponse);
216217
PutObjectResponse.Builder builder = PutObjectResponse.builder()
217218
.bucketKeyEnabled(crtPutObjectOutput.bucketKeyEnabled())
218219
.eTag(crtPutObjectOutput.eTag())
@@ -232,7 +233,9 @@ public static PutObjectResponse fromCrtPutObjectOutput(PutObjectOutput crtPutObj
232233
builder.serverSideEncryption(crtPutObjectOutput.serverSideEncryption().name());
233234
}
234235

235-
return builder.build();
236+
return (PutObjectResponse) builder.responseMetadata(s3ResponseMetadata)
237+
.sdkHttpResponse(sdkHttpResponse)
238+
.build();
236239
}
237240

238241
private static S3ResponseMetadata createS3ResponseMetadata(SdkHttpResponse sdkHttpResponse) {

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

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,14 @@
5656
public class S3CrtPojoConversionTest {
5757
private static final Logger log = Logger.loggerFor(S3CrtPojoConversionTest.class);
5858
private static final Random RNG = new Random();
59-
private static final String ACCESS_KEY = "accessKey";
60-
private static final String SECRET_ACCESS_KEY = "secretAccessKey";
61-
private static final String SESSION_TOKEN = "sessionToken";
6259

6360
@Test
6461
public void fromCrtPutObjectOutputAllFields_shouldConvert() throws IllegalAccessException {
6562

6663
PutObjectOutput crtResponse = randomCrtPutObjectOutput();
67-
PutObjectResponse sdkResponse = S3CrtPojoConversion.fromCrtPutObjectOutput(crtResponse);
64+
SdkHttpResponse sdkHttpResponse = SdkHttpResponse.builder()
65+
.build();
66+
PutObjectResponse sdkResponse = S3CrtPojoConversion.fromCrtPutObjectOutput(crtResponse, sdkHttpResponse);
6867

6968
// ignoring fields with different casings and enum fields.
7069
assertThat(sdkResponse).isEqualToIgnoringGivenFields(crtResponse,
@@ -86,6 +85,30 @@ public void fromCrtPutObjectOutputAllFields_shouldConvert() throws IllegalAccess
8685
//assertThat(sdkResponse.requestCharged().name()).isEqualTo(crtResponse.requestCharged().name());
8786
}
8887

88+
@Test
89+
public void fromCrtPutObjectOutputAllFields_shouldAddSdkHttpResponse() throws IllegalAccessException {
90+
String expectedRequestId = "123456";
91+
PutObjectOutput crtResponse = PutObjectOutput.builder().build();
92+
SdkHttpResponse sdkHttpResponse = SdkHttpResponse.builder()
93+
.statusCode(200)
94+
.appendHeader("x-amz-request-id", expectedRequestId)
95+
.build();
96+
PutObjectResponse sdkResponse = S3CrtPojoConversion.fromCrtPutObjectOutput(crtResponse, sdkHttpResponse);
97+
98+
// ignoring fields with different casing and enum fields.
99+
assertThat(sdkResponse).isEqualToIgnoringGivenFields(crtResponse,
100+
"sseCustomerAlgorithm",
101+
"sseCustomerKeyMD5",
102+
"ssekmsKeyId",
103+
"ssekmsEncryptionContext",
104+
"serverSideEncryption",
105+
"requestCharged",
106+
"responseMetadata",
107+
"sdkHttpResponse");
108+
assertThat(sdkResponse.sdkHttpResponse()).isEqualTo(sdkHttpResponse);
109+
assertThat(sdkResponse.responseMetadata().requestId()).isEqualTo(expectedRequestId);
110+
}
111+
89112
@Test
90113
public void fromCrtGetObjectOutput_shouldAddSdkHttpResponse() {
91114
String expectedRequestId = "123456";

0 commit comments

Comments
 (0)