Skip to content

Add specific http configurations for cloudwatch and s3 #1450

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 4, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/next-release/bugfix-AmazonCloudWatch-03b6e4e.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"category": "Amazon CloudWatch",
"type": "bugfix",
"description": "Add cloudwatch specific http configurations, specifically reducing `connectionMaxIdleTime`. Related to [#1380](https://github.com/aws/aws-sdk-java-v2/issues/1380)"
}
5 changes: 5 additions & 0 deletions .changes/next-release/bugfix-AmazonS3-2cc26c3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"category": "Amazon S3",
"type": "bugfix",
"description": "Add s3 specific http configurations, specifically reducing `connectionMaxIdleTime`. Related to [#1122](https://github.com/aws/aws-sdk-java-v2/issues/1122)"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.awssdk.services.cloudwatch.internal;

import java.time.Duration;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.http.SdkHttpConfigurationOption;
import software.amazon.awssdk.utils.AttributeMap;

/**
* CloudWatch specific http configurations
*/
@SdkInternalApi
public final class CloudWatchHttpConfigurationOptions {
private static final AttributeMap OPTIONS = AttributeMap
.builder()
.put(SdkHttpConfigurationOption.CONNECTION_MAX_IDLE_TIMEOUT, Duration.ofSeconds(5))
.build();

private CloudWatchHttpConfigurationOptions() {
}

public static AttributeMap defaultHttpConfig() {
return OPTIONS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
"deleteDashboards",
"putDashboard",
"getDashboard"
]
],
"serviceSpecificHttpConfig": "software.amazon.awssdk.services.cloudwatch.internal.CloudWatchHttpConfigurationOptions"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.awssdk.services.s3.internal;

import java.time.Duration;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.http.SdkHttpConfigurationOption;
import software.amazon.awssdk.utils.AttributeMap;

