software.amazon.awssdk.core.RequestOverrideConfiguration Maven / Gradle / Ivy
Show all versions of sdk-core Show documentation
/*
* 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 extends 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);
}
}
}