Skip to content

Commit e4cbcb9

Browse files
committed
Changes document error root definition for XML based errors to same as AWS S1, so that errors are fully parsed. This change also adds honoring endpoint overrides for the S3 Control client.
1 parent c244893 commit e4cbcb9

File tree

5 files changed

+172
-1
lines changed

5 files changed

+172
-1
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"category": "AWS S3 Control",
3+
"type": "bugfix",
4+
"description": "Changes document error root definition for XML based errors to same as AWS S3, so that errors are fully parsed."
5+
}

services/s3control/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,10 @@
7878
<version>${awsjavasdk.version}</version>
7979
<scope>test</scope>
8080
</dependency>
81+
<dependency>
82+
<groupId>com.github.tomakehurst</groupId>
83+
<artifactId>wiremock</artifactId>
84+
<scope>test</scope>
85+
</dependency>
8186
</dependencies>
8287
</project>

services/s3control/src/main/resources/codegen-resources/customization.config

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
"customResponseMetadata": {
44
"EXTENDED_REQUEST_ID": "x-amz-id-2",
55
"REQUEST_ID": "x-amz-request-id"
6-
}
6+
},
7+
"customProtocolFactoryFqcn": "software.amazon.awssdk.protocols.xml.AwsS3ProtocolFactory"
78
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
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.services.s3control.functionaltests;
17+
18+
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
19+
import static com.github.tomakehurst.wiremock.client.WireMock.any;
20+
import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl;
21+
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
22+
import static org.assertj.core.api.Assertions.assertThat;
23+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
24+
25+
import java.net.URI;
26+
import java.util.concurrent.CompletionException;
27+
import com.github.tomakehurst.wiremock.junit.WireMockRule;
28+
import org.junit.Rule;
29+
import org.junit.Test;
30+
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
31+
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
32+
import software.amazon.awssdk.core.interceptor.Context;
33+
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
34+
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
35+
import software.amazon.awssdk.http.SdkHttpRequest;
36+
import software.amazon.awssdk.regions.Region;
37+
import software.amazon.awssdk.services.s3control.S3ControlAsyncClient;
38+
import software.amazon.awssdk.services.s3control.S3ControlAsyncClientBuilder;
39+
import software.amazon.awssdk.services.s3control.S3ControlClient;
40+
import software.amazon.awssdk.services.s3control.S3ControlClientBuilder;
41+
import software.amazon.awssdk.services.s3control.model.S3ControlException;
42+
43+
public class CreateJobFunctionalTest {
44+
45+
private static final URI HTTP_LOCALHOST_URI = URI.create("http://localhost:8080/");
46+
47+
@Rule
48+
public WireMockRule wireMock = new WireMockRule();
49+
50+
private S3ControlClientBuilder getSyncClientBuilder() {
51+
return S3ControlClient.builder()
52+
.region(Region.US_EAST_1)
53+
.overrideConfiguration(c -> c.addExecutionInterceptor(new LocalhostEndpointAddressInterceptor()))
54+
.credentialsProvider(
55+
StaticCredentialsProvider.create(
56+
AwsBasicCredentials.create("key", "secret")));
57+
}
58+
59+
private S3ControlAsyncClientBuilder getAsyncClientBuilder() {
60+
return S3ControlAsyncClient.builder()
61+
.region(Region.US_EAST_1)
62+
.overrideConfiguration(c -> c.addExecutionInterceptor(new LocalhostEndpointAddressInterceptor()))
63+
.credentialsProvider(
64+
StaticCredentialsProvider.create(
65+
AwsBasicCredentials.create("key", "secret")));
66+
}
67+
68+
@Test
69+
public void createJob_syncClient_errorInResponseBody_correct() {
70+
String accountId = "Account-Id";
71+
String xmlResponseBody = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
72+
+ "<Error>\n"
73+
+ "<Code>InvalidRequest</Code>\n"
74+
+ "<Message>Missing role arn</Message>\n"
75+
+ "<RequestId>656c76696e6727732072657175657374</RequestId>\n"
76+
+ "<HostId>Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg==</HostId>\n"
77+
+ "</Error>";
78+
79+
stubFor(any(anyUrl()).willReturn(aResponse().withStatus(400).withBody(xmlResponseBody)));
80+
81+
S3ControlClient s3Client = getSyncClientBuilder().build();
82+
83+
assertThatThrownBy(() -> s3Client.createJob(r -> r.accountId(accountId)))
84+
.isInstanceOf(S3ControlException.class)
85+
.satisfies(e -> assertThat(((S3ControlException) e).awsErrorDetails().errorCode()).isEqualTo("InvalidRequest"))
86+
.satisfies(e -> assertThat(((S3ControlException) e).awsErrorDetails().errorMessage()).isEqualTo("Missing role arn"));
87+
}
88+
89+
@Test
90+
public void createJob_asyncClient_errorInResponseBody_correct() {
91+
String accountId = "Account-Id";
92+
String xmlResponseBody = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
93+
+ "<Error>\n"
94+
+ "<Code>InvalidRequest</Code>\n"
95+
+ "<Message>Missing role arn</Message>\n"
96+
+ "<RequestId>656c76696e6727732072657175657374</RequestId>\n"
97+
+ "<HostId>Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg==</HostId>\n"
98+
+ "</Error>";
99+
100+
stubFor(any(anyUrl()).willReturn(aResponse().withStatus(400).withBody(xmlResponseBody)));
101+
102+
S3ControlAsyncClient s3Client = getAsyncClientBuilder().build();
103+
104+
assertThatThrownBy(() -> s3Client.createJob(r -> r.accountId(accountId)).join())
105+
.isInstanceOf(CompletionException.class)
106+
.hasCauseInstanceOf(S3ControlException.class)
107+
.satisfies(e -> {
108+
S3ControlException s3ControlException = (S3ControlException) e.getCause();
109+
assertThat(s3ControlException.awsErrorDetails().errorCode()).isEqualTo("InvalidRequest");
110+
assertThat(s3ControlException.awsErrorDetails().errorMessage()).isEqualTo("Missing role arn");
111+
});
112+
}
113+
114+
private static final class LocalhostEndpointAddressInterceptor implements ExecutionInterceptor {
115+
116+
@Override
117+
public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) {
118+
return context.httpRequest()
119+
.toBuilder()
120+
.protocol(HTTP_LOCALHOST_URI.getScheme())
121+
.host(HTTP_LOCALHOST_URI.getHost())
122+
.port(HTTP_LOCALHOST_URI.getPort())
123+
.build();
124+
}
125+
}
126+
127+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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+
log4j.rootLogger=WARN, A1
17+
log4j.appender.A1=org.apache.log4j.ConsoleAppender
18+
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
19+
20+
# Print the date in ISO 8601 format
21+
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
22+
23+
# Adjust to see more / less logging
24+
#log4j.logger.com.amazonaws.ec2=DEBUG
25+
26+
# HttpClient 3 Wire Logging
27+
#log4j.logger.httpclient.wire=DEBUG
28+
29+
# HttpClient 4 Wire Logging
30+
#log4j.logger.org.apache.http.wire=DEBUG
31+
#log4j.logger.org.apache.http=DEBUG
32+
#log4j.logger.org.apache.http.wire=WARN
33+
#log4j.logger.software.amazon.awssdk=DEBUG

0 commit comments

Comments
 (0)