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 static software.amazon.awssdk.utils.Validate.paramNotNull;
19
20 import java.util.function.Consumer;
21 import software.amazon.awssdk.annotations.SdkInternalApi;
22 import software.amazon.awssdk.core.SdkGlobalTime;
23 import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
24 import software.amazon.awssdk.core.internal.http.pipeline.RequestPipeline;
25 import software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder;
26 import software.amazon.awssdk.core.internal.retry.ClockSkewAdjuster;
27 import software.amazon.awssdk.utils.SdkAutoCloseable;
28
29 /**
30  * Client scoped dependencies of {@link AmazonSyncHttpClient} and {@link AmazonAsyncHttpClient}.
31  * May be injected into constructors of {@link RequestPipeline} implementations by {@link RequestPipelineBuilder}.
32  */

33 @SdkInternalApi
34 public final class HttpClientDependencies implements SdkAutoCloseable {
35     private final ClockSkewAdjuster clockSkewAdjuster;
36     private final SdkClientConfiguration clientConfiguration;
37
38     /**
39      * Time offset may be mutated by {@link RequestPipeline} implementations if a clock skew is detected.
40      */

41     private volatile int timeOffset = SdkGlobalTime.getGlobalTimeOffset();
42
43     private HttpClientDependencies(Builder builder) {
44         this.clockSkewAdjuster = builder.clockSkewAdjuster != null ? builder.clockSkewAdjuster : new ClockSkewAdjuster();
45         this.clientConfiguration = paramNotNull(builder.clientConfiguration, "ClientConfiguration");
46     }
47
48     public static Builder builder() {
49         return new Builder();
50     }
51
52     public SdkClientConfiguration clientConfiguration() {
53         return clientConfiguration;
54     }
55
56     /**
57      * @return The adjuster used for adjusting the {@link #timeOffset} for this client.
58      */

59     public ClockSkewAdjuster clockSkewAdjuster() {
60         return clockSkewAdjuster;
61     }
62
63     /**
64      * @return Current time offset. This is mutable and should not be cached.
65      */

66     public int timeOffset() {
67         return timeOffset;
68     }
69
70     /**
71      * Updates the time offset of the client as well as the global time offset.
72      */

73     public void updateTimeOffset(int timeOffset) {
74         this.timeOffset = timeOffset;
75         SdkGlobalTime.setGlobalTimeOffset(timeOffset);
76     }
77
78     @Override
79     public void close() {
80         this.clientConfiguration.close();
81     }
82
83     /**
84      * Builder for {@link HttpClientDependencies}.
85      */

86     public static class Builder {
87         private ClockSkewAdjuster clockSkewAdjuster;
88         private SdkClientConfiguration clientConfiguration;
89
90         private Builder() {
91         }
92
93         public Builder clockSkewAdjuster(ClockSkewAdjuster clockSkewAdjuster) {
94             this.clockSkewAdjuster = clockSkewAdjuster;
95             return this;
96         }
97
98         public Builder clientConfiguration(SdkClientConfiguration clientConfiguration) {
99             this.clientConfiguration = clientConfiguration;
100             return this;
101         }
102
103         public Builder clientConfiguration(Consumer<SdkClientConfiguration.Builder> clientConfiguration) {
104             SdkClientConfiguration.Builder c = SdkClientConfiguration.builder();
105             clientConfiguration.accept(c);
106             clientConfiguration(c.build());
107             return this;
108         }
109
110         public HttpClientDependencies build() {
111             return new HttpClientDependencies(this);
112         }
113     }
114 }
115