Skip to content

Commit 180c606

Browse files
authored
Expose S3CrtHttpConfiguration (#3824)
* Expose S3CrtHttpConfiguration to allow users to configure HTTP settings such as connectionTimeout and proxy with the AWS CRT-based S3 client. * Fix checkstyle errors and spotbug issue * Address feedback * close clientTlsContextOptions * Revert "close clientTlsContextOptions" This reverts commit e08c468. * Fix version * Update version
1 parent 0812b7d commit 180c606

File tree

27 files changed

+1438
-305
lines changed

27 files changed

+1438
-305
lines changed

.brazil.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"url-connection-client": { "packageName": "AwsJavaSdk-HttpClient-UrlConnectionClient" },
3131
"utils": { "packageName": "AwsJavaSdk-Core-Utils" },
3232
"imds": { "packageName": "AwsJavaSdk-Imds" },
33+
"crt-core": { "packageName": "AwsJavaSdk-Core-CrtCore" },
3334

3435
"dynamodb": { "packageName": "AwsJavaSdk-DynamoDb" },
3536
"waf": { "packageName": "AwsJavaSdk-Waf" },
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "feature",
3+
"category": "AWS CRT-based S3 client",
4+
"contributor": "",
5+
"description": "Exposes `S3CrtHttpConfiguration` to allow users to configure HTTP settings such as proxy and connection timeout on AWS CRT-based S3 client. [#3262](https://github.com/aws/aws-sdk-java-v2/issues/3262)"
6+
}

build-tools/src/main/java/software/amazon/awssdk/buildtools/findbugs/ToBuilderIsCorrect.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ private void validateBuilderConstructor(String buildableClassName, JavaClass bui
376376
}
377377

378378
// Find which fields we modified in those constructors
379-
Set<String> builderFieldsForBuilder = new HashSet<>(builderFields.get(builder));
379+
Set<String> builderFieldsForBuilder = new HashSet<>(builderFields.getOrDefault(builder, new ArrayList<>()));
380380
Map<String, List<String>> allConstructors = builderConstructorModifiedFields.get(builder);
381381

