1 /*
2  * Copyright 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.internal.http;
17
18 import software.amazon.awssdk.annotations.SdkInternalApi;
19 import software.amazon.awssdk.core.RequestOverrideConfiguration;
20 import software.amazon.awssdk.core.SdkRequest;
21 import software.amazon.awssdk.core.SdkRequestOverrideConfiguration;
22 import software.amazon.awssdk.core.async.AsyncRequestBody;
23 import software.amazon.awssdk.core.http.ExecutionContext;
24 import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
25 import software.amazon.awssdk.core.interceptor.ExecutionInterceptorChain;
26 import software.amazon.awssdk.core.internal.http.pipeline.RequestPipeline;
27 import software.amazon.awssdk.core.internal.http.timers.TimeoutTracker;
28 import software.amazon.awssdk.core.signer.Signer;
29 import software.amazon.awssdk.utils.Validate;
30
31 /**
32  * Request scoped dependencies and context for an execution of a request by {@link AmazonSyncHttpClient} or
33  * {@link AmazonAsyncHttpClient}.
34  * Provided to the {@link RequestPipeline#execute(Object, RequestExecutionContext)} method.
35  */

36 @SdkInternalApi
37 public final class RequestExecutionContext {
38     private static final RequestOverrideConfiguration EMPTY_CONFIG = SdkRequestOverrideConfiguration.builder().build();
39     private AsyncRequestBody requestProvider;
40     private final SdkRequest originalRequest;
41     private final ExecutionContext executionContext;
42     private TimeoutTracker apiCallTimeoutTracker;
43     private TimeoutTracker apiCallAttemptTimeoutTracker;
44
45     private RequestExecutionContext(Builder builder) {
46         this.requestProvider = builder.requestProvider;
47         this.originalRequest = Validate.paramNotNull(builder.originalRequest, "originalRequest");
48         this.executionContext = Validate.paramNotNull(builder.executionContext, "executionContext");
49     }
50
51     /**
52      * Create a {@link Builder}, used to create a {@link RequestExecutionContext}.
53      */

54     public static Builder builder() {
55         return new Builder();
56     }
57
58     public AsyncRequestBody requestProvider() {
59         return requestProvider;
60     }
61
62     /**
63      * @return Execution interceptors to hook into execution lifecycle.
64      */

65     public ExecutionInterceptorChain interceptorChain() {
66         return executionContext.interceptorChain();
67     }
68
69     public ExecutionAttributes executionAttributes() {
70         return executionContext.executionAttributes();
71     }
72
73     public ExecutionContext executionContext() {
74         return executionContext;
75     }
76
77     public SdkRequest originalRequest() {
78         return originalRequest;
79     }
80
81     public RequestOverrideConfiguration requestConfig() {
82         return originalRequest.overrideConfiguration()
83                               // ugly but needed to avoid capture of capture and creating a type mismatch
84                               .map(c -> (RequestOverrideConfiguration) c)
85                               .orElse(EMPTY_CONFIG);
86     }
87
88     /**
89      * @return SignerProvider used to obtain an instance of a {@link Signer}.
90      */

91     public Signer signer() {
92         return executionContext.signer();
93     }
94
95     /**
96      * @return Tracker task for the {@link TimeoutTracker}.
97      */

98     public TimeoutTracker apiCallTimeoutTracker() {
99         return apiCallTimeoutTracker;
100     }
101
102     /**
103      * Sets the tracker task for the . Should
104      * be called once per request lifecycle.
105      */

106     public void apiCallTimeoutTracker(TimeoutTracker timeoutTracker) {
107         this.apiCallTimeoutTracker = timeoutTracker;
108     }
109
110     public TimeoutTracker apiCallAttemptTimeoutTracker() {
111         return apiCallAttemptTimeoutTracker;
112     }
113
114     public void apiCallAttemptTimeoutTracker(TimeoutTracker timeoutTracker) {
115         this.apiCallAttemptTimeoutTracker = timeoutTracker;
116     }
117
118     /**
119      * Sets the request body provider.
120      * Used for transforming the original body provider to sign events for
121      * event stream operations that support signing.
122      */

123     public void requestProvider(AsyncRequestBody publisher) {
124         requestProvider = publisher;
125     }
126
127     /**
128      * An SDK-internal implementation of {@link Builder}.
129      */

130     public static final class Builder {
131
132         private AsyncRequestBody requestProvider;
133         private SdkRequest originalRequest;
134         private ExecutionContext executionContext;
135
136         public Builder requestProvider(AsyncRequestBody requestProvider) {
137             this.requestProvider = requestProvider;
138             return this;
139         }
140
141         public Builder originalRequest(SdkRequest originalRequest) {
142             this.originalRequest = originalRequest;
143             return this;
144         }
145
146         public Builder executionContext(ExecutionContext executionContext) {
147             this.executionContext = executionContext;
148             return this;
149         }
150
151         public RequestExecutionContext build() {
152             return new RequestExecutionContext(this);
153         }
154     }
155 }
156