Skip to content

Commit 236147d

Browse files
committed
Refactoring interceptors for async payloads and adding S3 checksum validation
1 parent ca99b28 commit 236147d

File tree

83 files changed

+2523
-688
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+2523
-688
lines changed

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/Ec2ProtocolSpec.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ private MethodSpec dryRunMethod() {
5151
StaxResponseHandler.class,
5252
dryRunResult,
5353
VoidStaxUnmarshaller.class)
54-
.addStatement("\nclientHandler.execute(new $T<$T, $T>().withMarshaller($L).withResponseHandler($N)" +
54+
.addStatement("\nclientHandler.execute(new $T<$T, $T>().marshaller($L).withResponseHandler($N)" +
5555
".withInput($L))",
5656
ClientExecutionParams.class,
5757
Request.class,

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/JsonProtocolSpec.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ public CodeBlock executionHandler(OperationModel opModel) {
174174
opModel.getInput().getVariableName());
175175

176176
if (opModel.hasStreamingInput()) {
177-
codeBlock.add(".withMarshaller(new $T(new $T(protocolFactory), requestBody))",
177+
codeBlock.add(".withRequestBody(requestBody)")
178+
.add(".withMarshaller(new $T(new $T(protocolFactory), requestBody))",
178179
ParameterizedTypeName.get(ClassName.get(StreamingRequestMarshaller.class), requestType),
179180
marshaller);
180181
} else {

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/QueryProtocolSpec.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ public CodeBlock executionHandler(OperationModel opModel) {
106106
"errorResponseHandler",
107107
opModel.getInput().getVariableName());
108108
if (opModel.hasStreamingInput()) {
109-
return codeBlock.add(".withMarshaller(new $T(new $T(protocolFactory), requestBody)));",
109+
return codeBlock.add(".withRequestBody(requestBody)")
110+
.add(".withMarshaller(new $T(new $T(protocolFactory), requestBody)));",
110111
ParameterizedTypeName.get(ClassName.get(StreamingRequestMarshaller.class), requestType),
111112
marshaller)
112113
.build();

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-client-class.java

Lines changed: 95 additions & 93 deletions
Large diffs are not rendered by default.

core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/handler/AwsClientHandlerUtils.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
4040
import software.amazon.awssdk.core.interceptor.ExecutionInterceptorChain;
4141
import software.amazon.awssdk.core.interceptor.InterceptorContext;
42+
import software.amazon.awssdk.core.interceptor.SdkExecutionAttribute;
4243
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
4344
import software.amazon.awssdk.core.signer.Signer;
4445
import software.amazon.awssdk.http.SdkHttpFullRequest;
@@ -55,7 +56,8 @@ private AwsClientHandlerUtils() {
5556
}
5657

5758
public static <InputT extends SdkRequest, OutputT extends SdkResponse> ExecutionContext createExecutionContext(
58-
ClientExecutionParams<InputT, OutputT> executionParams, SdkClientConfiguration clientConfig) {
59+
ClientExecutionParams<InputT, OutputT> executionParams,
60+
SdkClientConfiguration clientConfig) {
5961

6062
SdkRequest originalRequest = executionParams.getInput();
6163
AwsCredentialsProvider clientCredentials = clientConfig.option(AwsClientOption.CREDENTIALS_PROVIDER);
@@ -76,14 +78,17 @@ public static <InputT extends SdkRequest, OutputT extends SdkResponse> Execution
7678
clientConfig.option(AwsClientOption.SERVICE_SIGNING_NAME))
7779
.putAttribute(AwsExecutionAttribute.AWS_REGION, clientConfig.option(AwsClientOption.AWS_REGION))
7880
.putAttribute(AwsSignerExecutionAttribute.SIGNING_REGION, clientConfig.option(AwsClientOption.SIGNING_REGION))
79-
.putAttribute(SdkInternalExecutionAttribute.IS_FULL_DUPLEX, executionParams.isFullDuplex());
81+
.putAttribute(SdkInternalExecutionAttribute.IS_FULL_DUPLEX, executionParams.isFullDuplex())
82+
.putAttribute(SdkExecutionAttribute.CLIENT_TYPE, clientConfig.option(SdkClientOption.CLIENT_TYPE));
8083

8184
ExecutionInterceptorChain executionInterceptorChain =
8285
new ExecutionInterceptorChain(clientConfig.option(SdkClientOption.EXECUTION_INTERCEPTORS));
8386
return ExecutionContext.builder()
8487
.interceptorChain(executionInterceptorChain)
8588
.interceptorContext(InterceptorContext.builder()
8689
.request(originalRequest)
90+
.asyncRequestBody(executionParams.getAsyncRequestBody())
91+
.requestBody(executionParams.getRequestBody())
8792
.build())
8893
.executionAttributes(executionAttributes)
8994
.signer(computeSigner(originalRequest, clientConfig))

core/sdk-core/src/it/java/software/amazon/awssdk/core/http/timers/client/AbortedExceptionClientExecutionTimerIntegrationTest.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@
2929
import software.amazon.awssdk.core.exception.AbortedException;
3030
import software.amazon.awssdk.core.exception.ApiCallTimeoutException;
3131
import software.amazon.awssdk.core.internal.http.AmazonSyncHttpClient;
32-
import software.amazon.awssdk.http.InvokeableHttpRequest;
32+
import software.amazon.awssdk.http.HttpExecuteResponse;
33+
import software.amazon.awssdk.http.ExecutableHttpRequest;
3334
import software.amazon.awssdk.http.SdkHttpClient;
34-
import software.amazon.awssdk.http.SdkHttpFullResponse;
35+
import software.amazon.awssdk.http.SdkHttpResponse;
3536
import utils.HttpTestUtils;
3637

3738
@RunWith(MockitoJUnitRunner.class)
@@ -43,16 +44,17 @@ public class AbortedExceptionClientExecutionTimerIntegrationTest {
4344
private SdkHttpClient sdkHttpClient;
4445

4546
@Mock
46-
private InvokeableHttpRequest abortableCallable;
47+
private ExecutableHttpRequest abortableCallable;
4748

4849
@Before
4950
public void setup() throws Exception {
5051
when(sdkHttpClient.prepareRequest(any())).thenReturn(abortableCallable);
5152
httpClient = HttpTestUtils.testClientBuilder().httpClient(sdkHttpClient)
5253
.apiCallTimeout(Duration.ofMillis(1000))
5354
.build();
54-
when(abortableCallable.call()).thenReturn(SdkHttpFullResponse.builder()
55-
.statusCode(200)
55+
when(abortableCallable.call()).thenReturn(HttpExecuteResponse.builder().response(SdkHttpResponse.builder()
56+
.statusCode(200)
57+
.build())
5658
.build());
5759
}
5860

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.core;
17+
18+
import software.amazon.awssdk.annotations.SdkPublicApi;
19+
20+
/**
21+
* Enum that represents the type of client being used.
22+
*/
23+
@SdkPublicApi
24+
public enum ClientType {
25+
26+
ASYNC("Async"),
27+
SYNC("Sync");
28+
29+
private final String clientType;
30+
31+
ClientType(String clientType) {
32+
this.clientType = clientType;
33+
}
34+
35+
/* (non-Javadoc)
36+
* @see java.lang.Enum#toString()
37+
*/
38+
@Override
39+
public String toString() {
40+
return clientType;
41+
}
42+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.core.checksums;
17+
18+
import java.security.MessageDigest;
19+
import software.amazon.awssdk.annotations.SdkInternalApi;
20+
21+
/**
22+
* Implementation of {@link SdkChecksum} to calculate an MD5 checksum.
23+
*/
24+
@SdkInternalApi
25+
public class Md5Checksum implements SdkChecksum {
26+
27+
private MessageDigest digest;
28+
29+
private MessageDigest digestLastMarked;
30+
31+
public Md5Checksum() {
32+
this.digest = getDigest();
33+
}
34+
35+
@Override
36+
public void update(int b) {
37+
digest.update((byte) b);
38+
}
39+
40+
@Override
41+
public void update(byte[] b, int off, int len) {
42+
digest.update(b, off, len);
43+
}
44+
45+
@Override
46+
public long getValue() {
47+
throw new UnsupportedOperationException("Use getChecksumBytes() instead.");
48+
}
49+
50+
@Override
51+
public void reset() {
52+
digest = (digestLastMarked == null)
53+
// This is necessary so that should there be a reset without a
54+
// preceding mark, the MD5 would still be computed correctly.
55+
? getDigest()
56+
: cloneFrom(digestLastMarked);
57+
}
58+
59+
private MessageDigest getDigest() {
60+
try {
61+
return MessageDigest.getInstance("MD5");
62+
} catch (Exception e) {
63+
throw new IllegalStateException("Unexpected error creating MD5 checksum", e);
64+
}
65+
}
66+
67+
@Override
68+
public byte[] getChecksumBytes() {
69+
return digest.digest();
70+
}
71+
72+
@Override
73+
public void mark(int readLimit) {
74+
digestLastMarked = cloneFrom(digest);
75+
}
76+
77+
private MessageDigest cloneFrom(MessageDigest from) {
78+
try {
79+
return (MessageDigest) from.clone();
80+
} catch (CloneNotSupportedException e) { // should never occur
81+
throw new IllegalStateException("unexpected", e);
82+
}
83+
}
84+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.core.checksums;
17+
18+
import java.util.zip.Checksum;
19+
import software.amazon.awssdk.annotations.SdkPublicApi;
20+
21+
/**
22+
* Extension of {@link Checksum} to support checksums and checksum validations used by the SDK that
23+
* are not provided by the JDK.
24+
*/
25+
@SdkPublicApi
26+
public interface SdkChecksum extends Checksum {
27+
28+
/**
29+
* Returns the computed checksum in a byte array rather than the long provided by
30+
* {@link #getValue()}.
31+
*
32+
* @return byte[] containing the checksum
33+
*/
34+
byte[] getChecksumBytes();
35+
36+
/**
37+
* Allows marking a checksum for checksums that support the ability to mark and reset.
38+
*
39+
* @param readLimit the maximum limit of bytes that can be read before the mark position becomes invalid.
40+
*/
41+
void mark(int readLimit);
42+
}

core/sdk-core/src/main/java/software/amazon/awssdk/core/client/builder/SdkDefaultClientBuilder.java

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

1616
package software.amazon.awssdk.core.client.builder;
1717

18+
import static software.amazon.awssdk.core.ClientType.ASYNC;
19+
import static software.amazon.awssdk.core.ClientType.SYNC;
1820
import static software.amazon.awssdk.core.client.config.SdkAdvancedAsyncClientOption.FUTURE_COMPLETION_EXECUTOR;
1921
import static software.amazon.awssdk.core.client.config.SdkAdvancedClientOption.SIGNER;
2022
import static software.amazon.awssdk.core.client.config.SdkAdvancedClientOption.USER_AGENT_PREFIX;
@@ -55,8 +57,8 @@
5557
import software.amazon.awssdk.core.internal.http.loader.DefaultSdkHttpClientBuilder;
5658
import software.amazon.awssdk.core.internal.util.UserAgentUtils;
5759
import software.amazon.awssdk.core.retry.RetryPolicy;
58-
import software.amazon.awssdk.http.ExecuteRequest;
59-
import software.amazon.awssdk.http.InvokeableHttpRequest;
60+
import software.amazon.awssdk.http.ExecutableHttpRequest;
61+
import software.amazon.awssdk.http.HttpExecuteRequest;
6062
import software.amazon.awssdk.http.SdkHttpClient;
6163
import software.amazon.awssdk.http.async.AsyncExecuteRequest;
6264
import software.amazon.awssdk.http.async.SdkAsyncHttpClient;
@@ -84,6 +86,7 @@
8486
*/
8587
@SdkProtectedApi
8688
public abstract class SdkDefaultClientBuilder<B extends SdkClientBuilder<B, C>, C> implements SdkClientBuilder<B, C> {
89+
8790
private static final SdkHttpClient.Builder DEFAULT_HTTP_CLIENT_BUILDER = new DefaultSdkHttpClientBuilder();
8891
private static final SdkAsyncHttpClient.Builder DEFAULT_ASYNC_HTTP_CLIENT_BUILDER = new DefaultSdkAsyncHttpClientBuilder();
8992

@@ -204,6 +207,7 @@ protected SdkClientConfiguration finalizeChildConfiguration(SdkClientConfigurati
204207
private SdkClientConfiguration finalizeSyncConfiguration(SdkClientConfiguration config) {
205208
return config.toBuilder()
206209
.option(SdkClientOption.SYNC_HTTP_CLIENT, resolveSyncHttpClient(config))
210+
.option(SdkClientOption.CLIENT_TYPE, SYNC)
207211
.build();
208212
}
209213

@@ -214,6 +218,7 @@ private SdkClientConfiguration finalizeAsyncConfiguration(SdkClientConfiguration
214218
return config.toBuilder()
215219
.option(FUTURE_COMPLETION_EXECUTOR, resolveAsyncFutureCompletionExecutor(config))
216220
.option(ASYNC_HTTP_CLIENT, resolveAsyncHttpClient(config))
221+
.option(SdkClientOption.CLIENT_TYPE, ASYNC)
217222
.build();
218223
}
219224

@@ -365,7 +370,7 @@ private NonManagedSdkHttpClient(SdkHttpClient delegate) {
365370
}
366371

367372
@Override
368-
public InvokeableHttpRequest prepareRequest(ExecuteRequest request) {
373+
public ExecutableHttpRequest prepareRequest(HttpExecuteRequest request) {
369374
return delegate.prepareRequest(request);
370375
}
371376

core/sdk-core/src/main/java/software/amazon/awssdk/core/client/config/SdkClientOption.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.Map;
2222
import java.util.concurrent.ScheduledExecutorService;
2323
import software.amazon.awssdk.annotations.SdkProtectedApi;
24+
import software.amazon.awssdk.core.ClientType;
2425
import software.amazon.awssdk.core.ServiceConfiguration;
2526
import software.amazon.awssdk.core.client.builder.SdkClientBuilder;
2627
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
@@ -86,6 +87,11 @@ public final class SdkClientOption<T> extends ClientOption<T> {
8687
public static final SdkClientOption<SdkHttpClient> SYNC_HTTP_CLIENT =
8788
new SdkClientOption<>(SdkHttpClient.class);
8889

90+
/**
91+
* The type of client used to make requests.
92+
*/
93+
public static final SdkClientOption<ClientType> CLIENT_TYPE = new SdkClientOption<ClientType>(ClientType.class);
94+
8995
/**
9096
* @see ClientOverrideConfiguration#apiCallAttemptTimeout()
9197
*/

0 commit comments

Comments
 (0)