/**
* S3 specific http configurations
*/
@SdkInternalApi
public final class S3HttpConfigurationOptions {
private static final AttributeMap OPTIONS = AttributeMap
.builder()
.put(SdkHttpConfigurationOption.CONNECTION_MAX_IDLE_TIMEOUT, Duration.ofSeconds(5))
.build();

private S3HttpConfigurationOptions() {
}

public static AttributeMap defaultHttpConfig() {
return OPTIONS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,6 @@
"createMethodParams": [
"clientConfiguration"
]
}
},
"serviceSpecificHttpConfig": "software.amazon.awssdk.services.s3.internal.S3HttpConfigurationOptions"
}
6 changes: 6 additions & 0 deletions test/stability-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@
<version>${awsjavasdk.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>cloudwatch</artifactId>
<version>${awsjavasdk.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,22 @@
package software.amazon.awssdk.stability.tests;


/**
* The main method will be invoked when you execute the test jar generated from
* "mvn package -P test-jar"
*
* You can add the tests in the main method.
* eg:
* try {
* S3AsyncStabilityTest s3AsyncStabilityTest = new S3AsyncStabilityTest();
* S3AsyncStabilityTest.setup();
* s3AsyncStabilityTest.putObject_getObject();
* } finally {
* S3AsyncStabilityTest.cleanup();
* }
*/
public class TestRunner {

public static void main(String... args) {
// You can add the tests you want to run here.
// eg:
// try {
// S3AsyncStabilityTest s3AsyncStabilityTest = new S3AsyncStabilityTest();
// S3AsyncStabilityTest.setup();
// s3AsyncStabilityTest.putObject_getObject();
// } finally {
// S3AsyncStabilityTest.cleanup();
// }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.awssdk.stability.tests.cloudwatch;


import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.IntFunction;
import org.apache.commons.lang3.RandomUtils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import software.amazon.awssdk.services.cloudwatch.model.MetricDatum;
import software.amazon.awssdk.stability.tests.exceptions.StabilityTestsRetryableException;
import software.amazon.awssdk.stability.tests.utils.RetryableTest;
import software.amazon.awssdk.stability.tests.utils.StabilityTestRunner;

public class CloudWatchAsyncStabilityTest extends CloudWatchBaseStabilityTest {
private static String namespace;

@BeforeAll
public static void setup() {
namespace = "CloudWatchAsyncStabilityTest" + System.currentTimeMillis();
}

@AfterAll
public static void tearDown() {
cloudWatchAsyncClient.close();
}

@RetryableTest(maxRetries = 3, retryableException = StabilityTestsRetryableException.class)
public void putMetrics_lowTpsLongInterval() {
List<MetricDatum> metrics = new ArrayList<>();
for (int i = 0; i < 20 ; i++) {
metrics.add(MetricDatum.builder()
.metricName("test")
.values(RandomUtils.nextDouble(1d, 1000d))
.build());
}

IntFunction<CompletableFuture<?>> futureIntFunction = i ->
cloudWatchAsyncClient.putMetricData(b -> b.namespace(namespace)
.metricData(metrics));

runCloudWatchTest("putMetrics_lowTpsLongInterval", futureIntFunction);
}


private void runCloudWatchTest(String testName, IntFunction<CompletableFuture<?>> futureIntFunction) {
StabilityTestRunner.newRunner()
.testName("CloudWatchAsyncStabilityTest." + testName)
.futureFactory(futureIntFunction)
.totalRuns(TOTAL_RUNS)
.requestCountPerRun(CONCURRENCY)
.delaysBetweenEachRun(Duration.ofSeconds(6))
.run();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.awssdk.stability.tests.cloudwatch;


import java.time.Duration;
import software.amazon.awssdk.core.retry.RetryPolicy;
import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
import software.amazon.awssdk.services.cloudwatch.CloudWatchAsyncClient;
import software.amazon.awssdk.testutils.service.AwsTestBase;

public abstract class CloudWatchBaseStabilityTest extends AwsTestBase {
protected static final int CONCURRENCY = 50;
protected static final int TOTAL_RUNS = 3;

protected static CloudWatchAsyncClient cloudWatchAsyncClient =
CloudWatchAsyncClient.builder()
.httpClientBuilder(NettyNioAsyncHttpClient.builder().maxConcurrency(CONCURRENCY))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forget how this works...does this one merge the custom config?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup

.credentialsProvider(CREDENTIALS_PROVIDER_CHAIN)
.overrideConfiguration(b -> b
// Retry at test level
.retryPolicy(RetryPolicy.none())
.apiCallTimeout(Duration.ofMinutes(1)))
.build();


}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ public void largeObject_put_get_usingFile() {
downloadLargeObjectToFile();
}

@RetryableTest(maxRetries = 3, retryableException = StabilityTestsRetryableException.class)
public void getBucketAcl_lowTpsLongInterval() {
IntFunction<CompletableFuture<?>> future = i -> s3NettyClient.getBucketAcl(b -> b.bucket(bucketName));
StabilityTestRunner.newRunner()
.testName("S3AsyncStabilityTest.getBucketAcl_lowTpsLongInterval")
.futureFactory(future)
.requestCountPerRun(10)
.totalRuns(3)
.delaysBetweenEachRun(Duration.ofSeconds(6))
.run();
}

private void downloadLargeObjectToFile() {
File randomTempFile = RandomTempFile.randomUncreatedFile();
StabilityTestRunner.newRunner()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import software.amazon.awssdk.core.retry.RetryPolicy;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.http.apache.ApacheHttpClient;
import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
Expand All @@ -46,7 +47,9 @@ public abstract class S3BaseStabilityTest extends AwsTestBase {
.httpClientBuilder(NettyNioAsyncHttpClient.builder()
.maxConcurrency(CONCURRENCY))
.credentialsProvider(CREDENTIALS_PROVIDER_CHAIN)
.overrideConfiguration(b -> b.apiCallTimeout(Duration.ofMinutes(10)))
.overrideConfiguration(b -> b.apiCallTimeout(Duration.ofMinutes(10))
// Retry at test level
.retryPolicy(RetryPolicy.none()))
.build();


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,11 @@ private static CompletableFuture<?> handleException(CompletableFuture<?> future,
} else if (isIOException(cause)) {
exceptionCounter.addIoException();
} else if (cause instanceof SdkClientException) {
exceptionCounter.addClientException();
if (isIOException(cause.getCause())) {
exceptionCounter.addIoException();
} else {
exceptionCounter.addClientException();
}
} else {
exceptionCounter.addUnknownException();
}
Expand Down