All Downloads are FREE. Search and download functionalities are using the official Maven repository.

software.amazon.awssdk.services.s3.internal.crossregion.utils.CrossRegionUtils Maven / Gradle / Ivy

Go to download

The AWS Java SDK for Amazon S3 module holds the client classes that are used for communicating with Amazon Simple Storage Service

There is a newer version: 2.29.39
Show newest version
/*
 * 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.s3.internal.crossregion.utils;


import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletionException;
import java.util.function.Consumer;
import java.util.function.Supplier;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
import software.amazon.awssdk.core.ApiName;
import software.amazon.awssdk.endpoints.EndpointProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.endpoints.S3EndpointProvider;
import software.amazon.awssdk.services.s3.internal.crossregion.endpointprovider.BucketEndpointProvider;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.model.S3Request;

@SdkInternalApi
public final class CrossRegionUtils {
    public static final int REDIRECT_STATUS_CODE = 301;
    public static final int TEMPORARY_REDIRECT_STATUS_CODE = 307;
    public static final String AMZ_BUCKET_REGION_HEADER = "x-amz-bucket-region";
    private static final List REDIRECT_STATUS_CODES =
        Arrays.asList(REDIRECT_STATUS_CODE, TEMPORARY_REDIRECT_STATUS_CODE);
    private static final ApiName API_NAME = ApiName.builder().version("cross-region").name("hll").build();
    private static final Consumer USER_AGENT_APPLIER = b -> b.addApiName(API_NAME);


    private CrossRegionUtils() {
    }

    public static Optional getBucketRegionFromException(S3Exception exception) {
        return exception.awsErrorDetails()
                        .sdkHttpResponse()
                        .firstMatchingHeader(AMZ_BUCKET_REGION_HEADER);
    }

    public static boolean isS3RedirectException(Throwable exception) {
        Throwable exceptionToBeChecked = exception instanceof CompletionException ? exception.getCause() : exception;
        return exceptionToBeChecked instanceof S3Exception
               && isRedirectError((S3Exception) exceptionToBeChecked);
    }

    private static boolean isRedirectError(S3Exception exceptionToBeChecked) {
        if (REDIRECT_STATUS_CODES.stream().anyMatch(status -> status.equals(exceptionToBeChecked.statusCode()))) {
            return true;
        }
        return getBucketRegionFromException(exceptionToBeChecked).isPresent();
    }

    @SuppressWarnings("unchecked")
    public static  T requestWithDecoratedEndpointProvider(T request, Supplier regionSupplier,
                                                                               EndpointProvider clientEndpointProvider) {
        AwsRequestOverrideConfiguration requestOverrideConfig =
            request.overrideConfiguration().orElseGet(() -> AwsRequestOverrideConfiguration.builder().build());

        S3EndpointProvider delegateEndpointProvider = (S3EndpointProvider) requestOverrideConfig.endpointProvider()
                                                                                                .orElse(clientEndpointProvider);
        return (T) request.toBuilder()
                          .overrideConfiguration(
                              requestOverrideConfig.toBuilder()
                                                   .endpointProvider(
                                                       BucketEndpointProvider.create(delegateEndpointProvider, regionSupplier))
                                                   .build())
                          .build();
    }

    public static  AwsRequestOverrideConfiguration updateUserAgentInConfig(T request) {
        return
            request.overrideConfiguration().map(c -> c.toBuilder()
                                                      .applyMutation(USER_AGENT_APPLIER)
                                                      .build())
                   .orElseGet(() -> AwsRequestOverrideConfiguration.builder()
                                                                   .applyMutation(USER_AGENT_APPLIER)
                                                                   .build());

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy