diff --git a/services/s3control/src/main/java/software/amazon/awssdk/services/s3control/internal/interceptors/EndpointAddressInterceptor.java b/services/s3control/src/main/java/software/amazon/awssdk/services/s3control/internal/interceptors/EndpointAddressInterceptor.java deleted file mode 100644 index 40930fae167f..000000000000 --- a/services/s3control/src/main/java/software/amazon/awssdk/services/s3control/internal/interceptors/EndpointAddressInterceptor.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 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.s3control.internal.interceptors; - - -import static software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute.SERVICE_SIGNING_NAME; -import static software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute.SIGNING_REGION; -import static software.amazon.awssdk.core.interceptor.SdkExecutionAttribute.CLIENT_ENDPOINT; -import static software.amazon.awssdk.core.interceptor.SdkExecutionAttribute.ENDPOINT_OVERRIDDEN; -import static software.amazon.awssdk.services.s3control.internal.HandlerUtils.ENDPOINT_PREFIX; -import static software.amazon.awssdk.services.s3control.internal.HandlerUtils.S3_OUTPOSTS; -import static software.amazon.awssdk.services.s3control.internal.HandlerUtils.isDualstackEnabled; -import static software.amazon.awssdk.services.s3control.internal.HandlerUtils.isFipsEnabledInClientConfig; -import static software.amazon.awssdk.services.s3control.internal.HandlerUtils.isFipsRegion; -import static software.amazon.awssdk.services.s3control.internal.HandlerUtils.isFipsRegion; -import static software.amazon.awssdk.services.s3control.internal.HandlerUtils.isUseArnRegionEnabledInClientConfig; -import static software.amazon.awssdk.services.s3control.internal.S3ControlInternalExecutionAttribute.S3_ARNABLE_FIELD; - -import java.net.URI; -import java.util.Optional; -import software.amazon.awssdk.annotations.SdkInternalApi; -import software.amazon.awssdk.arns.Arn; -import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute; -import software.amazon.awssdk.core.SdkRequest; -import software.amazon.awssdk.core.interceptor.Context; -import software.amazon.awssdk.core.interceptor.ExecutionAttributes; -import software.amazon.awssdk.core.interceptor.ExecutionInterceptor; -import software.amazon.awssdk.http.SdkHttpRequest; -import software.amazon.awssdk.regions.PartitionMetadata; -import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.s3.internal.resource.S3OutpostResource; -import software.amazon.awssdk.services.s3.internal.resource.S3Resource; -import software.amazon.awssdk.services.s3.internal.settingproviders.UseArnRegionProviderChain; -import software.amazon.awssdk.services.s3control.S3ControlConfiguration; -import software.amazon.awssdk.services.s3control.internal.S3ArnableField; -import software.amazon.awssdk.services.s3control.internal.S3ControlArnConverter; -import software.amazon.awssdk.utils.StringUtils; -import software.amazon.awssdk.utils.Validate; - -/** - * Execution interceptor which modifies the HTTP request to S3 Control to - * change the endpoint to the correct endpoint. This includes prefixing the AWS - * account identifier and, when enabled, adding in FIPS and dualstack. - */ -@SdkInternalApi -public final class EndpointAddressInterceptor implements ExecutionInterceptor { - private static final String X_AMZ_OUTPOST_ID_HEADER = "x-amz-outpost-id"; - private static final UseArnRegionProviderChain USE_ARN_REGION_RESOLVER = UseArnRegionProviderChain.create(); - - @Override - public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, - ExecutionAttributes executionAttributes) { - Optional requestArn = getRequestArn(executionAttributes); - - if (requestArn.isPresent()) { - return resolveHostForOutpostArnRequest(context.httpRequest(), executionAttributes, requestArn.get()); - } else if (isNonArnOutpostRequest(context.request())) { - return resolveHostForOutpostNonArnRequest(context.httpRequest(), executionAttributes); - } else { - return resolveHostForNonOutpostNonArnRequest(context.httpRequest(), executionAttributes); - } - } - - private SdkHttpRequest resolveHostForOutpostArnRequest(SdkHttpRequest request, - ExecutionAttributes executionAttributes, - Arn arn) { - S3Resource s3Resource = S3ControlArnConverter.getInstance().convertArn(arn); - - S3ControlConfiguration serviceConfig = getServiceConfig(executionAttributes); - String signingRegion = executionAttributes.getAttribute(SIGNING_REGION).id(); - String arnRegion = s3Resource.region().orElseThrow(() -> new IllegalArgumentException("Region is missing from ARN.")); - String arnPartion = arn.partition(); - S3Resource parentS3Resource = s3Resource.parentS3Resource().orElse(null); - - Validate.isTrue(!isFipsInvolved(signingRegion, arnRegion, serviceConfig), - "FIPS is not supported for outpost requests."); - - // Even though we validated that we're not *calling* a FIPS region, the client region may still be a FIPS region if we're - // using the ARN region. For that reason, we need to strip off the "fips" from the signing region before we get the - // partition to make sure we're not making a cross-partition call. - signingRegion = removeFipsIfNeeded(signingRegion); - - String signingPartition = PartitionMetadata.of(Region.of(signingRegion)).id(); - - S3OutpostResource outpostResource = Validate.isInstanceOf(S3OutpostResource.class, parentS3Resource, - "The ARN passed must have a parent outpost resource."); - Validate.isTrue(!isDualstackEnabled(serviceConfig), "Dual stack endpoints are not supported for outpost requests."); - Validate.isTrue(arnPartion.equals(signingPartition), - "The partition field of the ARN being passed as a bucket parameter to an S3 operation does not match " - + "the partition the client has been configured with. Provided partition: '%s'; client partition: '%s'.", - arnPartion, signingPartition); - Validate.isTrue(useArnRegion(serviceConfig) || arnRegion.equals(signingRegion), - "The region field of the ARN being passed as a bucket parameter to an operation does not match the " - + "region the client was configured with. Provided region: '%s'; client region: '%s'.", - arnRegion, signingRegion); - - executionAttributes.putAttribute(SIGNING_REGION, Region.of(arnRegion)); - executionAttributes.putAttribute(SERVICE_SIGNING_NAME, S3_OUTPOSTS); - - SdkHttpRequest.Builder requestBuilder = request.toBuilder() - .appendHeader(X_AMZ_OUTPOST_ID_HEADER, outpostResource.outpostId()); - - if (isEndpointOverridden(executionAttributes)) { - // Drop endpoint prefix for ARN-based requests - requestBuilder.host(endpointOverride(executionAttributes).getHost()); - } else { - String arnPartitionDnsSuffix = PartitionMetadata.of(arnPartion).dnsSuffix(); - requestBuilder.host(String.format("s3-outposts.%s.%s", arnRegion, arnPartitionDnsSuffix)); - } - - return requestBuilder.build(); - } - - private SdkHttpRequest resolveHostForOutpostNonArnRequest(SdkHttpRequest sdkHttpRequest, - ExecutionAttributes executionAttributes) { - S3ControlConfiguration serviceConfig = getServiceConfig(executionAttributes); - Region signingRegion = executionAttributes.getAttribute(SIGNING_REGION); - - Validate.isTrue(!isDualstackEnabled(serviceConfig), - "Dual stack is not supported for outpost requests."); - Validate.isTrue(!isFipsEnabledInClientConfig(serviceConfig) && !isFipsRegion(signingRegion.id()), - "FIPS endpoints are not supported for outpost requests."); - - executionAttributes.putAttribute(SERVICE_SIGNING_NAME, S3_OUTPOSTS); - - if (isEndpointOverridden(executionAttributes)) { - // Preserve endpoint prefix for endpoint-overridden non-ARN-based requests - return sdkHttpRequest; - } else { - String signingDnsSuffix = PartitionMetadata.of(signingRegion).dnsSuffix(); - return sdkHttpRequest.copy(r -> r.host(String.format("s3-outposts.%s.%s", signingRegion, signingDnsSuffix))); - } - } - - private SdkHttpRequest resolveHostForNonOutpostNonArnRequest(SdkHttpRequest request, - ExecutionAttributes executionAttributes) { - S3ControlConfiguration serviceConfig = getServiceConfig(executionAttributes); - - boolean isDualStackEnabled = isDualstackEnabled(serviceConfig); - boolean isFipsEnabledInClient = isFipsEnabledInClientConfig(serviceConfig); - - Validate.isTrue(!isDualStackEnabled || !isFipsEnabledInClient, "Dual stack and FIPS are not supported together."); - - if (isEndpointOverridden(executionAttributes)) { - Validate.isTrue(!isDualStackEnabled, "Dual stack is not supported with endpoint overrides."); - Validate.isTrue(!isFipsEnabledInClient, "FIPS is not supported with endpoint overrides."); - // Preserve endpoint prefix for endpoint-overridden non-ARN-based requests - return request; - } else if (isDualStackEnabled) { - String newEndpointPrefix = ENDPOINT_PREFIX + "." + "dualstack"; - return request.copy(r -> r.host(StringUtils.replace(request.host(), ENDPOINT_PREFIX, newEndpointPrefix))); - } else if (isFipsEnabledInClient) { - String newEndpointPrefix = ENDPOINT_PREFIX + "-" + "fips"; - return request.copy(r -> r.host(StringUtils.replace(request.host(), ENDPOINT_PREFIX, newEndpointPrefix))); - } else { - return request; - } - } - - private Optional getRequestArn(ExecutionAttributes executionAttributes) { - return Optional.ofNullable(executionAttributes.getAttribute(S3_ARNABLE_FIELD)) - .map(S3ArnableField::arn); - } - - private boolean isNonArnOutpostRequest(SdkRequest request) { - return request.getValueForField("OutpostId", String.class) - .map(StringUtils::isNotBlank) - .orElse(false); - } - - private S3ControlConfiguration getServiceConfig(ExecutionAttributes executionAttributes) { - return (S3ControlConfiguration) executionAttributes.getAttribute(AwsSignerExecutionAttribute.SERVICE_CONFIG); - } - - private boolean useArnRegion(S3ControlConfiguration configuration) { - // If useArnRegion is false, it was not set to false by the customer, it was simply not enabled - if (isUseArnRegionEnabledInClientConfig(configuration)) { - return true; - } - - return USE_ARN_REGION_RESOLVER.resolveUseArnRegion().orElse(false); - } - - private boolean isEndpointOverridden(ExecutionAttributes executionAttributes) { - return Boolean.TRUE.equals(executionAttributes.getAttribute(ENDPOINT_OVERRIDDEN)); - } - - private URI endpointOverride(ExecutionAttributes executionAttributes) { - return executionAttributes.getAttribute(CLIENT_ENDPOINT); - } - - private boolean isFipsInvolved(String signingRegion, String arnRegion, S3ControlConfiguration serviceConfig) { - if (serviceConfig.fipsModeEnabled()) { - return true; - } - - return isFipsRegion(signingRegion) || isFipsRegion(arnRegion); - } - - private String removeFipsIfNeeded(String region) { - if (region.startsWith("fips-")) { - return StringUtils.replace(region, "fips-", ""); - } - - if (region.endsWith("-fips")) { - return StringUtils.replace(region, "-fips", ""); - } - return region; - } -} diff --git a/services/s3control/src/test/java/software/amazon/awssdk/services/s3control/internal/interceptors/EndpointAddressInterceptorTest.java b/services/s3control/src/test/java/software/amazon/awssdk/services/s3control/internal/interceptors/EndpointAddressInterceptorTest.java deleted file mode 100644 index ce035d11b194..000000000000 --- a/services/s3control/src/test/java/software/amazon/awssdk/services/s3control/internal/interceptors/EndpointAddressInterceptorTest.java +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright 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.s3control.internal.interceptors; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute.SERVICE_SIGNING_NAME; -import static software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute.SIGNING_REGION; -import static software.amazon.awssdk.core.interceptor.SdkExecutionAttribute.SERVICE_CONFIG; -import static software.amazon.awssdk.services.s3control.internal.S3ControlInternalExecutionAttribute.S3_ARNABLE_FIELD; - -import java.util.Optional; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import software.amazon.awssdk.arns.Arn; -import software.amazon.awssdk.core.Protocol; -import software.amazon.awssdk.core.SdkRequest; -import software.amazon.awssdk.core.async.AsyncRequestBody; -import software.amazon.awssdk.core.interceptor.ExecutionAttributes; -import software.amazon.awssdk.core.interceptor.SdkExecutionAttribute; -import software.amazon.awssdk.core.sync.RequestBody; -import software.amazon.awssdk.http.SdkHttpFullRequest; -import software.amazon.awssdk.http.SdkHttpMethod; -import software.amazon.awssdk.http.SdkHttpRequest; -import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.s3control.S3ControlClient; -import software.amazon.awssdk.services.s3control.S3ControlConfiguration; -import software.amazon.awssdk.services.s3control.internal.S3ArnableField; -import software.amazon.awssdk.services.s3control.model.CreateBucketRequest; -import software.amazon.awssdk.services.s3control.model.ListRegionalBucketsRequest; - -public class EndpointAddressInterceptorTest { - @Rule - public ExpectedException thrown = ExpectedException.none(); - - private static final String X_AMZ_ACCOUNT_ID = "x-amz-account-id"; - private static final String ACCOUNT_ID = "123456789012"; - - private SdkHttpRequest request; - private S3ControlConfiguration configuration; - private ExecutionAttributes executionAttributes; - - @Before - public void setup() { - request = SdkHttpFullRequest.builder() - .appendHeader(X_AMZ_ACCOUNT_ID, ACCOUNT_ID) - .protocol(Protocol.HTTPS.toString()) - .method(SdkHttpMethod.POST) - .host(S3ControlClient.serviceMetadata().endpointFor(Region.US_EAST_1).toString()) - .build(); - configuration = S3ControlConfiguration.builder().build(); - executionAttributes = new ExecutionAttributes(); - executionAttributes.putAttribute(SERVICE_SIGNING_NAME, "s3-control"); - executionAttributes.putAttribute(SIGNING_REGION, Region.of("us-east-1")); - executionAttributes.putAttribute(SERVICE_CONFIG, configuration); - } - - @Test - public void modifyHttpRequest_ResolvesCorrectHost_StandardSettings() { - EndpointAddressInterceptor interceptor = new EndpointAddressInterceptor(); - SdkHttpRequest modified = interceptor.modifyHttpRequest(new Context(request), new ExecutionAttributes()); - assertThat(modified.host()).isEqualTo("s3-control.us-east-1.amazonaws.com"); - } - - @Test - public void modifyHttpRequest_ResolvesCorrectHost_Dualstack() { - EndpointAddressInterceptor interceptor = new EndpointAddressInterceptor(); - - S3ControlConfiguration controlConfiguration = S3ControlConfiguration.builder().dualstackEnabled(true).build(); - ExecutionAttributes executionAttributes = new ExecutionAttributes(); - executionAttributes.putAttribute(SdkExecutionAttribute.SERVICE_CONFIG, controlConfiguration); - - SdkHttpRequest modified = interceptor.modifyHttpRequest(new Context(request), executionAttributes); - assertThat(modified.host()).isEqualTo("s3-control.dualstack.us-east-1.amazonaws.com"); - } - - @Test - public void modifyHttpRequest_ResolvesCorrectHost_Fips() { - EndpointAddressInterceptor interceptor = new EndpointAddressInterceptor(); - - S3ControlConfiguration controlConfiguration = S3ControlConfiguration.builder().fipsModeEnabled(true).build(); - ExecutionAttributes executionAttributes = new ExecutionAttributes(); - executionAttributes.putAttribute(SdkExecutionAttribute.SERVICE_CONFIG, controlConfiguration); - - SdkHttpRequest modified = interceptor.modifyHttpRequest(new Context(request), executionAttributes); - assertThat(modified.host()).isEqualTo("s3-control-fips.us-east-1.amazonaws.com"); - } - - @Test - public void createBucketRequestWithOutpostId_shouldRedirect() { - EndpointAddressInterceptor interceptor = new EndpointAddressInterceptor(); - CreateBucketRequest createBucketRequest = CreateBucketRequest.builder().outpostId("1234").build(); - - S3ControlConfiguration controlConfiguration = S3ControlConfiguration.builder().build(); - ExecutionAttributes executionAttributes = new ExecutionAttributes(); - executionAttributes.putAttribute(SdkExecutionAttribute.SERVICE_CONFIG, controlConfiguration); - executionAttributes.putAttribute(SIGNING_REGION, Region.US_EAST_1); - - SdkHttpRequest modified = interceptor.modifyHttpRequest(new Context(request).request(createBucketRequest), - executionAttributes); - assertThat(executionAttributes.getAttribute(SERVICE_SIGNING_NAME)).isEqualTo("s3-outposts"); - assertThat(modified.host()).isEqualTo("s3-outposts.us-east-1.amazonaws.com"); - } - - @Test - public void listRegionalBucketsRequestsWithOutpostId_shouldRedirect() { - EndpointAddressInterceptor interceptor = new EndpointAddressInterceptor(); - ListRegionalBucketsRequest sdkRequest = ListRegionalBucketsRequest.builder().outpostId("1234").build(); - - S3ControlConfiguration controlConfiguration = S3ControlConfiguration.builder().build(); - ExecutionAttributes executionAttributes = new ExecutionAttributes(); - executionAttributes.putAttribute(SdkExecutionAttribute.SERVICE_CONFIG, controlConfiguration); - executionAttributes.putAttribute(SIGNING_REGION, Region.US_EAST_1); - executionAttributes.putAttribute(SERVICE_SIGNING_NAME, "s3"); - - SdkHttpRequest modified = interceptor.modifyHttpRequest(new Context(request).request(sdkRequest), - executionAttributes); - assertThat(executionAttributes.getAttribute(SERVICE_SIGNING_NAME)).isEqualTo("s3-outposts"); - assertThat(modified.host()).isEqualTo("s3-outposts.us-east-1.amazonaws.com"); - } - - @Test - public void listRegionalBucketsRequestsWithoutOutpostId_shouldNotRedirect() { - EndpointAddressInterceptor interceptor = new EndpointAddressInterceptor(); - ListRegionalBucketsRequest sdkRequest = ListRegionalBucketsRequest.builder().build(); - - S3ControlConfiguration controlConfiguration = S3ControlConfiguration.builder() - .dualstackEnabled(true) - .build(); - ExecutionAttributes executionAttributes = new ExecutionAttributes(); - executionAttributes.putAttribute(SdkExecutionAttribute.SERVICE_CONFIG, controlConfiguration); - executionAttributes.putAttribute(SIGNING_REGION, Region.US_EAST_1); - executionAttributes.putAttribute(SERVICE_SIGNING_NAME, "s3"); - - SdkHttpRequest modified = interceptor.modifyHttpRequest(new Context(request).request(sdkRequest), - executionAttributes); - assertThat(executionAttributes.getAttribute(SERVICE_SIGNING_NAME)).isEqualTo("s3"); - assertThat(modified.host()).isEqualTo("s3-control.dualstack.us-east-1.amazonaws.com"); - } - - @Test - public void createBucketRequestsWithoutOutpostId_shouldNotRedirect() { - EndpointAddressInterceptor interceptor = new EndpointAddressInterceptor(); - ListRegionalBucketsRequest sdkRequest = ListRegionalBucketsRequest.builder() - .build(); - - S3ControlConfiguration controlConfiguration = S3ControlConfiguration.builder() - .fipsModeEnabled(true) - .build(); - ExecutionAttributes executionAttributes = new ExecutionAttributes(); - executionAttributes.putAttribute(SdkExecutionAttribute.SERVICE_CONFIG, controlConfiguration); - executionAttributes.putAttribute(SIGNING_REGION, Region.US_EAST_1); - executionAttributes.putAttribute(SERVICE_SIGNING_NAME, "s3"); - - SdkHttpRequest modified = interceptor.modifyHttpRequest(new Context(request).request(sdkRequest), - executionAttributes); - assertThat(executionAttributes.getAttribute(SERVICE_SIGNING_NAME)).isEqualTo("s3"); - assertThat(modified.host()).isEqualTo("s3-control-fips.us-east-1.amazonaws.com"); - } - - @Test - public void listRegionalBucketsRequestWithOutpostId_fipsEnabled_shouldThrowException() { - EndpointAddressInterceptor interceptor = new EndpointAddressInterceptor(); - ListRegionalBucketsRequest sdkRequest = ListRegionalBucketsRequest.builder() - .outpostId("123") - .build(); - - S3ControlConfiguration controlConfiguration = S3ControlConfiguration.builder().fipsModeEnabled(true).build(); - ExecutionAttributes executionAttributes = new ExecutionAttributes(); - executionAttributes.putAttribute(SdkExecutionAttribute.SERVICE_CONFIG, controlConfiguration); - executionAttributes.putAttribute(SIGNING_REGION, Region.US_EAST_1); - executionAttributes.putAttribute(SERVICE_SIGNING_NAME, "s3"); - - assertThatThrownBy(() -> interceptor.modifyHttpRequest(new Context(request).request(sdkRequest), - executionAttributes)).hasMessageContaining("FIPS endpoints are " - + "not supported"); - } - - @Test - public void listRegionalBucketsRequestWithOutpostId_fipsDualsackEnabled_shouldThrowException() { - EndpointAddressInterceptor interceptor = new EndpointAddressInterceptor(); - ListRegionalBucketsRequest sdkRequest = ListRegionalBucketsRequest.builder() - .outpostId("123") - .build(); - - S3ControlConfiguration controlConfiguration = S3ControlConfiguration.builder().dualstackEnabled(true).build(); - ExecutionAttributes executionAttributes = new ExecutionAttributes(); - executionAttributes.putAttribute(SdkExecutionAttribute.SERVICE_CONFIG, controlConfiguration); - executionAttributes.putAttribute(SIGNING_REGION, Region.US_EAST_1); - executionAttributes.putAttribute(SERVICE_SIGNING_NAME, "s3"); - - assertThatThrownBy(() -> interceptor.modifyHttpRequest(new Context(request).request(sdkRequest), - executionAttributes)) - .hasMessageContaining("Dual stack"); - } - - @Test(expected = IllegalArgumentException.class) - public void modifyHttpRequest_ThrowsException_FipsAndDualstack() { - EndpointAddressInterceptor interceptor = new EndpointAddressInterceptor(); - - S3ControlConfiguration controlConfiguration = S3ControlConfiguration.builder() - .fipsModeEnabled(true) - .dualstackEnabled(true) - .build(); - ExecutionAttributes executionAttributes = new ExecutionAttributes(); - executionAttributes.putAttribute(SdkExecutionAttribute.SERVICE_CONFIG, controlConfiguration); - - interceptor.modifyHttpRequest(new Context(request), executionAttributes); - } - - @Test - public void outpostBucketArn_shouldResolveHost() { - EndpointAddressInterceptor interceptor = new EndpointAddressInterceptor(); - - Arn arn = Arn.fromString("arn:aws:s3-outposts:us-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket"); - executionAttributes.putAttribute(S3_ARNABLE_FIELD, S3ArnableField.builder().arn(arn).build()); - SdkHttpRequest modifiedRequest = interceptor.modifyHttpRequest(new Context(request), executionAttributes); - - assertThat(modifiedRequest.host()).isEqualTo("s3-outposts.us-east-1.amazonaws.com"); - assertThat(executionAttributes.getAttribute(SERVICE_SIGNING_NAME)).isEqualTo("s3-outposts"); - assertThat(modifiedRequest.headers().get("x-amz-outpost-id").get(0)).isEqualTo("op-01234567890123456"); - assertThat(modifiedRequest.headers().get("x-amz-account-id").get(0)).isEqualTo(ACCOUNT_ID); - } - - @Test - public void outpostAccessPointArn_shouldResolveHost() { - EndpointAddressInterceptor interceptor = new EndpointAddressInterceptor(); - - Arn arn = Arn.fromString("arn:aws:s3-outposts:us-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint"); - executionAttributes.putAttribute(S3_ARNABLE_FIELD, S3ArnableField.builder().arn(arn).build()); - SdkHttpRequest modifiedRequest = interceptor.modifyHttpRequest(new Context(request), executionAttributes); - - assertThat(modifiedRequest.host()).isEqualTo("s3-outposts.us-east-1.amazonaws.com"); - assertThat(executionAttributes.getAttribute(SERVICE_SIGNING_NAME)).isEqualTo("s3-outposts"); - assertThat(modifiedRequest.headers().get("x-amz-outpost-id").get(0)).isEqualTo("op-01234567890123456"); - assertThat(modifiedRequest.headers().get("x-amz-account-id").get(0)).isEqualTo(ACCOUNT_ID); - } - - @Test - public void outpostArnWithFipsEnabled_shouldThrowException() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("FIPS"); - - EndpointAddressInterceptor interceptor = new EndpointAddressInterceptor(); - Arn arn = Arn.fromString("arn:aws:s3-outposts:us-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket"); - executionAttributes.putAttribute(S3_ARNABLE_FIELD, S3ArnableField.builder().arn(arn).build()); - executionAttributes.putAttribute(SERVICE_CONFIG, enableFips()); - interceptor.modifyHttpRequest(new Context(request), executionAttributes); - } - - @Test - public void outpostArnWithDualstackEnabled_shouldThrowException() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Dual stack"); - - EndpointAddressInterceptor interceptor = new EndpointAddressInterceptor(); - Arn arn = Arn.fromString("arn:aws:s3-outposts:us-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket"); - executionAttributes.putAttribute(S3_ARNABLE_FIELD, S3ArnableField.builder().arn(arn).build()); - executionAttributes.putAttribute(SERVICE_CONFIG, enableDualstack()); - interceptor.modifyHttpRequest(new Context(request), executionAttributes); - } - - private S3ControlConfiguration enableDualstack() { - return S3ControlConfiguration.builder() - .dualstackEnabled(true) - .build(); - } - - private S3ControlConfiguration enableFips() { - return S3ControlConfiguration.builder() - .fipsModeEnabled(true) - .build(); - } - - public final class Context implements software.amazon.awssdk.core.interceptor.Context.ModifyHttpRequest { - - private final SdkHttpRequest request; - private SdkRequest sdkRequest = CreateBucketRequest.builder().build(); - - public Context(SdkHttpRequest request) { - this.request = request; - } - - public Context request(SdkRequest sdkRequest) { - this.sdkRequest = sdkRequest; - return this; - } - - @Override - public SdkRequest request() { - return sdkRequest; - } - - @Override - public SdkHttpRequest httpRequest() { - return request; - } - - @Override - public Optional requestBody() { - return Optional.empty(); - } - - @Override - public Optional asyncRequestBody() { - return Optional.empty(); - } - } -}