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

software.amazon.awssdk.core.RequestOverrideConfiguration Maven / Gradle / Ivy

Go to download

The AWS SDK for Java - SDK Core runtime module holds the classes that are used by the individual service clients to interact with Amazon Web Services. Users need to depend on aws-java-sdk artifact for accessing individual client classes.

There is a newer version: 2.29.15
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.core;

import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.TreeMap;
import java.util.function.Consumer;
import software.amazon.awssdk.annotations.Immutable;
import software.amazon.awssdk.annotations.SdkPreviewApi;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
import software.amazon.awssdk.core.interceptor.ExecutionAttribute;
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
import software.amazon.awssdk.core.signer.Signer;
import software.amazon.awssdk.endpoints.EndpointProvider;
import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.utils.CollectionUtils;
import software.amazon.awssdk.utils.Validate;

/**
 * Base per-request override configuration for all SDK requests.
 */
@Immutable
@SdkPublicApi
public abstract class RequestOverrideConfiguration {

    private final Map> headers;
    private final Map> rawQueryParameters;
    private final List apiNames;
    private final Duration apiCallTimeout;
    private final Duration apiCallAttemptTimeout;
    private final Signer signer;
    private final List metricPublishers;
    private final ExecutionAttributes executionAttributes;
    private final EndpointProvider endpointProvider;
    private final CompressionConfiguration compressionConfiguration;
    private final List plugins;

    protected RequestOverrideConfiguration(Builder builder) {
        this.headers = CollectionUtils.deepUnmodifiableMap(builder.headers(), () -> new TreeMap<>(String.CASE_INSENSITIVE_ORDER));
        this.rawQueryParameters = CollectionUtils.deepUnmodifiableMap(builder.rawQueryParameters());
        this.apiNames = Collections.unmodifiableList(new ArrayList<>(builder.apiNames()));
        this.apiCallTimeout = Validate.isPositiveOrNull(builder.apiCallTimeout(), "apiCallTimeout");
        this.apiCallAttemptTimeout = Validate.isPositiveOrNull(builder.apiCallAttemptTimeout(), "apiCallAttemptTimeout");
        this.signer = builder.signer();
        this.metricPublishers = Collections.unmodifiableList(new ArrayList<>(builder.metricPublishers()));
        this.executionAttributes = ExecutionAttributes.unmodifiableExecutionAttributes(builder.executionAttributes());
        this.endpointProvider = builder.endpointProvider();
        this.compressionConfiguration = builder.compressionConfiguration();
        this.plugins = Collections.unmodifiableList(new ArrayList<>(builder.plugins()));
    }

    /**
     * Optional additional headers to be added to the HTTP request.
     *
     * @return The optional additional headers.
     */
    public Map> headers() {
        return headers;
    }

    /**
     * Optional additional query parameters to be added to the HTTP request.
     *
     * @return The optional additional query parameters.
     */
    public Map> rawQueryParameters() {
        return rawQueryParameters;
    }

    /**
     * The optional names of the higher level libraries that constructed the request.
     *
     * @return The names of the libraries.
     */
    public List apiNames() {
        return apiNames;
    }