382382
allInvokedConstructors.forEach(constructorSignature -> {

core/crt-core/pom.xml

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
~
5+
~ Licensed under the Apache License, Version 2.0 (the "License").
6+
~ You may not use this file except in compliance with the License.
7+
~ A copy of the License is located at
8+
~
9+
~ http://aws.amazon.com/apache2.0
10+
~
11+
~ or in the "license" file accompanying this file. This file is distributed
12+
~ on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13+
~ express or implied. See the License for the specific language governing
14+
~ permissions and limitations under the License.
15+
-->
16+
17+
<project xmlns="http://maven.apache.org/POM/4.0.0"
18+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
19+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
20+
<modelVersion>4.0.0</modelVersion>
21+
<parent>
22+
<groupId>software.amazon.awssdk</groupId>
23+
<artifactId>core</artifactId>
24+
<version>2.20.28-SNAPSHOT</version>
25+
</parent>
26+
27+
<artifactId>crt-core</artifactId>
28+
<name>AWS Java SDK :: AWS CRT Core</name>
29+
<description>The AWS SDK for Java - AWS CRT Core holds common types that are built on the AWS Common Runtime
30+
</description>
31+
<url>https://aws.amazon.com/sdkforjava</url>
32+
<dependencies>
33+
<dependency>
34+
<groupId>software.amazon.awssdk</groupId>
35+
<artifactId>annotations</artifactId>
36+
<version>${awsjavasdk.version}</version>
37+
</dependency>
38+
<dependency>
39+
<groupId>software.amazon.awssdk</groupId>
40+
<artifactId>utils</artifactId>
41+
<version>${awsjavasdk.version}</version>
42+
</dependency>
43+
<dependency>
44+
<groupId>software.amazon.awssdk.crt</groupId>
45+
<artifactId>aws-crt</artifactId>
46+
<version>${awscrt.version}</version>
47+
<optional>true</optional>
48+
</dependency>
49+
<dependency>
50+
<groupId>org.assertj</groupId>
51+
<artifactId>assertj-core</artifactId>
52+
<scope>test</scope>
53+
</dependency>
54+
<dependency>
55+
<groupId>software.amazon.awssdk</groupId>
56+
<artifactId>test-utils</artifactId>
57+
<version>${awsjavasdk.version}</version>
58+
<scope>test</scope>
59+
<exclusions>
60+
<exclusion>
61+
<groupId>junit</groupId>
62+
<artifactId>junit</artifactId>
63+
</exclusion>
64+
<exclusion>
65+
<groupId>org.junit.vintage</groupId>
66+
<artifactId>junit-vintage-engine</artifactId>
67+
</exclusion>
68+
</exclusions>
69+
</dependency>
70+
<dependency>
71+
<groupId>org.mockito</groupId>
72+
<artifactId>mockito-core</artifactId>
73+
<scope>test</scope>
74+
</dependency>
75+
</dependencies>
76+
<build>
77+
<plugins>
78+
<plugin>
79+
<groupId>org.apache.maven.plugins</groupId>
80+
<artifactId>maven-jar-plugin</artifactId>
81+
<configuration>
82+
<archive>
83+
<manifestEntries>
84+
<Automatic-Module-Name>software.amazon.awssdk.crtcore</Automatic-Module-Name>
85+
</manifestEntries>
86+
</archive>
87+
</configuration>
88+
</plugin>
89+
</plugins>
90+
</build>
91+
92+
</project>
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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.crtcore;
17+
18+
import java.util.Optional;
19+
import software.amazon.awssdk.annotations.SdkProtectedApi;
20+
import software.amazon.awssdk.crt.http.HttpMonitoringOptions;
21+
import software.amazon.awssdk.crt.http.HttpProxyOptions;
22+
import software.amazon.awssdk.crt.io.TlsContext;
23+
import software.amazon.awssdk.utils.NumericUtils;
24+
25+
@SdkProtectedApi
26+
public final class CrtConfigurationUtils {
27+
28+
private CrtConfigurationUtils() {
29+
}
30+
31+
public static Optional<HttpProxyOptions> resolveProxy(CrtProxyConfiguration proxyConfiguration,
32+
TlsContext tlsContext) {
33+
if (proxyConfiguration == null) {
34+
return Optional.empty();
35+
}
36+
37+
HttpProxyOptions clientProxyOptions = new HttpProxyOptions();
38+
39+
clientProxyOptions.setHost(proxyConfiguration.host());
40+
clientProxyOptions.setPort(proxyConfiguration.port());
41+
42+
if ("https".equalsIgnoreCase(proxyConfiguration.scheme())) {
43+
clientProxyOptions.setTlsContext(tlsContext);
44+
}
45+
46+
if (proxyConfiguration.username() != null && proxyConfiguration.password() != null) {
47+
clientProxyOptions.setAuthorizationUsername(proxyConfiguration.username());
48+
clientProxyOptions.setAuthorizationPassword(proxyConfiguration.password());
49+
clientProxyOptions.setAuthorizationType(HttpProxyOptions.HttpProxyAuthorizationType.Basic);
50+
} else {
51+
clientProxyOptions.setAuthorizationType(HttpProxyOptions.HttpProxyAuthorizationType.None);
52+
}
53+
54+
return Optional.of(clientProxyOptions);
55+
}
56+
57+
public static Optional<HttpMonitoringOptions> resolveHttpMonitoringOptions(CrtConnectionHealthConfiguration config) {
58+
if (config == null) {
59+
return Optional.empty();
60+
}
61+
62+
HttpMonitoringOptions httpMonitoringOptions = new HttpMonitoringOptions();
63+
httpMonitoringOptions.setMinThroughputBytesPerSecond(config.minimumThroughputInBps());
64+
int seconds = NumericUtils.saturatedCast(config.minimumThroughputTimeout().getSeconds());
65+
httpMonitoringOptions.setAllowableThroughputFailureIntervalSeconds(seconds);
66+
return Optional.of(httpMonitoringOptions);
67+
}
68+
69+
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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.crtcore;
17+
18+
import java.time.Duration;
19+
import software.amazon.awssdk.annotations.SdkPublicApi;
20+
import software.amazon.awssdk.utils.Validate;
21+
22+
/**
23+
* The base class for CRT connection health configuration
24+
*/
25+
@SdkPublicApi
26+
public abstract class CrtConnectionHealthConfiguration {
27+
private final long minimumThroughputInBps;
28+
private final Duration minimumThroughputTimeout;
29+
30+
protected CrtConnectionHealthConfiguration(DefaultBuilder<?> builder) {
31+
this.minimumThroughputInBps = Validate.paramNotNull(builder.minimumThroughputInBps,
32+
"minimumThroughputInBps");
33+
this.minimumThroughputTimeout = Validate.isPositive(builder.minimumThroughputTimeout,
34+
"minimumThroughputTimeout");
35+
}
36+
37+
/**
38+
* @return the minimum amount of throughput, in bytes per second, for a connection to be considered healthy.
39+
*/
40+
public final long minimumThroughputInBps() {
41+
return minimumThroughputInBps;
42+
}
43+
44+
/**
45+
* @return How long a connection is allowed to be unhealthy before getting shut down.
46+
*/
47+
public final Duration minimumThroughputTimeout() {
48+
return minimumThroughputTimeout;
49+
}
50+
51+
52+
@Override
53+
public boolean equals(Object o) {
54+
if (this == o) {
55+
return true;
56+
}
57+
if (o == null || getClass() != o.getClass()) {
58+
return false;
59+
}
60+
61+
CrtConnectionHealthConfiguration that = (CrtConnectionHealthConfiguration) o;
62+
63+
if (minimumThroughputInBps != that.minimumThroughputInBps) {
64+
return false;
65+
}
66+
return minimumThroughputTimeout.equals(that.minimumThroughputTimeout);
67+
}
68+
69+
@Override
70+
public int hashCode() {
71+
int result = (int) (minimumThroughputInBps ^ (minimumThroughputInBps >>> 32));
72+
result = 31 * result + minimumThroughputTimeout.hashCode();
73+
return result;
74+
}
75+
76+
/**
77+
* A builder for {@link CrtConnectionHealthConfiguration}.
78+
*
79+
* <p>All implementations of this interface are mutable and not thread safe.</p>
80+
*/
81+
public interface Builder {
82+
83+
/**
84+
* Sets a throughput threshold for connections. Throughput below this value will be considered unhealthy.
85+
*
86+
* @param minimumThroughputInBps minimum amount of throughput, in bytes per second, for a connection to be
87+
* considered healthy.
88+
* @return Builder
89+
*/
90+
Builder minimumThroughputInBps(Long minimumThroughputInBps);
91+
92+
/**
93+
* Sets how long a connection is allowed to be unhealthy before getting shut down.
94+
*
95+
* <p>
96+
* It only supports seconds precision
97+
*
98+
* @param minimumThroughputTimeout How long a connection is allowed to be unhealthy
99+
* before getting shut down.
100+
* @return Builder
101+
*/
102+
Builder minimumThroughputTimeout(Duration minimumThroughputTimeout);
103+
104+
CrtConnectionHealthConfiguration build();
105+
}
106+
107+
protected abstract static class DefaultBuilder<B extends Builder> implements Builder {
108+
private Long minimumThroughputInBps;
109+
private Duration minimumThroughputTimeout;
110+
111+
protected DefaultBuilder() {
112+
}
113+
114+
protected DefaultBuilder(CrtConnectionHealthConfiguration configuration) {
115+
this.minimumThroughputInBps = configuration.minimumThroughputInBps;
116+
this.minimumThroughputTimeout = configuration.minimumThroughputTimeout;
117+
}
118+
119+
@Override
120+
public B minimumThroughputInBps(Long minimumThroughputInBps) {
121+
this.minimumThroughputInBps = minimumThroughputInBps;
122+
return (B) this;
123+
}
124+
125+
@Override
126+
public B minimumThroughputTimeout(Duration minimumThroughputTimeout) {
127+
this.minimumThroughputTimeout = minimumThroughputTimeout;
128+
return (B) this;
129+
}
130+
131+
}
132+
}

0 commit comments

Comments
 (0)