    /**
     * The amount of time to allow the client to complete the execution of an API call. This timeout covers the entire client
     * execution except for marshalling. This includes request handler execution, all HTTP requests including retries,
     * unmarshalling, etc. This value should always be positive, if present.
     *
     * 

The api call timeout feature doesn't have strict guarantees on how quickly a request is aborted when the * timeout is breached. The typical case aborts the request within a few milliseconds but there may occasionally be * requests that don't get aborted until several seconds after the timer has been breached. Because of this, the client * execution timeout feature should not be used when absolute precision is needed. * *

This may be used together with {@link #apiCallAttemptTimeout()} to enforce both a timeout on each individual HTTP * request (i.e. each retry) and the total time spent on all requests across retries (i.e. the 'api call' time). * * @see Builder#apiCallTimeout(Duration) */ public Optional apiCallTimeout() { return Optional.ofNullable(apiCallTimeout); } /** * The amount of time to wait for the http request to complete before giving up and timing out. This value should always be * positive, if present. * *

The request timeout feature doesn't have strict guarantees on how quickly a request is aborted when the timeout is * breached. The typical case aborts the request within a few milliseconds but there may occasionally be requests that * don't get aborted until several seconds after the timer has been breached. Because of this, the request timeout * feature should not be used when absolute precision is needed. * *

This may be used together with {@link #apiCallTimeout()} to enforce both a timeout on each individual HTTP * request * (i.e. each retry) and the total time spent on all requests across retries (i.e. the 'api call' time). * * @see Builder#apiCallAttemptTimeout(Duration) */ public Optional apiCallAttemptTimeout() { return Optional.ofNullable(apiCallAttemptTimeout); } /** * @return the signer for signing the request. This signer get priority over the signer set on the client while * signing the requests. If this value is not set, then the client level signer is used for signing the request. */ public Optional signer() { return Optional.ofNullable(signer); } /** * Return the metric publishers for publishing the metrics collected for this request. This list supersedes the * metric publishers set on the client. */ public List metricPublishers() { return metricPublishers; } /** * Return the plugins that will be used to update the configuration used by the request. */ @SdkPreviewApi public List plugins() { return plugins; } /** * Returns the additional execution attributes to be added to this request. * This collection of attributes is added in addition to the attributes set on the client. * An attribute value added on the client within the collection of attributes is superseded by an * attribute value added on the request. */ public ExecutionAttributes executionAttributes() { return executionAttributes; } /** * Returns the endpoint provider for resolving the endpoint for this request. This supersedes the * endpoint provider set on the client. */ public Optional endpointProvider() { return Optional.ofNullable(endpointProvider); } /** * Returns the compression configuration object, if present, which includes options to enable/disable compression and set * the minimum compression threshold. This compression config object supersedes the compression config object set on the * client. */ public Optional compressionConfiguration() { return Optional.ofNullable(compressionConfiguration); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } RequestOverrideConfiguration that = (RequestOverrideConfiguration) o; return Objects.equals(headers, that.headers) && Objects.equals(rawQueryParameters, that.rawQueryParameters) && Objects.equals(apiNames, that.apiNames) && Objects.equals(apiCallTimeout, that.apiCallTimeout) && Objects.equals(apiCallAttemptTimeout, that.apiCallAttemptTimeout) && Objects.equals(signer, that.signer) && Objects.equals(metricPublishers, that.metricPublishers) && Objects.equals(executionAttributes, that.executionAttributes) && Objects.equals(endpointProvider, that.endpointProvider) && Objects.equals(compressionConfiguration, that.compressionConfiguration) && Objects.equals(plugins, that.plugins); } @Override public int hashCode() { int hashCode = 1; hashCode = 31 * hashCode + Objects.hashCode(headers); hashCode = 31 * hashCode + Objects.hashCode(rawQueryParameters); hashCode = 31 * hashCode + Objects.hashCode(apiNames); hashCode = 31 * hashCode + Objects.hashCode(apiCallTimeout); hashCode = 31 * hashCode + Objects.hashCode(apiCallAttemptTimeout); hashCode = 31 * hashCode + Objects.hashCode(signer); hashCode = 31 * hashCode + Objects.hashCode(metricPublishers); hashCode = 31 * hashCode + Objects.hashCode(executionAttributes); hashCode = 31 * hashCode + Objects.hashCode(endpointProvider); hashCode = 31 * hashCode + Objects.hashCode(compressionConfiguration); hashCode = 31 * hashCode + Objects.hashCode(plugins); return hashCode; } /** * Create a {@link Builder} initialized with the properties of this {@code SdkRequestOverrideConfiguration}. * * @return A new builder intialized with this config's properties. */ public abstract Builder toBuilder(); public interface Builder { /** * Optional additional headers to be added to the HTTP request. * * @return The optional additional headers. */ Map> headers(); /** * Add a single header to be set on the HTTP request. *

* This overrides any values for the given header set on the request by default by the SDK, as well as header * overrides set at the client level using * {@link software.amazon.awssdk.core.client.config.ClientOverrideConfiguration}. * *

* This overrides any values already configured with this header name in the builder. * * @param name The name of the header. * @param value The value of the header. * @return This object for method chaining. */ default B putHeader(String name, String value) { putHeader(name, Collections.singletonList(value)); return (B) this; } /** * Add a single header with multiple values to be set on the HTTP request. *

* This overrides any values for the given header set on the request by default by the SDK, as well as header * overrides set at the client level using * {@link software.amazon.awssdk.core.client.config.ClientOverrideConfiguration}. * *

* This overrides any values already configured with this header name in the builder. * * @param name The name of the header. * @param values The values of the header. * @return This object for method chaining. */ B putHeader(String name, List values); /** * Add additional headers to be set on the HTTP request. *

* This overrides any values for the given headers set on the request by default by the SDK, as well as header * overrides set at the client level using * {@link software.amazon.awssdk.core.client.config.ClientOverrideConfiguration}. * *

* This completely overrides any values currently configured in the builder. * * @param headers The set of additional headers. * @return This object for method chaining. */ B headers(Map> headers); /** * Optional additional query parameters to be added to the HTTP request. * * @return The optional additional query parameters. */ Map> rawQueryParameters(); /** * Add a single query parameter to be set on the HTTP request. * *

* This overrides any values already configured with this query name in the builder. * * @param name The query parameter name. * @param value The query parameter value. * @return This object for method chaining. */ default B putRawQueryParameter(String name, String value) { putRawQueryParameter(name, Collections.singletonList(value)); return (B) this; } /** * Add a single query parameter with multiple values to be set on the HTTP request. * *

* This overrides any values already configured with this query name in the builder. * * @param name The query parameter name. * @param values The query parameter values. * @return This object for method chaining. */ B putRawQueryParameter(String name, List values); /** * Configure query parameters to be set on the HTTP request. * *

* This completely overrides any query parameters currently configured in the builder. * * @param rawQueryParameters The set of additional query parameters. * @return This object for method chaining. */ B rawQueryParameters(Map> rawQueryParameters); /** * The optional names of the higher level libraries that constructed the request. * * @return The names of the libraries. */ List apiNames(); /** * Set the optional name of the higher level library that constructed the request. * * @param apiName The name of the library. * * @return This object for method chaining. */ B addApiName(ApiName apiName); /** * Set the optional name of the higher level library that constructed the request. * * @param apiNameConsumer A {@link Consumer} that accepts a {@link ApiName.Builder}. * * @return This object for method chaining. */ B addApiName(Consumer apiNameConsumer); /** * Configure the amount of time to allow the client to complete the execution of an API call. This timeout covers the * entire client execution except for marshalling. This includes request handler execution, all HTTP requests including * retries, unmarshalling, etc. This value should always be positive, if present. * *

The api call timeout feature doesn't have strict guarantees on how quickly a request is aborted when the * timeout is breached. The typical case aborts the request within a few milliseconds but there may occasionally be * requests that don't get aborted until several seconds after the timer has been breached. Because of this, the client * execution timeout feature should not be used when absolute precision is needed. * *

This may be used together with {@link #apiCallAttemptTimeout()} to enforce both a timeout on each individual HTTP * request (i.e. each retry) and the total time spent on all requests across retries (i.e. the 'api call' time). * *

* Note that this timeout takes precedence over the value configured at client level via * {@link ClientOverrideConfiguration.Builder#apiCallTimeout(Duration)}. * * @see RequestOverrideConfiguration#apiCallTimeout() */ B apiCallTimeout(Duration apiCallTimeout); Duration apiCallTimeout(); /** * Configure the amount of time to wait for the http request to complete before giving up and timing out. This value * should always be positive, if present. * *

The request timeout feature doesn't have strict guarantees on how quickly a request is aborted when the timeout is * breached. The typical case aborts the request within a few milliseconds but there may occasionally be requests that * don't get aborted until several seconds after the timer has been breached. Because of this, the request timeout * feature should not be used when absolute precision is needed. * *

This may be used together with {@link #apiCallTimeout()} to enforce both a timeout on each individual HTTP * request (i.e. each retry) and the total time spent on all requests across retries (i.e. the 'api call' time). * *

* Note that this timeout takes precedence over the value configured at client level via * {@link ClientOverrideConfiguration.Builder#apiCallAttemptTimeout(Duration)}. * * @see RequestOverrideConfiguration#apiCallAttemptTimeout() */ B apiCallAttemptTimeout(Duration apiCallAttemptTimeout); Duration apiCallAttemptTimeout(); /** * Sets the signer to use for signing the request. This signer get priority over the signer set on the client while * signing the requests. If this value is null, then the client level signer is used for signing the request. * * @param signer Signer for signing the request * @return This object for method chaining */ B signer(Signer signer); Signer signer(); /** * Sets the metric publishers for publishing the metrics collected for this request. This list supersedes * the metric publisher set on the client. * * @param metricPublisher The list metric publisher for this request. * @return This object for method chaining. */ B metricPublishers(List metricPublisher); /** * Add a metric publisher to the existing list of previously set publishers to be used for publishing metrics * for this request. * * @param metricPublisher The metric publisher to add. */ B addMetricPublisher(MetricPublisher metricPublisher); List metricPublishers(); /** * Sets the additional execution attributes collection for this request. * @param executionAttributes Execution attributes for this request * @return This object for method chaining. */ B executionAttributes(ExecutionAttributes executionAttributes); /** * Add an execution attribute to the existing collection of execution attributes. * @param attribute The execution attribute object * @param value The value of the execution attribute. */ B putExecutionAttribute(ExecutionAttribute attribute, T value); ExecutionAttributes executionAttributes(); /** * Sets the endpointProvider to use for resolving the endpoint of the request. This endpointProvider gets priority * over the endpointProvider set on the client while resolving the endpoint for the requests. * If this value is null, then the client level endpointProvider is used for resolving the endpoint. * * @param endpointProvider Endpoint Provider that will override the resolving the endpoint for the request. * @return This object for method chaining */ B endpointProvider(EndpointProvider endpointProvider); EndpointProvider endpointProvider(); /** * Sets the {@link CompressionConfiguration} for this request. The order of precedence, from highest to lowest, * for this setting is: 1) Per request configuration 2) Client configuration 3) Environment variables 4) Profile setting. * * @param compressionConfiguration Request compression configuration object for this request. */ B compressionConfiguration(CompressionConfiguration compressionConfiguration); /** * Sets the {@link CompressionConfiguration} for this request. The order of precedence, from highest to lowest, * for this setting is: 1) Per request configuration 2) Client configuration 3) Environment variables 4) Profile setting. * * @param compressionConfigurationConsumer A {@link Consumer} that accepts a {@link CompressionConfiguration.Builder} * * @return This object for method chaining */ B compressionConfiguration(Consumer compressionConfigurationConsumer); CompressionConfiguration compressionConfiguration(); /** * Sets the plugins used to update the configuration used by this request. * * @param plugins The list of plugins for this request. * @return This object for method chaining. */ @SdkPreviewApi B plugins(List plugins); /** * Add a plugin used to update the configuration used by this request. * * @param plugin The plugin to add. */ @SdkPreviewApi B addPlugin(SdkPlugin plugin); /** * Returns the list of registered plugins */ @SdkPreviewApi List plugins(); /** * Create a new {@code SdkRequestOverrideConfiguration} with the properties set on this builder. * * @return The new {@code SdkRequestOverrideConfiguration}. */ RequestOverrideConfiguration build(); } protected abstract static class BuilderImpl implements Builder { private Map> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); private Map> rawQueryParameters = new HashMap<>(); private List apiNames = new ArrayList<>(); private Duration apiCallTimeout; private Duration apiCallAttemptTimeout; private Signer signer; private List metricPublishers = new ArrayList<>(); private ExecutionAttributes.Builder executionAttributesBuilder = ExecutionAttributes.builder(); private EndpointProvider endpointProvider; private CompressionConfiguration compressionConfiguration; private List plugins = new ArrayList<>(); protected BuilderImpl() { } protected BuilderImpl(RequestOverrideConfiguration sdkRequestOverrideConfig) { headers(sdkRequestOverrideConfig.headers); rawQueryParameters(sdkRequestOverrideConfig.rawQueryParameters); sdkRequestOverrideConfig.apiNames.forEach(this::addApiName); apiCallTimeout(sdkRequestOverrideConfig.apiCallTimeout); apiCallAttemptTimeout(sdkRequestOverrideConfig.apiCallAttemptTimeout); signer(sdkRequestOverrideConfig.signer().orElse(null)); metricPublishers(sdkRequestOverrideConfig.metricPublishers()); executionAttributes(sdkRequestOverrideConfig.executionAttributes()); endpointProvider(sdkRequestOverrideConfig.endpointProvider); compressionConfiguration(sdkRequestOverrideConfig.compressionConfiguration); plugins(sdkRequestOverrideConfig.plugins); } @Override public Map> headers() { return CollectionUtils.unmodifiableMapOfLists(headers); } @Override public B putHeader(String name, List values) { Validate.paramNotNull(values, "values"); headers.put(name, new ArrayList<>(values)); return (B) this; } @Override @SuppressWarnings("unchecked") public B headers(Map> headers) { Validate.paramNotNull(headers, "headers"); this.headers = CollectionUtils.deepCopyMap(headers); return (B) this; } @Override public Map> rawQueryParameters() { return CollectionUtils.unmodifiableMapOfLists(rawQueryParameters); } @Override public B putRawQueryParameter(String name, List values) { Validate.paramNotNull(name, "name"); Validate.paramNotNull(values, "values"); rawQueryParameters.put(name, new ArrayList<>(values)); return (B) this; } @Override @SuppressWarnings("unchecked") public B rawQueryParameters(Map> rawQueryParameters) { Validate.paramNotNull(rawQueryParameters, "rawQueryParameters"); this.rawQueryParameters = CollectionUtils.deepCopyMap(rawQueryParameters); return (B) this; } @Override public List apiNames() { return Collections.unmodifiableList(apiNames); } @Override @SuppressWarnings("unchecked") public B addApiName(ApiName apiName) { this.apiNames.add(apiName); return (B) this; } @Override @SuppressWarnings("unchecked") public B addApiName(Consumer apiNameConsumer) { ApiName.Builder b = ApiName.builder(); apiNameConsumer.accept(b); addApiName(b.build()); return (B) this; } @Override public B apiCallTimeout(Duration apiCallTimeout) { this.apiCallTimeout = apiCallTimeout; return (B) this; } public void setApiCallTimeout(Duration apiCallTimeout) { apiCallTimeout(apiCallTimeout); } @Override public Duration apiCallTimeout() { return apiCallTimeout; } @Override public B apiCallAttemptTimeout(Duration apiCallAttemptTimeout) { this.apiCallAttemptTimeout = apiCallAttemptTimeout; return (B) this; } public void setApiCallAttemptTimeout(Duration apiCallAttemptTimeout) { apiCallAttemptTimeout(apiCallAttemptTimeout); } @Override public Duration apiCallAttemptTimeout() { return apiCallAttemptTimeout; } @Override public B signer(Signer signer) { this.signer = signer; return (B) this; } public void setSigner(Signer signer) { signer(signer); } @Override public Signer signer() { return signer; } @Override public B metricPublishers(List metricPublishers) { Validate.paramNotNull(metricPublishers, "metricPublishers"); this.metricPublishers = new ArrayList<>(metricPublishers); return (B) this; } @Override public B addMetricPublisher(MetricPublisher metricPublisher) { Validate.paramNotNull(metricPublisher, "metricPublisher"); this.metricPublishers.add(metricPublisher); return (B) this; } public void setMetricPublishers(List metricPublishers) { metricPublishers(metricPublishers); } @Override public List metricPublishers() { return metricPublishers; } @Override public B executionAttributes(ExecutionAttributes executionAttributes) { Validate.paramNotNull(executionAttributes, "executionAttributes"); this.executionAttributesBuilder = executionAttributes.toBuilder(); return (B) this; } @Override public B putExecutionAttribute(ExecutionAttribute executionAttribute, T value) { this.executionAttributesBuilder.put(executionAttribute, value); return (B) this; } @Override public ExecutionAttributes executionAttributes() { return executionAttributesBuilder.build(); } public void setExecutionAttributes(ExecutionAttributes executionAttributes) { executionAttributes(executionAttributes); } @Override public B endpointProvider(EndpointProvider endpointProvider) { this.endpointProvider = endpointProvider; return (B) this; } public void setEndpointProvider(EndpointProvider endpointProvider) { endpointProvider(endpointProvider); } @Override public EndpointProvider endpointProvider() { return endpointProvider; } @Override public B compressionConfiguration(CompressionConfiguration compressionConfiguration) { this.compressionConfiguration = compressionConfiguration; return (B) this; } @Override public B compressionConfiguration(Consumer compressionConfigurationConsumer) { CompressionConfiguration.Builder b = CompressionConfiguration.builder(); compressionConfigurationConsumer.accept(b); compressionConfiguration(b.build()); return (B) this; } @Override public CompressionConfiguration compressionConfiguration() { return compressionConfiguration; } @Override public B plugins(List plugins) { this.plugins = new ArrayList<>(plugins); return (B) this; } @Override public B addPlugin(SdkPlugin plugin) { this.plugins.add(plugin); return (B) this; } @Override public List plugins() { return Collections.unmodifiableList(plugins); } } }