diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java index 717b792ae793..e8b7c2557160 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java @@ -25,6 +25,7 @@ import static software.amazon.awssdk.codegen.internal.Constant.EVENT_PUBLISHER_PARAM_NAME; import static software.amazon.awssdk.codegen.poet.client.ClientClassUtils.addS3ArnableFieldCode; import static software.amazon.awssdk.codegen.poet.client.ClientClassUtils.applySignerOverrideMethod; +import static software.amazon.awssdk.codegen.poet.client.SyncClientClass.addConfigurationUpdater; import static software.amazon.awssdk.codegen.poet.client.SyncClientClass.getProtocolSpecs; import com.squareup.javapoet.ClassName; @@ -44,6 +45,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; +import java.util.function.BiFunction; import java.util.stream.Collectors; import java.util.stream.Stream; import org.reactivestreams.Publisher; @@ -70,7 +72,9 @@ import software.amazon.awssdk.codegen.poet.client.specs.ProtocolSpec; import software.amazon.awssdk.codegen.poet.eventstream.EventStreamUtils; import software.amazon.awssdk.codegen.poet.model.EventStreamSpecHelper; +import software.amazon.awssdk.codegen.poet.model.ServiceClientConfigurationUtils; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkRequest; import software.amazon.awssdk.core.async.AsyncResponseTransformer; import software.amazon.awssdk.core.async.AsyncResponseTransformerUtils; import software.amazon.awssdk.core.async.SdkPublisher; @@ -96,6 +100,7 @@ public final class AsyncClientClass extends AsyncClientInterface { private final ClassName className; private final ProtocolSpec protocolSpec; private final ClassName serviceClientConfigurationClassName; + private final ServiceClientConfigurationUtils configurationUtils; private final boolean useSraAuth; public AsyncClientClass(GeneratorTaskParams dependencies) { @@ -106,6 +111,7 @@ public AsyncClientClass(GeneratorTaskParams dependencies) { this.protocolSpec = getProtocolSpecs(poetExtensions, model); this.serviceClientConfigurationClassName = new PoetExtension(model).getServiceConfigClass(); this.useSraAuth = new AuthSchemeSpecUtils(model).useSraAuth(); + this.configurationUtils = new ServiceClientConfigurationUtils(model); } @Override @@ -140,7 +146,10 @@ protected void addFields(TypeSpec.Builder type) { .addField(AsyncClientHandler.class, "clientHandler", PRIVATE, FINAL) .addField(protocolSpec.protocolFactory(model)) .addField(SdkClientConfiguration.class, "clientConfiguration", PRIVATE, FINAL) - .addField(serviceClientConfigurationClassName, "serviceClientConfiguration", PRIVATE, FINAL); + .addField(serviceClientConfigurationClassName, "serviceClientConfiguration", PRIVATE, FINAL) + .addField(ParameterizedTypeName.get(BiFunction.class, SdkRequest.class, + SdkClientConfiguration.class, SdkClientConfiguration.class), + "clientConfigurationForRequest", PRIVATE, FINAL); // Kinesis doesn't support CBOR for STS yet so need another protocol factory for JSON if (model.getMetadata().isCborProtocol()) { @@ -210,6 +219,7 @@ private MethodSpec constructor(TypeSpec.Builder classBuilder) { .addStatement("this.clientHandler = new $T(clientConfiguration)", AwsAsyncClientHandler.class) .addStatement("this.clientConfiguration = clientConfiguration") .addStatement("this.serviceClientConfiguration = serviceClientConfiguration"); + builder.addCode(addConfigurationUpdater(configurationUtils.serviceClientConfigurationBuilderClassName())); FieldSpec protocolFactoryField = protocolSpec.protocolFactory(model); if (model.getMetadata().isJsonProtocol()) { builder.addStatement("this.$N = init($T.builder()).build()", protocolFactoryField.name, @@ -294,7 +304,8 @@ protected MethodSpec.Builder operationBody(MethodSpec.Builder builder, Operation builder.addModifiers(PUBLIC) .addAnnotation(Override.class); - + builder.addStatement("$T clientConfiguration = this.clientConfigurationForRequest.apply($L, this.clientConfiguration)", + SdkClientConfiguration.class, opModel.getInput().getVariableName()); builder.addStatement("$T<$T> metricPublishers = " + "resolveMetricPublishers(clientConfiguration, $N.overrideConfiguration().orElse(null))", List.class, diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java index cb414e0139f8..ac192df8dc42 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java @@ -24,9 +24,11 @@ import static software.amazon.awssdk.codegen.poet.client.ClientClassUtils.applySignerOverrideMethod; import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.CodeBlock; import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; import com.squareup.javapoet.WildcardTypeName; import java.net.URI; @@ -34,6 +36,7 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.function.BiFunction; import java.util.stream.Collectors; import java.util.stream.Stream; import software.amazon.awssdk.annotations.SdkInternalApi; @@ -52,9 +55,15 @@ import software.amazon.awssdk.codegen.poet.client.specs.ProtocolSpec; import software.amazon.awssdk.codegen.poet.client.specs.QueryProtocolSpec; import software.amazon.awssdk.codegen.poet.client.specs.XmlProtocolSpec; +import software.amazon.awssdk.codegen.poet.model.ServiceClientConfigurationUtils; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.SyncClientHandler; import software.amazon.awssdk.core.endpointdiscovery.EndpointDiscoveryRefreshCache; import software.amazon.awssdk.core.endpointdiscovery.EndpointDiscoveryRequest; @@ -73,6 +82,7 @@ public class SyncClientClass extends SyncClientInterface { private final ClassName className; private final ProtocolSpec protocolSpec; private final ClassName serviceClientConfigurationClassName; + private final ServiceClientConfigurationUtils configurationUtils; private final boolean useSraAuth; public SyncClientClass(GeneratorTaskParams taskParams) { @@ -82,6 +92,7 @@ public SyncClientClass(GeneratorTaskParams taskParams) { this.className = poetExtensions.getClientClass(model.getMetadata().getSyncClient()); this.protocolSpec = getProtocolSpecs(poetExtensions, model); this.serviceClientConfigurationClassName = new PoetExtension(model).getServiceConfigClass(); + this.configurationUtils = new ServiceClientConfigurationUtils(model); this.useSraAuth = new AuthSchemeSpecUtils(model).useSraAuth(); } @@ -113,7 +124,10 @@ protected void addFields(TypeSpec.Builder type) { .addField(SyncClientHandler.class, "clientHandler", PRIVATE, FINAL) .addField(protocolSpec.protocolFactory(model)) .addField(SdkClientConfiguration.class, "clientConfiguration", PRIVATE, FINAL) - .addField(serviceClientConfigurationClassName, "serviceClientConfiguration", PRIVATE, FINAL); + .addField(serviceClientConfigurationClassName, "serviceClientConfiguration", PRIVATE, FINAL) + .addField(ParameterizedTypeName.get(BiFunction.class, SdkRequest.class, + SdkClientConfiguration.class, SdkClientConfiguration.class), + "clientConfigurationForRequest", PRIVATE, FINAL); } @Override @@ -176,6 +190,8 @@ private MethodSpec constructor() { .addStatement("this.clientHandler = new $T(clientConfiguration)", protocolSpec.getClientHandlerClass()) .addStatement("this.clientConfiguration = clientConfiguration") .addStatement("this.serviceClientConfiguration = serviceClientConfiguration"); + + builder.addCode(addConfigurationUpdater(configurationUtils.serviceClientConfigurationBuilderClassName())); FieldSpec protocolFactoryField = protocolSpec.protocolFactory(model); if (model.getMetadata().isJsonProtocol()) { builder.addStatement("this.$N = init($T.builder()).build()", protocolFactoryField.name, @@ -207,6 +223,26 @@ private MethodSpec constructor() { return builder.build(); } + static CodeBlock addConfigurationUpdater(TypeName serviceClientConfigurationBuilderClassName) { + CodeBlock.Builder builder = CodeBlock.builder(); + builder.add("$T configurationUpdater = ", + ParameterizedTypeName.get(ConfigurationUpdater.class, SdkServiceClientConfiguration.Builder.class)); + builder.add("(consumer, configBuilder) -> {\n$>") + .addStatement("$1T.BuilderInternal serviceConfigBuilder = $1T.builder(configBuilder)", + serviceClientConfigurationBuilderClassName) + .addStatement("consumer.accept(serviceConfigBuilder)") + .addStatement("return serviceConfigBuilder.buildSdkClientConfiguration()") + .add("$<};\n"); + builder.add("this.clientConfigurationForRequest = (request, config) -> {\n$>"); + builder.addStatement("$T plugins = request.overrideConfiguration()\n" + + ".map(c -> c.registeredPlugins()).orElse(Collections.emptyList())", + ParameterizedTypeName.get(List.class, SdkPlugin.class)); + builder.addStatement("return $T.invokePlugins(config, plugins, configurationUpdater)", SdkClientConfigurationUtil.class); + + builder.add("$<};\n"); + return builder.build(); + } + @Override protected List operations() { return model.getOperations().values().stream() @@ -289,6 +325,8 @@ private MethodSpec traditionalMethod(OperationModel opModel) { method.endControlFlow(); } + method.addStatement("$T clientConfiguration = this.clientConfigurationForRequest.apply($L, this.clientConfiguration)", + SdkClientConfiguration.class, opModel.getInput().getVariableName()); method.addStatement("$T<$T> metricPublishers = " + "resolveMetricPublishers(clientConfiguration, $N.overrideConfiguration().orElse(null))", List.class, diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/JsonProtocolSpec.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/JsonProtocolSpec.java index 3d384ae8dfcd..5d86cfd13078 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/JsonProtocolSpec.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/JsonProtocolSpec.java @@ -187,6 +187,7 @@ public CodeBlock executionHandler(OperationModel opModel) { .add(hostPrefixExpression(opModel)) .add(discoveredEndpoint(opModel)) .add(credentialType(opModel, model)) + .add(".withRequestConfiguration(clientConfiguration)") .add(".withInput($L)\n", opModel.getInput().getVariableName()) .add(".withMetricCollector(apiCallMetricCollector)") .add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel)) @@ -259,6 +260,7 @@ public CodeBlock asyncExecutionHandler(IntermediateModel intermediateModel, Oper .add(hasInitialRequestEvent(opModel, isRestJson)) .add(".withResponseHandler($L)\n", responseHandlerName(opModel, isRestJson)) .add(".withErrorResponseHandler(errorResponseHandler)\n") + .add(".withRequestConfiguration(clientConfiguration)") .add(".withMetricCollector(apiCallMetricCollector)\n") .add(hostPrefixExpression(opModel)) .add(discoveredEndpoint(opModel)) diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/QueryProtocolSpec.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/QueryProtocolSpec.java index 101e1d9c87db..f14efae69473 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/QueryProtocolSpec.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/QueryProtocolSpec.java @@ -116,6 +116,7 @@ public CodeBlock executionHandler(OperationModel opModel) { .add(hostPrefixExpression(opModel)) .add(discoveredEndpoint(opModel)) .add(credentialType(opModel, intermediateModel)) + .add(".withRequestConfiguration(clientConfiguration)") .add(".withInput($L)", opModel.getInput().getVariableName()) .add(".withMetricCollector(apiCallMetricCollector)") .add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel)) @@ -156,6 +157,7 @@ public CodeBlock asyncExecutionHandler(IntermediateModel intermediateModel, Oper .add(".withResponseHandler(responseHandler)\n") .add(".withErrorResponseHandler(errorResponseHandler)\n") .add(credentialType(opModel, intermediateModel)) + .add(".withRequestConfiguration(clientConfiguration)") .add(".withMetricCollector(apiCallMetricCollector)\n") .add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel)) .add(HttpChecksumTrait.create(opModel)); diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/XmlProtocolSpec.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/XmlProtocolSpec.java index 2251d8e9acd8..f7092ccdaf36 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/XmlProtocolSpec.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/XmlProtocolSpec.java @@ -133,6 +133,7 @@ public CodeBlock executionHandler(OperationModel opModel) { hostPrefixExpression(opModel) + discoveredEndpoint(opModel)) .add(credentialType(opModel, model)) + .add(".withRequestConfiguration(clientConfiguration)") .add(".withInput($L)", opModel.getInput().getVariableName()) .add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel)) .add(HttpChecksumTrait.create(opModel)); @@ -198,11 +199,11 @@ public CodeBlock asyncExecutionHandler(IntermediateModel intermediateModel, Oper if (opModel.hasEventStreamOutput()) { executionResponseTransformerName = "restAsyncResponseTransformer"; } - builder.add("\n\n$T<$T> executeFuture = clientHandler.execute(new $T<$T, $T>()\n", CompletableFuture.class, executeFutureValueType, ClientExecutionParams.class, requestType, pojoResponseType) .add(".withOperationName(\"$N\")\n", opModel.getOperationName()) + .add(".withRequestConfiguration(clientConfiguration)") .add(".withMarshaller($L)\n", asyncMarshaller(intermediateModel, opModel, marshaller, "protocolFactory")); if (opModel.hasEventStreamOutput()) { diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ServiceClientConfigurationUtils.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ServiceClientConfigurationUtils.java index 47c6935e532a..87febd8c8af2 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ServiceClientConfigurationUtils.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ServiceClientConfigurationUtils.java @@ -38,6 +38,7 @@ import software.amazon.awssdk.http.auth.spi.scheme.AuthSchemeProvider; import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity; import software.amazon.awssdk.identity.spi.IdentityProvider; +import software.amazon.awssdk.identity.spi.IdentityProviders; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.utils.Validate; @@ -102,14 +103,7 @@ private static List baseServiceClientConfigurationFields() { .optionClass(AwsClientOption.class) .optionValue(AwsClientOption.AWS_REGION) .build(), - Field.builder("credentialsProvider", - ParameterizedTypeName.get(ClassName.get(IdentityProvider.class), - WildcardTypeName.subtypeOf(AwsCredentialsIdentity.class))) - .doc("credentials provider") - .definingClass(AwsServiceClientConfiguration.class) - .optionClass(AwsClientOption.class) - .optionValue(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER) - .build() + credentialsProviderField() ); } @@ -143,6 +137,55 @@ SdkClientOption.class, fieldName(SdkClientOption.ENDPOINT_OVERRIDDEN, SdkClientO return builder.build(); } + private static Field credentialsProviderField() { + Field.Builder builder = Field.builder("credentialsProvider", + ParameterizedTypeName.get(ClassName.get(IdentityProvider.class), + WildcardTypeName.subtypeOf(AwsCredentialsIdentity.class))) + .doc("credentials provider") + .definingClass(AwsServiceClientConfiguration.class); + + builder.constructFromConfiguration( + CodeBlock.builder() + .addStatement("this.credentialsProvider = internalBuilder.option($T.$L)", + AwsClientOption.class, fieldName(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER, + AwsClientOption.class)) + .build() + ); + + builder.copyToConfiguration( + // TODO(sra-plugins) + // This code duplicates the logic here + // https://github.com/aws/aws-sdk-java-v2/blob/fa9dbcce47637486e3f7d4d366ab6509b535342a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java#L212 + // That adds the credentialsProvider to the identityProviders class. This is for request level plugins, + // to be able to support credentialsProvider overrides. + CodeBlock.builder() + .beginControlFlow("if (credentialsProvider != null &&" + + " !credentialsProvider.equals(internalBuilder.option($T.$L)))", + AwsClientOption.class, fieldName(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER, + AwsClientOption.class)) + .addStatement("internalBuilder.option($T.$L, credentialsProvider)", + AwsClientOption.class, fieldName(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER, + AwsClientOption.class)) + .addStatement("$T identityProviders = internalBuilder.option($T.$L)", + IdentityProviders.class, SdkClientOption.class, + fieldName(SdkClientOption.IDENTITY_PROVIDERS, SdkClientOption.class)) + .beginControlFlow("if (identityProviders == null)") + .addStatement("identityProviders = $T.builder().putIdentityProvider(credentialsProvider).build()", + IdentityProviders.class) + .nextControlFlow(" else ") + .addStatement("identityProviders = identityProviders.toBuilder()" + + ".putIdentityProvider(credentialsProvider)" + + ".build()") + .endControlFlow() + .addStatement("internalBuilder.option($T.$L, identityProviders)", + SdkClientOption.class, fieldName(SdkClientOption.IDENTITY_PROVIDERS, SdkClientOption.class)) + .endControlFlow() + .build() + ); + + return builder.build(); + } + private static Field overrideConfigurationField() { Field.Builder builder = Field.builder("overrideConfiguration", ClientOverrideConfiguration.class) .doc("client override configuration") @@ -324,11 +367,11 @@ public Field build() { *
      * fieldName(AwsClientOption.AWS_REGION, AwsClientOption.class)
      * 
- * it will return the string "AWS_REGION" that we can use for codegen. - * Using the value directly avoid typo bugs and allows the compiler and the IDE to know about this relationship. + * it will return the string "AWS_REGION" that we can use for codegen. Using the value directly avoid typo bugs and allows the + * compiler and the IDE to know about this relationship. *

- * This method uses the fully qualified names in the reflection package to avoid polluting this class imports. - * Adapted from https://stackoverflow.com/a/35416606 + * This method uses the fully qualified names in the reflection package to avoid polluting this class imports. Adapted from + * https://stackoverflow.com/a/35416606 */ private static String fieldName(Object fieldObject, Class parent) { java.lang.reflect.Field[] allFields = parent.getFields(); diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-aws-json-async-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-aws-json-async-client-class.java index c4b21ecaed97..9517d034866b 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-aws-json-async-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-aws-json-async-client-class.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import java.util.function.BiFunction; import org.reactivestreams.Publisher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,8 +20,11 @@ import software.amazon.awssdk.awscore.eventstream.EventStreamTaggedUnionPojoSupplier; import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; import software.amazon.awssdk.core.SdkPojoBuilder; +import software.amazon.awssdk.core.SdkRequest; import software.amazon.awssdk.core.SdkResponse; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.async.AsyncRequestBody; import software.amazon.awssdk.core.async.AsyncResponseTransformer; import software.amazon.awssdk.core.async.AsyncResponseTransformerUtils; @@ -28,6 +32,8 @@ import software.amazon.awssdk.core.client.config.SdkAdvancedAsyncClientOption; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.AsyncClientHandler; import software.amazon.awssdk.core.client.handler.AttachHttpMetadataResponseHandler; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; @@ -46,6 +52,7 @@ import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.JsonOperationMetadata; +import software.amazon.awssdk.services.json.internal.JsonServiceClientConfigurationBuilder; import software.amazon.awssdk.services.json.model.APostOperationRequest; import software.amazon.awssdk.services.json.model.APostOperationResponse; import software.amazon.awssdk.services.json.model.APostOperationWithOutputRequest; @@ -123,6 +130,8 @@ final class DefaultJsonAsyncClient implements JsonAsyncClient { private final JsonServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + private final Executor executor; protected DefaultJsonAsyncClient(JsonServiceClientConfiguration serviceClientConfiguration, @@ -130,6 +139,17 @@ protected DefaultJsonAsyncClient(JsonServiceClientConfiguration serviceClientCon this.clientHandler = new AwsAsyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + JsonServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = JsonServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(AwsJsonProtocolFactory.builder()).build(); this.executor = clientConfiguration.option(SdkAdvancedAsyncClientOption.FUTURE_COMPLETION_EXECUTOR); } @@ -164,6 +184,8 @@ public JsonUtilities utilities() { */ @Override public CompletableFuture aPostOperation(APostOperationRequest aPostOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -189,8 +211,8 @@ public CompletableFuture aPostOperation(APostOperationRe .withOperationName("APostOperation") .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).hostPrefixExpression(resolvedHostExpression) - .withInput(aPostOperationRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .hostPrefixExpression(resolvedHostExpression).withInput(aPostOperationRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -229,6 +251,8 @@ public CompletableFuture aPostOperation(APostOperationRe @Override public CompletableFuture aPostOperationWithOutput( APostOperationWithOutputRequest aPostOperationWithOutputRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationWithOutputRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationWithOutputRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -250,7 +274,8 @@ public CompletableFuture aPostOperationWithOut .withOperationName("APostOperationWithOutput") .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(aPostOperationWithOutputRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(aPostOperationWithOutputRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -284,6 +309,8 @@ public CompletableFuture aPostOperationWithOut @Override public CompletableFuture eventStreamOperation(EventStreamOperationRequest eventStreamOperationRequest, Publisher requestStream, EventStreamOperationResponseHandler asyncResponseHandler) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(eventStreamOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, eventStreamOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -328,8 +355,9 @@ public CompletableFuture eventStreamOperation(EventStreamOperationRequest .withMarshaller(new EventStreamOperationRequestMarshaller(protocolFactory)) .withAsyncRequestBody(AsyncRequestBody.fromPublisher(adapted)).withFullDuplex(true) .withInitialRequestEvent(true).withResponseHandler(voidResponseHandler) - .withErrorResponseHandler(errorResponseHandler).withMetricCollector(apiCallMetricCollector) - .withInput(eventStreamOperationRequest), asyncResponseTransformer); + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector).withInput(eventStreamOperationRequest), + asyncResponseTransformer); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { try { @@ -374,6 +402,8 @@ public CompletableFuture eventStreamOperation(EventStreamOperationRequest public CompletableFuture eventStreamOperationWithOnlyInput( EventStreamOperationWithOnlyInputRequest eventStreamOperationWithOnlyInputRequest, Publisher requestStream) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + eventStreamOperationWithOnlyInputRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, eventStreamOperationWithOnlyInputRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -402,7 +432,8 @@ public CompletableFuture eventStreamO .withMarshaller(new EventStreamOperationWithOnlyInputRequestMarshaller(protocolFactory)) .withAsyncRequestBody(AsyncRequestBody.fromPublisher(adapted)).withInitialRequestEvent(true) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(eventStreamOperationWithOnlyInputRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(eventStreamOperationWithOnlyInputRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -438,6 +469,8 @@ public CompletableFuture eventStreamO public CompletableFuture eventStreamOperationWithOnlyOutput( EventStreamOperationWithOnlyOutputRequest eventStreamOperationWithOnlyOutputRequest, EventStreamOperationWithOnlyOutputResponseHandler asyncResponseHandler) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + eventStreamOperationWithOnlyOutputRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, eventStreamOperationWithOnlyOutputRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -476,8 +509,8 @@ public CompletableFuture eventStreamOperationWithOnlyOutput( .withOperationName("EventStreamOperationWithOnlyOutput") .withMarshaller(new EventStreamOperationWithOnlyOutputRequestMarshaller(protocolFactory)) .withResponseHandler(voidResponseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(eventStreamOperationWithOnlyOutputRequest), - asyncResponseTransformer); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(eventStreamOperationWithOnlyOutputRequest), asyncResponseTransformer); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { try { @@ -524,6 +557,8 @@ public CompletableFuture eventStreamOperationWithOnlyOutput( @Override public CompletableFuture getWithoutRequiredMembers( GetWithoutRequiredMembersRequest getWithoutRequiredMembersRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getWithoutRequiredMembersRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getWithoutRequiredMembersRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -545,7 +580,8 @@ public CompletableFuture getWithoutRequiredMe .withOperationName("GetWithoutRequiredMembers") .withMarshaller(new GetWithoutRequiredMembersRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(getWithoutRequiredMembersRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(getWithoutRequiredMembersRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -580,6 +616,8 @@ public CompletableFuture getWithoutRequiredMe @Override public CompletableFuture operationWithChecksumRequired( OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithChecksumRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -602,6 +640,7 @@ public CompletableFuture operationWithChe .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withMetricCollector(apiCallMetricCollector) .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, HttpChecksumRequired.create()).withInput(operationWithChecksumRequiredRequest)); @@ -638,6 +677,8 @@ public CompletableFuture operationWithChe @Override public CompletableFuture operationWithNoneAuthType( OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(operationWithNoneAuthTypeRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithNoneAuthTypeRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -659,7 +700,7 @@ public CompletableFuture operationWithNoneAut .withOperationName("OperationWithNoneAuthType") .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) .withInput(operationWithNoneAuthTypeRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -694,33 +735,36 @@ public CompletableFuture operationWithNoneAut */ @Override public CompletableFuture operationWithRequestCompression( - OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithRequestCompressionRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); + operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithRequestCompression"); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - operationMetadata, OperationWithRequestCompressionResponse::builder); + operationMetadata, OperationWithRequestCompressionResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithRequestCompression") - .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, - RequestCompression.builder().encodings("gzip").isStreaming(false).build()) - .withInput(operationWithRequestCompressionRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithRequestCompression") + .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, + RequestCompression.builder().encodings("gzip").isStreaming(false).build()) + .withInput(operationWithRequestCompressionRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -755,6 +799,8 @@ public CompletableFuture operationWithR @Override public CompletableFuture paginatedOperationWithResultKey( PaginatedOperationWithResultKeyRequest paginatedOperationWithResultKeyRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + paginatedOperationWithResultKeyRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, paginatedOperationWithResultKeyRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -776,7 +822,8 @@ public CompletableFuture paginatedOpera .withOperationName("PaginatedOperationWithResultKey") .withMarshaller(new PaginatedOperationWithResultKeyRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(paginatedOperationWithResultKeyRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(paginatedOperationWithResultKeyRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -811,6 +858,8 @@ public CompletableFuture paginatedOpera @Override public CompletableFuture paginatedOperationWithoutResultKey( PaginatedOperationWithoutResultKeyRequest paginatedOperationWithoutResultKeyRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + paginatedOperationWithoutResultKeyRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, paginatedOperationWithoutResultKeyRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -832,7 +881,8 @@ public CompletableFuture paginatedOp .withOperationName("PaginatedOperationWithoutResultKey") .withMarshaller(new PaginatedOperationWithoutResultKeyRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(paginatedOperationWithoutResultKeyRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(paginatedOperationWithoutResultKeyRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -871,6 +921,8 @@ public CompletableFuture paginatedOp @Override public CompletableFuture streamingInputOperation( StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingInputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -894,8 +946,9 @@ public CompletableFuture streamingInputOperatio AsyncStreamingRequestMarshaller.builder() .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) .asyncRequestBody(requestBody).build()).withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withMetricCollector(apiCallMetricCollector) - .withAsyncRequestBody(requestBody).withInput(streamingInputOperationRequest)); + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector).withAsyncRequestBody(requestBody) + .withInput(streamingInputOperationRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -940,6 +993,8 @@ public CompletableFuture streamingInputOperatio public CompletableFuture streamingInputOutputOperation( StreamingInputOutputOperationRequest streamingInputOutputOperationRequest, AsyncRequestBody requestBody, AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + streamingInputOutputOperationRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOutputOperationRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -970,8 +1025,9 @@ public CompletableFuture streamingInputOutputOperation( new StreamingInputOutputOperationRequestMarshaller(protocolFactory)) .asyncRequestBody(requestBody).transferEncoding(true).build()) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withAsyncRequestBody(requestBody) - .withInput(streamingInputOutputOperationRequest), asyncResponseTransformer); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withAsyncRequestBody(requestBody).withInput(streamingInputOutputOperationRequest), + asyncResponseTransformer); AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { @@ -1021,6 +1077,8 @@ public CompletableFuture streamingInputOutputOperation( public CompletableFuture streamingOutputOperation( StreamingOutputOperationRequest streamingOutputOperationRequest, AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingOutputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingOutputOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -1046,8 +1104,8 @@ public CompletableFuture streamingOutputOperation( .withOperationName("StreamingOutputOperation") .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(streamingOutputOperationRequest), - asyncResponseTransformer); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(streamingOutputOperationRequest), asyncResponseTransformer); AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-json-async-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-json-async-client-class.java index 659ab1ef9683..7510d000981d 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-json-async-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-json-async-client-class.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import java.util.function.BiFunction; import org.reactivestreams.Publisher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,8 +22,11 @@ import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.CredentialType; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; import software.amazon.awssdk.core.SdkPojoBuilder; +import software.amazon.awssdk.core.SdkRequest; import software.amazon.awssdk.core.SdkResponse; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.async.AsyncRequestBody; import software.amazon.awssdk.core.async.AsyncResponseTransformer; import software.amazon.awssdk.core.async.AsyncResponseTransformerUtils; @@ -30,6 +34,8 @@ import software.amazon.awssdk.core.client.config.SdkAdvancedAsyncClientOption; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.AsyncClientHandler; import software.amazon.awssdk.core.client.handler.AttachHttpMetadataResponseHandler; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; @@ -49,6 +55,7 @@ import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.JsonOperationMetadata; +import software.amazon.awssdk.services.json.internal.JsonServiceClientConfigurationBuilder; import software.amazon.awssdk.services.json.model.APostOperationRequest; import software.amazon.awssdk.services.json.model.APostOperationResponse; import software.amazon.awssdk.services.json.model.APostOperationWithOutputRequest; @@ -131,6 +138,8 @@ final class DefaultJsonAsyncClient implements JsonAsyncClient { private final JsonServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + private final Executor executor; protected DefaultJsonAsyncClient(JsonServiceClientConfiguration serviceClientConfiguration, @@ -138,6 +147,17 @@ protected DefaultJsonAsyncClient(JsonServiceClientConfiguration serviceClientCon this.clientHandler = new AwsAsyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + JsonServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = JsonServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(AwsJsonProtocolFactory.builder()).build(); this.executor = clientConfiguration.option(SdkAdvancedAsyncClientOption.FUTURE_COMPLETION_EXECUTOR); } @@ -172,6 +192,8 @@ public JsonUtilities utilities() { */ @Override public CompletableFuture aPostOperation(APostOperationRequest aPostOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -197,8 +219,8 @@ public CompletableFuture aPostOperation(APostOperationRe .withOperationName("APostOperation") .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).hostPrefixExpression(resolvedHostExpression) - .withInput(aPostOperationRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .hostPrefixExpression(resolvedHostExpression).withInput(aPostOperationRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -236,6 +258,8 @@ public CompletableFuture aPostOperation(APostOperationRe @Override public CompletableFuture aPostOperationWithOutput( APostOperationWithOutputRequest aPostOperationWithOutputRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationWithOutputRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationWithOutputRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -257,7 +281,8 @@ public CompletableFuture aPostOperationWithOut .withOperationName("APostOperationWithOutput") .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(aPostOperationWithOutputRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(aPostOperationWithOutputRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -291,6 +316,8 @@ public CompletableFuture aPostOperationWithOut @Override public CompletableFuture bearerAuthOperation( BearerAuthOperationRequest bearerAuthOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(bearerAuthOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, bearerAuthOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -312,8 +339,8 @@ public CompletableFuture bearerAuthOperation( .withOperationName("BearerAuthOperation") .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).credentialType(CredentialType.TOKEN) - .withInput(bearerAuthOperationRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .credentialType(CredentialType.TOKEN).withInput(bearerAuthOperationRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -347,6 +374,8 @@ public CompletableFuture bearerAuthOperation( @Override public CompletableFuture eventStreamOperation(EventStreamOperationRequest eventStreamOperationRequest, Publisher requestStream, EventStreamOperationResponseHandler asyncResponseHandler) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(eventStreamOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, eventStreamOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -395,8 +424,8 @@ public CompletableFuture eventStreamOperation(EventStreamOperationRequest .withMarshaller(new EventStreamOperationRequestMarshaller(protocolFactory)) .withAsyncRequestBody(AsyncRequestBody.fromPublisher(adapted)).withFullDuplex(true) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(eventStreamOperationRequest), - restAsyncResponseTransformer); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(eventStreamOperationRequest), restAsyncResponseTransformer); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { try { @@ -441,6 +470,8 @@ public CompletableFuture eventStreamOperation(EventStreamOperationRequest public CompletableFuture eventStreamOperationWithOnlyInput( EventStreamOperationWithOnlyInputRequest eventStreamOperationWithOnlyInputRequest, Publisher requestStream) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + eventStreamOperationWithOnlyInputRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, eventStreamOperationWithOnlyInputRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -468,8 +499,8 @@ public CompletableFuture eventStreamO .withOperationName("EventStreamOperationWithOnlyInput") .withMarshaller(new EventStreamOperationWithOnlyInputRequestMarshaller(protocolFactory)) .withAsyncRequestBody(AsyncRequestBody.fromPublisher(adapted)).withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withMetricCollector(apiCallMetricCollector) - .withInput(eventStreamOperationWithOnlyInputRequest)); + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector).withInput(eventStreamOperationWithOnlyInputRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -505,6 +536,8 @@ public CompletableFuture eventStreamO public CompletableFuture eventStreamOperationWithOnlyOutput( EventStreamOperationWithOnlyOutputRequest eventStreamOperationWithOnlyOutputRequest, EventStreamOperationWithOnlyOutputResponseHandler asyncResponseHandler) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + eventStreamOperationWithOnlyOutputRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, eventStreamOperationWithOnlyOutputRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -548,7 +581,7 @@ public CompletableFuture eventStreamOperationWithOnlyOutput( .withOperationName("EventStreamOperationWithOnlyOutput") .withMarshaller(new EventStreamOperationWithOnlyOutputRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) .withInput(eventStreamOperationWithOnlyOutputRequest), restAsyncResponseTransformer); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { @@ -592,6 +625,8 @@ public CompletableFuture eventStreamOperationWithOnlyOutput( @Override public CompletableFuture getOperationWithChecksum( GetOperationWithChecksumRequest getOperationWithChecksumRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getOperationWithChecksumRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -614,6 +649,7 @@ public CompletableFuture getOperationWithCheck .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withMetricCollector(apiCallMetricCollector) .putExecutionAttribute( SdkInternalExecutionAttribute.HTTP_CHECKSUM, @@ -657,6 +693,8 @@ public CompletableFuture getOperationWithCheck @Override public CompletableFuture getWithoutRequiredMembers( GetWithoutRequiredMembersRequest getWithoutRequiredMembersRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getWithoutRequiredMembersRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getWithoutRequiredMembersRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -678,7 +716,8 @@ public CompletableFuture getWithoutRequiredMe .withOperationName("GetWithoutRequiredMembers") .withMarshaller(new GetWithoutRequiredMembersRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(getWithoutRequiredMembersRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(getWithoutRequiredMembersRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -713,6 +752,8 @@ public CompletableFuture getWithoutRequiredMe @Override public CompletableFuture operationWithChecksumRequired( OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithChecksumRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -735,6 +776,7 @@ public CompletableFuture operationWithChe .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withMetricCollector(apiCallMetricCollector) .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, HttpChecksumRequired.create()).withInput(operationWithChecksumRequiredRequest)); @@ -771,33 +813,36 @@ public CompletableFuture operationWithChe */ @Override public CompletableFuture operationWithRequestCompression( - OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithRequestCompressionRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); + operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithRequestCompression"); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - operationMetadata, OperationWithRequestCompressionResponse::builder); + operationMetadata, OperationWithRequestCompressionResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithRequestCompression") - .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, - RequestCompression.builder().encodings("gzip").isStreaming(false).build()) - .withInput(operationWithRequestCompressionRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithRequestCompression") + .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, + RequestCompression.builder().encodings("gzip").isStreaming(false).build()) + .withInput(operationWithRequestCompressionRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -832,6 +877,8 @@ public CompletableFuture operationWithR @Override public CompletableFuture paginatedOperationWithResultKey( PaginatedOperationWithResultKeyRequest paginatedOperationWithResultKeyRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + paginatedOperationWithResultKeyRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, paginatedOperationWithResultKeyRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -853,7 +900,8 @@ public CompletableFuture paginatedOpera .withOperationName("PaginatedOperationWithResultKey") .withMarshaller(new PaginatedOperationWithResultKeyRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(paginatedOperationWithResultKeyRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(paginatedOperationWithResultKeyRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -888,6 +936,8 @@ public CompletableFuture paginatedOpera @Override public CompletableFuture paginatedOperationWithoutResultKey( PaginatedOperationWithoutResultKeyRequest paginatedOperationWithoutResultKeyRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + paginatedOperationWithoutResultKeyRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, paginatedOperationWithoutResultKeyRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -909,7 +959,8 @@ public CompletableFuture paginatedOp .withOperationName("PaginatedOperationWithoutResultKey") .withMarshaller(new PaginatedOperationWithoutResultKeyRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(paginatedOperationWithoutResultKeyRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(paginatedOperationWithoutResultKeyRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -962,6 +1013,8 @@ public CompletableFuture paginatedOp public CompletableFuture putOperationWithChecksum( PutOperationWithChecksumRequest putOperationWithChecksumRequest, AsyncRequestBody requestBody, AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(putOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, putOperationWithChecksumRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -991,6 +1044,7 @@ public CompletableFuture putOperationWithChecksum( .asyncRequestBody(requestBody).build()) .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withMetricCollector(apiCallMetricCollector) .withAsyncRequestBody(requestBody) .putExecutionAttribute( @@ -1047,6 +1101,8 @@ public CompletableFuture putOperationWithChecksum( @Override public CompletableFuture streamingInputOperation( StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingInputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -1070,8 +1126,9 @@ public CompletableFuture streamingInputOperatio AsyncStreamingRequestMarshaller.builder() .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) .asyncRequestBody(requestBody).build()).withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withMetricCollector(apiCallMetricCollector) - .withAsyncRequestBody(requestBody).withInput(streamingInputOperationRequest)); + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector).withAsyncRequestBody(requestBody) + .withInput(streamingInputOperationRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -1116,6 +1173,8 @@ public CompletableFuture streamingInputOperatio public CompletableFuture streamingInputOutputOperation( StreamingInputOutputOperationRequest streamingInputOutputOperationRequest, AsyncRequestBody requestBody, AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + streamingInputOutputOperationRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOutputOperationRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -1146,8 +1205,9 @@ public CompletableFuture streamingInputOutputOperation( new StreamingInputOutputOperationRequestMarshaller(protocolFactory)) .asyncRequestBody(requestBody).transferEncoding(true).build()) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withAsyncRequestBody(requestBody) - .withInput(streamingInputOutputOperationRequest), asyncResponseTransformer); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withAsyncRequestBody(requestBody).withInput(streamingInputOutputOperationRequest), + asyncResponseTransformer); AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { @@ -1197,6 +1257,8 @@ public CompletableFuture streamingInputOutputOperation( public CompletableFuture streamingOutputOperation( StreamingOutputOperationRequest streamingOutputOperationRequest, AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingOutputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingOutputOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -1222,8 +1284,8 @@ public CompletableFuture streamingOutputOperation( .withOperationName("StreamingOutputOperation") .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(streamingOutputOperationRequest), - asyncResponseTransformer); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(streamingOutputOperationRequest), asyncResponseTransformer); AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-json-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-json-client-class.java index 12b9e3a5e361..b9410edd90b3 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-json-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-json-client-class.java @@ -2,14 +2,20 @@ import java.util.Collections; import java.util.List; +import java.util.function.BiFunction; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler; import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.CredentialType; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.client.handler.SyncClientHandler; import software.amazon.awssdk.core.exception.SdkClientException; @@ -30,6 +36,7 @@ import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.JsonOperationMetadata; +import software.amazon.awssdk.services.json.internal.JsonServiceClientConfigurationBuilder; import software.amazon.awssdk.services.json.model.APostOperationRequest; import software.amazon.awssdk.services.json.model.APostOperationResponse; import software.amazon.awssdk.services.json.model.APostOperationWithOutputRequest; @@ -92,11 +99,24 @@ final class DefaultJsonClient implements JsonClient { private final JsonServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + protected DefaultJsonClient(JsonServiceClientConfiguration serviceClientConfiguration, SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsSyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + JsonServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = JsonServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(AwsJsonProtocolFactory.builder()).build(); } @@ -131,6 +151,8 @@ public APostOperationResponse aPostOperation(APostOperationRequest aPostOperatio HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -146,7 +168,8 @@ public APostOperationResponse aPostOperation(APostOperationRequest aPostOperatio return clientHandler.execute(new ClientExecutionParams() .withOperationName("APostOperation").withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler).hostPrefixExpression(resolvedHostExpression) - .withInput(aPostOperationRequest).withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration).withInput(aPostOperationRequest) + .withMetricCollector(apiCallMetricCollector) .withMarshaller(new APostOperationRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -185,6 +208,8 @@ public APostOperationWithOutputResponse aPostOperationWithOutput( HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationWithOutputRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationWithOutputRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -196,8 +221,8 @@ public APostOperationWithOutputResponse aPostOperationWithOutput( return clientHandler .execute(new ClientExecutionParams() .withOperationName("APostOperationWithOutput").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(aPostOperationWithOutputRequest) - .withMetricCollector(apiCallMetricCollector) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(aPostOperationWithOutputRequest).withMetricCollector(apiCallMetricCollector) .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -231,6 +256,8 @@ public BearerAuthOperationResponse bearerAuthOperation(BearerAuthOperationReques HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(bearerAuthOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, bearerAuthOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -242,7 +269,8 @@ public BearerAuthOperationResponse bearerAuthOperation(BearerAuthOperationReques return clientHandler.execute(new ClientExecutionParams() .withOperationName("BearerAuthOperation").withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler).credentialType(CredentialType.TOKEN) - .withInput(bearerAuthOperationRequest).withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration).withInput(bearerAuthOperationRequest) + .withMetricCollector(apiCallMetricCollector) .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -277,6 +305,8 @@ public GetOperationWithChecksumResponse getOperationWithChecksum( HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getOperationWithChecksumRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -290,6 +320,7 @@ public GetOperationWithChecksumResponse getOperationWithChecksum( .withOperationName("GetOperationWithChecksum") .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withInput(getOperationWithChecksumRequest) .withMetricCollector(apiCallMetricCollector) .putExecutionAttribute( @@ -335,6 +366,8 @@ public GetWithoutRequiredMembersResponse getWithoutRequiredMembers( HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getWithoutRequiredMembersRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getWithoutRequiredMembersRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -346,8 +379,8 @@ public GetWithoutRequiredMembersResponse getWithoutRequiredMembers( return clientHandler .execute(new ClientExecutionParams() .withOperationName("GetWithoutRequiredMembers").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(getWithoutRequiredMembersRequest) - .withMetricCollector(apiCallMetricCollector) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(getWithoutRequiredMembersRequest).withMetricCollector(apiCallMetricCollector) .withMarshaller(new GetWithoutRequiredMembersRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -382,6 +415,8 @@ public OperationWithChecksumRequiredResponse operationWithChecksumRequired( HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithChecksumRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -395,6 +430,7 @@ public OperationWithChecksumRequiredResponse operationWithChecksumRequired( .withOperationName("OperationWithChecksumRequired") .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withInput(operationWithChecksumRequiredRequest) .withMetricCollector(apiCallMetricCollector) .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, @@ -433,6 +469,8 @@ public OperationWithRequestCompressionResponse operationWithRequestCompression( HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithRequestCompressionRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -446,6 +484,7 @@ public OperationWithRequestCompressionResponse operationWithRequestCompression( .withOperationName("OperationWithRequestCompression") .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withInput(operationWithRequestCompressionRequest) .withMetricCollector(apiCallMetricCollector) .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, @@ -484,6 +523,8 @@ public PaginatedOperationWithResultKeyResponse paginatedOperationWithResultKey( HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + paginatedOperationWithResultKeyRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, paginatedOperationWithResultKeyRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -495,8 +536,8 @@ public PaginatedOperationWithResultKeyResponse paginatedOperationWithResultKey( return clientHandler .execute(new ClientExecutionParams() .withOperationName("PaginatedOperationWithResultKey").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(paginatedOperationWithResultKeyRequest) - .withMetricCollector(apiCallMetricCollector) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(paginatedOperationWithResultKeyRequest).withMetricCollector(apiCallMetricCollector) .withMarshaller(new PaginatedOperationWithResultKeyRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -531,6 +572,8 @@ public PaginatedOperationWithoutResultKeyResponse paginatedOperationWithoutResul HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + paginatedOperationWithoutResultKeyRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, paginatedOperationWithoutResultKeyRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -542,8 +585,8 @@ public PaginatedOperationWithoutResultKeyResponse paginatedOperationWithoutResul return clientHandler .execute(new ClientExecutionParams() .withOperationName("PaginatedOperationWithoutResultKey").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(paginatedOperationWithoutResultKeyRequest) - .withMetricCollector(apiCallMetricCollector) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(paginatedOperationWithoutResultKeyRequest).withMetricCollector(apiCallMetricCollector) .withMarshaller(new PaginatedOperationWithoutResultKeyRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -604,6 +647,8 @@ public ReturnT putOperationWithChecksum(PutOperationWithChecksumReques HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(putOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, putOperationWithChecksumRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -617,6 +662,7 @@ public ReturnT putOperationWithChecksum(PutOperationWithChecksumReques .withOperationName("PutOperationWithChecksum") .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withInput(putOperationWithChecksumRequest) .withMetricCollector(apiCallMetricCollector) .putExecutionAttribute( @@ -673,6 +719,8 @@ public StreamingInputOperationResponse streamingInputOperation(StreamingInputOpe HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingInputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -686,6 +734,7 @@ public StreamingInputOperationResponse streamingInputOperation(StreamingInputOpe .withOperationName("StreamingInputOperation") .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withInput(streamingInputOperationRequest) .withMetricCollector(apiCallMetricCollector) .withRequestBody(requestBody) @@ -745,6 +794,8 @@ public ReturnT streamingInputOutputOperation( HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + streamingInputOutputOperationRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOutputOperationRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -758,6 +809,7 @@ public ReturnT streamingInputOutputOperation( .withOperationName("StreamingInputOutputOperation") .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withInput(streamingInputOutputOperationRequest) .withMetricCollector(apiCallMetricCollector) .withRequestBody(requestBody) @@ -807,6 +859,8 @@ public ReturnT streamingOutputOperation(StreamingOutputOperationReques HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingOutputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingOutputOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -818,8 +872,8 @@ public ReturnT streamingOutputOperation(StreamingOutputOperationReques return clientHandler.execute( new ClientExecutionParams() .withOperationName("StreamingOutputOperation").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(streamingOutputOperationRequest) - .withMetricCollector(apiCallMetricCollector) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(streamingOutputOperationRequest).withMetricCollector(apiCallMetricCollector) .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)), responseTransformer); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-query-async-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-query-async-client-class.java index 71e16131bcf7..fba49727169b 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-query-async-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-query-async-client-class.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ScheduledExecutorService; +import java.util.function.BiFunction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.annotations.Generated; @@ -14,11 +15,16 @@ import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.CredentialType; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.async.AsyncRequestBody; import software.amazon.awssdk.core.async.AsyncResponseTransformer; import software.amazon.awssdk.core.async.AsyncResponseTransformerUtils; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.AsyncClientHandler; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.http.HttpResponseHandler; @@ -33,6 +39,7 @@ import software.amazon.awssdk.metrics.NoOpMetricCollector; import software.amazon.awssdk.protocols.core.ExceptionMetadata; import software.amazon.awssdk.protocols.query.AwsQueryProtocolFactory; +import software.amazon.awssdk.services.query.internal.QueryServiceClientConfigurationBuilder; import software.amazon.awssdk.services.query.model.APostOperationRequest; import software.amazon.awssdk.services.query.model.APostOperationResponse; import software.amazon.awssdk.services.query.model.APostOperationWithOutputRequest; @@ -93,13 +100,26 @@ final class DefaultQueryAsyncClient implements QueryAsyncClient { private final QueryServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + private final ScheduledExecutorService executorService; protected DefaultQueryAsyncClient(QueryServiceClientConfiguration serviceClientConfiguration, - SdkClientConfiguration clientConfiguration) { + SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsAsyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + QueryServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = QueryServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(); this.executorService = clientConfiguration.option(SdkClientOption.SCHEDULED_EXECUTOR_SERVICE); } @@ -129,28 +149,30 @@ protected DefaultQueryAsyncClient(QueryServiceClientConfiguration serviceClientC */ @Override public CompletableFuture aPostOperation(APostOperationRequest aPostOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperation"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(APostOperationResponse::builder); + .createResponseHandler(APostOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); String hostPrefix = "foo-"; String resolvedHostExpression = "foo-"; CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("APostOperation") - .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).hostPrefixExpression(resolvedHostExpression) - .withInput(aPostOperationRequest)); + .execute(new ClientExecutionParams() + .withOperationName("APostOperation") + .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .hostPrefixExpression(resolvedHostExpression).withInput(aPostOperationRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -187,26 +209,29 @@ public CompletableFuture aPostOperation(APostOperationRe */ @Override public CompletableFuture aPostOperationWithOutput( - APostOperationWithOutputRequest aPostOperationWithOutputRequest) { + APostOperationWithOutputRequest aPostOperationWithOutputRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationWithOutputRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationWithOutputRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperationWithOutput"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(APostOperationWithOutputResponse::builder); + .createResponseHandler(APostOperationWithOutputResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("APostOperationWithOutput") - .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(aPostOperationWithOutputRequest)); + .execute(new ClientExecutionParams() + .withOperationName("APostOperationWithOutput") + .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(aPostOperationWithOutputRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -239,27 +264,29 @@ public CompletableFuture aPostOperationWithOut */ @Override public CompletableFuture bearerAuthOperation( - BearerAuthOperationRequest bearerAuthOperationRequest) { + BearerAuthOperationRequest bearerAuthOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(bearerAuthOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, bearerAuthOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "BearerAuthOperation"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(BearerAuthOperationResponse::builder); + .createResponseHandler(BearerAuthOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("BearerAuthOperation") - .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .credentialType(CredentialType.TOKEN).withMetricCollector(apiCallMetricCollector) - .withInput(bearerAuthOperationRequest)); + .execute(new ClientExecutionParams() + .withOperationName("BearerAuthOperation") + .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .credentialType(CredentialType.TOKEN).withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector).withInput(bearerAuthOperationRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -292,32 +319,35 @@ public CompletableFuture bearerAuthOperation( */ @Override public CompletableFuture getOperationWithChecksum( - GetOperationWithChecksumRequest getOperationWithChecksumRequest) { + GetOperationWithChecksumRequest getOperationWithChecksumRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "GetOperationWithChecksum"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(GetOperationWithChecksumResponse::builder); + .createResponseHandler(GetOperationWithChecksumResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("GetOperationWithChecksum") - .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(true) - .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) - .isRequestStreaming(false).build()).withInput(getOperationWithChecksumRequest)); + .execute(new ClientExecutionParams() + .withOperationName("GetOperationWithChecksum") + .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(true) + .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) + .isRequestStreaming(false).build()).withInput(getOperationWithChecksumRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -351,29 +381,32 @@ public CompletableFuture getOperationWithCheck */ @Override public CompletableFuture operationWithChecksumRequired( - OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) { + OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithChecksumRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); + operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithChecksumRequired"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithChecksumRequiredResponse::builder); + .createResponseHandler(OperationWithChecksumRequiredResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithChecksumRequired") - .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, - HttpChecksumRequired.create()).withInput(operationWithChecksumRequiredRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithChecksumRequired") + .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, + HttpChecksumRequired.create()).withInput(operationWithChecksumRequiredRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -406,26 +439,29 @@ public CompletableFuture operationWithChe */ @Override public CompletableFuture operationWithContextParam( - OperationWithContextParamRequest operationWithContextParamRequest) { + OperationWithContextParamRequest operationWithContextParamRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(operationWithContextParamRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithContextParamRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithContextParam"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithContextParamResponse::builder); + .createResponseHandler(OperationWithContextParamResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithContextParam") - .withMarshaller(new OperationWithContextParamRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(operationWithContextParamRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithContextParam") + .withMarshaller(new OperationWithContextParamRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(operationWithContextParamRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -458,27 +494,29 @@ public CompletableFuture operationWithContext */ @Override public CompletableFuture operationWithNoneAuthType( - OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) { + OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(operationWithNoneAuthTypeRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithNoneAuthTypeRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithNoneAuthType"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithNoneAuthTypeResponse::builder); + .createResponseHandler(OperationWithNoneAuthTypeResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithNoneAuthType") - .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .withInput(operationWithNoneAuthTypeRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithNoneAuthType") + .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(operationWithNoneAuthTypeRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -512,30 +550,33 @@ public CompletableFuture operationWithNoneAut */ @Override public CompletableFuture operationWithRequestCompression( - OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithRequestCompressionRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); + operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithRequestCompression"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithRequestCompressionResponse::builder); + .createResponseHandler(OperationWithRequestCompressionResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithRequestCompression") - .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, - RequestCompression.builder().encodings("gzip").isStreaming(false).build()) - .withInput(operationWithRequestCompressionRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithRequestCompression") + .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, + RequestCompression.builder().encodings("gzip").isStreaming(false).build()) + .withInput(operationWithRequestCompressionRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -569,26 +610,29 @@ public CompletableFuture operationWithR */ @Override public CompletableFuture operationWithStaticContextParams( - OperationWithStaticContextParamsRequest operationWithStaticContextParamsRequest) { + OperationWithStaticContextParamsRequest operationWithStaticContextParamsRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithStaticContextParamsRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithStaticContextParamsRequest.overrideConfiguration().orElse(null)); + operationWithStaticContextParamsRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithStaticContextParams"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithStaticContextParamsResponse::builder); + .createResponseHandler(OperationWithStaticContextParamsResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithStaticContextParams") - .withMarshaller(new OperationWithStaticContextParamsRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(operationWithStaticContextParamsRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithStaticContextParams") + .withMarshaller(new OperationWithStaticContextParamsRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(operationWithStaticContextParamsRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -639,48 +683,51 @@ public CompletableFuture operationWith */ @Override public CompletableFuture putOperationWithChecksum( - PutOperationWithChecksumRequest putOperationWithChecksumRequest, AsyncRequestBody requestBody, - AsyncResponseTransformer asyncResponseTransformer) { + PutOperationWithChecksumRequest putOperationWithChecksumRequest, AsyncRequestBody requestBody, + AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(putOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, putOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "PutOperationWithChecksum"); Pair, CompletableFuture> pair = AsyncResponseTransformerUtils - .wrapWithEndOfStreamFuture(asyncResponseTransformer); + .wrapWithEndOfStreamFuture(asyncResponseTransformer); asyncResponseTransformer = pair.left(); CompletableFuture endOfStreamFuture = pair.right(); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(PutOperationWithChecksumResponse::builder); + .createResponseHandler(PutOperationWithChecksumResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler.execute( - new ClientExecutionParams() - .withOperationName("PutOperationWithChecksum") - .withMarshaller( - AsyncStreamingRequestMarshaller.builder() - .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) - .asyncRequestBody(requestBody).build()) - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(false) - .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) - .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) - .build()).withAsyncRequestBody(requestBody) - .withInput(putOperationWithChecksumRequest), asyncResponseTransformer); + new ClientExecutionParams() + .withOperationName("PutOperationWithChecksum") + .withMarshaller( + AsyncStreamingRequestMarshaller.builder() + .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) + .asyncRequestBody(requestBody).build()) + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(false) + .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) + .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) + .build()).withAsyncRequestBody(requestBody) + .withInput(putOperationWithChecksumRequest), asyncResponseTransformer); CompletableFuture whenCompleteFuture = null; AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { if (e != null) { runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(e)); + () -> finalAsyncResponseTransformer.exceptionOccurred(e)); } endOfStreamFuture.whenComplete((r2, e2) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -690,7 +737,7 @@ public CompletableFuture putOperationWithChecksum( } catch (Throwable t) { AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(t)); + () -> finalAsyncResponseTransformer.exceptionOccurred(t)); metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); return CompletableFutureUtils.failedFuture(t); } @@ -722,29 +769,32 @@ public CompletableFuture putOperationWithChecksum( */ @Override public CompletableFuture streamingInputOperation( - StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) { + StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingInputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingInputOperation"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(StreamingInputOperationResponse::builder); + .createResponseHandler(StreamingInputOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("StreamingInputOperation") - .withMarshaller( - AsyncStreamingRequestMarshaller.builder() - .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) - .asyncRequestBody(requestBody).build()).withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withMetricCollector(apiCallMetricCollector) - .withAsyncRequestBody(requestBody).withInput(streamingInputOperationRequest)); + .execute(new ClientExecutionParams() + .withOperationName("StreamingInputOperation") + .withMarshaller( + AsyncStreamingRequestMarshaller.builder() + .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) + .asyncRequestBody(requestBody).build()).withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector).withAsyncRequestBody(requestBody) + .withInput(streamingInputOperationRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -782,38 +832,40 @@ public CompletableFuture streamingInputOperatio */ @Override public CompletableFuture streamingOutputOperation( - StreamingOutputOperationRequest streamingOutputOperationRequest, - AsyncResponseTransformer asyncResponseTransformer) { + StreamingOutputOperationRequest streamingOutputOperationRequest, + AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingOutputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingOutputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingOutputOperation"); Pair, CompletableFuture> pair = AsyncResponseTransformerUtils - .wrapWithEndOfStreamFuture(asyncResponseTransformer); + .wrapWithEndOfStreamFuture(asyncResponseTransformer); asyncResponseTransformer = pair.left(); CompletableFuture endOfStreamFuture = pair.right(); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(StreamingOutputOperationResponse::builder); + .createResponseHandler(StreamingOutputOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler.execute( - new ClientExecutionParams() - .withOperationName("StreamingOutputOperation") - .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(streamingOutputOperationRequest), - asyncResponseTransformer); + new ClientExecutionParams() + .withOperationName("StreamingOutputOperation") + .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(streamingOutputOperationRequest), asyncResponseTransformer); CompletableFuture whenCompleteFuture = null; AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { if (e != null) { runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(e)); + () -> finalAsyncResponseTransformer.exceptionOccurred(e)); } endOfStreamFuture.whenComplete((r2, e2) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -823,7 +875,7 @@ public CompletableFuture streamingOutputOperation( } catch (Throwable t) { AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(t)); + () -> finalAsyncResponseTransformer.exceptionOccurred(t)); metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); return CompletableFutureUtils.failedFuture(t); } @@ -846,15 +898,15 @@ public final String serviceName() { private AwsQueryProtocolFactory init() { return AwsQueryProtocolFactory - .builder() - .registerModeledException( - ExceptionMetadata.builder().errorCode("InvalidInput") - .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) - .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(QueryException::builder).build(); + .builder() + .registerModeledException( + ExceptionMetadata.builder().errorCode("InvalidInput") + .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) + .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(QueryException::builder).build(); } private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, - RequestOverrideConfiguration requestOverrideConfiguration) { + RequestOverrideConfiguration requestOverrideConfiguration) { List publishers = null; if (requestOverrideConfiguration != null) { publishers = requestOverrideConfiguration.metricPublishers(); diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-query-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-query-client-class.java index af5838bdc34d..4a73e1921291 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-query-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-query-client-class.java @@ -2,14 +2,20 @@ import java.util.Collections; import java.util.List; +import java.util.function.BiFunction; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler; import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.CredentialType; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.client.handler.SyncClientHandler; import software.amazon.awssdk.core.exception.SdkClientException; @@ -27,6 +33,7 @@ import software.amazon.awssdk.metrics.NoOpMetricCollector; import software.amazon.awssdk.protocols.core.ExceptionMetadata; import software.amazon.awssdk.protocols.query.AwsQueryProtocolFactory; +import software.amazon.awssdk.services.query.internal.QueryServiceClientConfigurationBuilder; import software.amazon.awssdk.services.query.model.APostOperationRequest; import software.amazon.awssdk.services.query.model.APostOperationResponse; import software.amazon.awssdk.services.query.model.APostOperationWithOutputRequest; @@ -86,11 +93,24 @@ final class DefaultQueryClient implements QueryClient { private final QueryServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + protected DefaultQueryClient(QueryServiceClientConfiguration serviceClientConfiguration, - SdkClientConfiguration clientConfiguration) { + SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsSyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + QueryServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = QueryServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(); } @@ -116,16 +136,18 @@ protected DefaultQueryClient(QueryServiceClientConfiguration serviceClientConfig */ @Override public APostOperationResponse aPostOperation(APostOperationRequest aPostOperationRequest) throws InvalidInputException, - AwsServiceException, SdkClientException, QueryException { + AwsServiceException, SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(APostOperationResponse::builder); + .createResponseHandler(APostOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperation"); @@ -133,10 +155,11 @@ public APostOperationResponse aPostOperation(APostOperationRequest aPostOperatio String resolvedHostExpression = "foo-"; return clientHandler.execute(new ClientExecutionParams() - .withOperationName("APostOperation").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).hostPrefixExpression(resolvedHostExpression) - .withInput(aPostOperationRequest).withMetricCollector(apiCallMetricCollector) - .withMarshaller(new APostOperationRequestMarshaller(protocolFactory))); + .withOperationName("APostOperation").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).hostPrefixExpression(resolvedHostExpression) + .withRequestConfiguration(clientConfiguration).withInput(aPostOperationRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new APostOperationRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -164,27 +187,29 @@ public APostOperationResponse aPostOperation(APostOperationRequest aPostOperatio */ @Override public APostOperationWithOutputResponse aPostOperationWithOutput( - APostOperationWithOutputRequest aPostOperationWithOutputRequest) throws InvalidInputException, AwsServiceException, - SdkClientException, QueryException { + APostOperationWithOutputRequest aPostOperationWithOutputRequest) throws InvalidInputException, AwsServiceException, + SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(APostOperationWithOutputResponse::builder); + .createResponseHandler(APostOperationWithOutputResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationWithOutputRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationWithOutputRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperationWithOutput"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("APostOperationWithOutput").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(aPostOperationWithOutputRequest) - .withMetricCollector(apiCallMetricCollector) - .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("APostOperationWithOutput").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(aPostOperationWithOutputRequest).withMetricCollector(apiCallMetricCollector) + .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -208,25 +233,28 @@ public APostOperationWithOutputResponse aPostOperationWithOutput( */ @Override public BearerAuthOperationResponse bearerAuthOperation(BearerAuthOperationRequest bearerAuthOperationRequest) - throws AwsServiceException, SdkClientException, QueryException { + throws AwsServiceException, SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(BearerAuthOperationResponse::builder); + .createResponseHandler(BearerAuthOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(bearerAuthOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, bearerAuthOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "BearerAuthOperation"); return clientHandler.execute(new ClientExecutionParams() - .withOperationName("BearerAuthOperation").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).credentialType(CredentialType.TOKEN) - .withInput(bearerAuthOperationRequest).withMetricCollector(apiCallMetricCollector) - .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory))); + .withOperationName("BearerAuthOperation").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).credentialType(CredentialType.TOKEN) + .withRequestConfiguration(clientConfiguration).withInput(bearerAuthOperationRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -250,34 +278,37 @@ public BearerAuthOperationResponse bearerAuthOperation(BearerAuthOperationReques */ @Override public GetOperationWithChecksumResponse getOperationWithChecksum( - GetOperationWithChecksumRequest getOperationWithChecksumRequest) throws AwsServiceException, SdkClientException, - QueryException { + GetOperationWithChecksumRequest getOperationWithChecksumRequest) throws AwsServiceException, SdkClientException, + QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(GetOperationWithChecksumResponse::builder); + .createResponseHandler(GetOperationWithChecksumResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "GetOperationWithChecksum"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("GetOperationWithChecksum") - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withInput(getOperationWithChecksumRequest) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(true) - .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) - .isRequestStreaming(false).build()) - .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("GetOperationWithChecksum") + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withInput(getOperationWithChecksumRequest) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(true) + .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) + .isRequestStreaming(false).build()) + .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -301,31 +332,34 @@ public GetOperationWithChecksumResponse getOperationWithChecksum( */ @Override public OperationWithChecksumRequiredResponse operationWithChecksumRequired( - OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) throws AwsServiceException, - SdkClientException, QueryException { + OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) throws AwsServiceException, + SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithChecksumRequiredResponse::builder); + .createResponseHandler(OperationWithChecksumRequiredResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithChecksumRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); + operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithChecksumRequired"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithChecksumRequired") - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withInput(operationWithChecksumRequiredRequest) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, - HttpChecksumRequired.create()) - .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithChecksumRequired") + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withInput(operationWithChecksumRequiredRequest) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, + HttpChecksumRequired.create()) + .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -349,27 +383,29 @@ public OperationWithChecksumRequiredResponse operationWithChecksumRequired( */ @Override public OperationWithContextParamResponse operationWithContextParam( - OperationWithContextParamRequest operationWithContextParamRequest) throws AwsServiceException, SdkClientException, - QueryException { + OperationWithContextParamRequest operationWithContextParamRequest) throws AwsServiceException, SdkClientException, + QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithContextParamResponse::builder); + .createResponseHandler(OperationWithContextParamResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(operationWithContextParamRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithContextParamRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithContextParam"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithContextParam").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(operationWithContextParamRequest) - .withMetricCollector(apiCallMetricCollector) - .withMarshaller(new OperationWithContextParamRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithContextParam").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(operationWithContextParamRequest).withMetricCollector(apiCallMetricCollector) + .withMarshaller(new OperationWithContextParamRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -393,27 +429,29 @@ public OperationWithContextParamResponse operationWithContextParam( */ @Override public OperationWithNoneAuthTypeResponse operationWithNoneAuthType( - OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) throws AwsServiceException, SdkClientException, - QueryException { + OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) throws AwsServiceException, SdkClientException, + QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithNoneAuthTypeResponse::builder); + .createResponseHandler(OperationWithNoneAuthTypeResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(operationWithNoneAuthTypeRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithNoneAuthTypeRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithNoneAuthType"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithNoneAuthType").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(operationWithNoneAuthTypeRequest) - .withMetricCollector(apiCallMetricCollector) - .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithNoneAuthType").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(operationWithNoneAuthTypeRequest).withMetricCollector(apiCallMetricCollector) + .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -437,31 +475,34 @@ public OperationWithNoneAuthTypeResponse operationWithNoneAuthType( */ @Override public OperationWithRequestCompressionResponse operationWithRequestCompression( - OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) throws AwsServiceException, - SdkClientException, QueryException { + OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) throws AwsServiceException, + SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithRequestCompressionResponse::builder); + .createResponseHandler(OperationWithRequestCompressionResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithRequestCompressionRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); + operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithRequestCompression"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithRequestCompression") - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withInput(operationWithRequestCompressionRequest) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, - RequestCompression.builder().encodings("gzip").isStreaming(false).build()) - .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithRequestCompression") + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withInput(operationWithRequestCompressionRequest) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, + RequestCompression.builder().encodings("gzip").isStreaming(false).build()) + .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -485,27 +526,29 @@ public OperationWithRequestCompressionResponse operationWithRequestCompression( */ @Override public OperationWithStaticContextParamsResponse operationWithStaticContextParams( - OperationWithStaticContextParamsRequest operationWithStaticContextParamsRequest) throws AwsServiceException, - SdkClientException, QueryException { + OperationWithStaticContextParamsRequest operationWithStaticContextParamsRequest) throws AwsServiceException, + SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithStaticContextParamsResponse::builder); + .createResponseHandler(OperationWithStaticContextParamsResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithStaticContextParamsRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithStaticContextParamsRequest.overrideConfiguration().orElse(null)); + operationWithStaticContextParamsRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithStaticContextParams"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithStaticContextParams").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(operationWithStaticContextParamsRequest) - .withMetricCollector(apiCallMetricCollector) - .withMarshaller(new OperationWithStaticContextParamsRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithStaticContextParams").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(operationWithStaticContextParamsRequest).withMetricCollector(apiCallMetricCollector) + .withMarshaller(new OperationWithStaticContextParamsRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -519,11 +562,11 @@ public OperationWithStaticContextParamsResponse operationWithStaticContextParams * The content to send to the service. A {@link RequestBody} can be created using one of several factory * methods for various sources of data. For example, to create a request body from a file you can do the * following. - * + * *

      * {@code RequestBody.fromFile(new File("myfile.txt"))}
      * 
- * + * * See documentation in {@link RequestBody} for additional details and which sources of data are supported. * The service documentation for the request content is as follows ' *

@@ -555,39 +598,42 @@ public OperationWithStaticContextParamsResponse operationWithStaticContextParams */ @Override public ReturnT putOperationWithChecksum(PutOperationWithChecksumRequest putOperationWithChecksumRequest, - RequestBody requestBody, ResponseTransformer responseTransformer) - throws AwsServiceException, SdkClientException, QueryException { + RequestBody requestBody, ResponseTransformer responseTransformer) + throws AwsServiceException, SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(PutOperationWithChecksumResponse::builder); + .createResponseHandler(PutOperationWithChecksumResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(putOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, putOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "PutOperationWithChecksum"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("PutOperationWithChecksum") - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withInput(putOperationWithChecksumRequest) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(false) - .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) - .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) - .build()) - .withRequestBody(requestBody) - .withMarshaller( - StreamingRequestMarshaller.builder() - .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) - .requestBody(requestBody).build())); + .execute(new ClientExecutionParams() + .withOperationName("PutOperationWithChecksum") + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withInput(putOperationWithChecksumRequest) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(false) + .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) + .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) + .build()) + .withRequestBody(requestBody) + .withMarshaller( + StreamingRequestMarshaller.builder() + .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) + .requestBody(requestBody).build())); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -601,11 +647,11 @@ public ReturnT putOperationWithChecksum(PutOperationWithChecksumReques * The content to send to the service. A {@link RequestBody} can be created using one of several factory * methods for various sources of data. For example, to create a request body from a file you can do the * following. - * + * *

      * {@code RequestBody.fromFile(new File("myfile.txt"))}
      * 
- * + * * See documentation in {@link RequestBody} for additional details and which sources of data are supported. * The service documentation for the request content is as follows 'This be a stream' * @return Result of the StreamingInputOperation operation returned by the service. @@ -622,32 +668,35 @@ public ReturnT putOperationWithChecksum(PutOperationWithChecksumReques */ @Override public StreamingInputOperationResponse streamingInputOperation(StreamingInputOperationRequest streamingInputOperationRequest, - RequestBody requestBody) throws AwsServiceException, SdkClientException, QueryException { + RequestBody requestBody) throws AwsServiceException, SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(StreamingInputOperationResponse::builder); + .createResponseHandler(StreamingInputOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingInputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingInputOperation"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("StreamingInputOperation") - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withInput(streamingInputOperationRequest) - .withMetricCollector(apiCallMetricCollector) - .withRequestBody(requestBody) - .withMarshaller( - StreamingRequestMarshaller.builder() - .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) - .requestBody(requestBody).build())); + .execute(new ClientExecutionParams() + .withOperationName("StreamingInputOperation") + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withInput(streamingInputOperationRequest) + .withMetricCollector(apiCallMetricCollector) + .withRequestBody(requestBody) + .withMarshaller( + StreamingRequestMarshaller.builder() + .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) + .requestBody(requestBody).build())); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -678,27 +727,29 @@ public StreamingInputOperationResponse streamingInputOperation(StreamingInputOpe */ @Override public ReturnT streamingOutputOperation(StreamingOutputOperationRequest streamingOutputOperationRequest, - ResponseTransformer responseTransformer) throws AwsServiceException, - SdkClientException, QueryException { + ResponseTransformer responseTransformer) throws AwsServiceException, + SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(StreamingOutputOperationResponse::builder); + .createResponseHandler(StreamingOutputOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingOutputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingOutputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingOutputOperation"); return clientHandler.execute( - new ClientExecutionParams() - .withOperationName("StreamingOutputOperation").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(streamingOutputOperationRequest) - .withMetricCollector(apiCallMetricCollector) - .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)), responseTransformer); + new ClientExecutionParams() + .withOperationName("StreamingOutputOperation").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(streamingOutputOperationRequest).withMetricCollector(apiCallMetricCollector) + .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)), responseTransformer); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -723,7 +774,7 @@ public final String serviceName() { } private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, - RequestOverrideConfiguration requestOverrideConfiguration) { + RequestOverrideConfiguration requestOverrideConfiguration) { List publishers = null; if (requestOverrideConfiguration != null) { publishers = requestOverrideConfiguration.metricPublishers(); @@ -739,11 +790,11 @@ private static List resolveMetricPublishers(SdkClientConfigurat private AwsQueryProtocolFactory init() { return AwsQueryProtocolFactory - .builder() - .registerModeledException( - ExceptionMetadata.builder().errorCode("InvalidInput") - .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) - .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(QueryException::builder).build(); + .builder() + .registerModeledException( + ExceptionMetadata.builder().errorCode("InvalidInput") + .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) + .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(QueryException::builder).build(); } @Override diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-xml-async-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-xml-async-client-class.java index e3fd75b9f5f4..880a78853a17 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-xml-async-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-xml-async-client-class.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import java.util.function.BiFunction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.annotations.Generated; @@ -18,13 +19,18 @@ import software.amazon.awssdk.core.CredentialType; import software.amazon.awssdk.core.RequestOverrideConfiguration; import software.amazon.awssdk.core.Response; +import software.amazon.awssdk.core.SdkPlugin; import software.amazon.awssdk.core.SdkPojoBuilder; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.async.AsyncRequestBody; import software.amazon.awssdk.core.async.AsyncResponseTransformer; import software.amazon.awssdk.core.async.AsyncResponseTransformerUtils; import software.amazon.awssdk.core.client.config.SdkAdvancedAsyncClientOption; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.AsyncClientHandler; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.http.HttpResponseHandler; @@ -40,6 +46,7 @@ import software.amazon.awssdk.protocols.core.ExceptionMetadata; import software.amazon.awssdk.protocols.xml.AwsXmlProtocolFactory; import software.amazon.awssdk.protocols.xml.XmlOperationMetadata; +import software.amazon.awssdk.services.xml.internal.XmlServiceClientConfigurationBuilder; import software.amazon.awssdk.services.xml.model.APostOperationRequest; import software.amazon.awssdk.services.xml.model.APostOperationResponse; import software.amazon.awssdk.services.xml.model.APostOperationWithOutputRequest; @@ -98,13 +105,26 @@ final class DefaultXmlAsyncClient implements XmlAsyncClient { private final XmlServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + private final Executor executor; protected DefaultXmlAsyncClient(XmlServiceClientConfiguration serviceClientConfiguration, - SdkClientConfiguration clientConfiguration) { + SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsAsyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + XmlServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = XmlServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(); this.executor = clientConfiguration.option(SdkAdvancedAsyncClientOption.FUTURE_COMPLETION_EXECUTOR); } @@ -134,26 +154,28 @@ protected DefaultXmlAsyncClient(XmlServiceClientConfiguration serviceClientConfi */ @Override public CompletableFuture aPostOperation(APostOperationRequest aPostOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperation"); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(APostOperationResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(APostOperationResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); String hostPrefix = "foo-"; String resolvedHostExpression = "foo-"; CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("APostOperation") - .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) - .withCombinedResponseHandler(responseHandler).hostPrefixExpression(resolvedHostExpression) - .withMetricCollector(apiCallMetricCollector).withInput(aPostOperationRequest)); + .execute(new ClientExecutionParams() + .withOperationName("APostOperation").withRequestConfiguration(clientConfiguration) + .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) + .withCombinedResponseHandler(responseHandler).hostPrefixExpression(resolvedHostExpression) + .withMetricCollector(apiCallMetricCollector).withInput(aPostOperationRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -191,25 +213,27 @@ public CompletableFuture aPostOperation(APostOperationRe */ @Override public CompletableFuture aPostOperationWithOutput( - APostOperationWithOutputRequest aPostOperationWithOutputRequest) { + APostOperationWithOutputRequest aPostOperationWithOutputRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationWithOutputRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationWithOutputRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperationWithOutput"); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(APostOperationWithOutputResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(APostOperationWithOutputResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("APostOperationWithOutput") - .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory)) - .withCombinedResponseHandler(responseHandler).withMetricCollector(apiCallMetricCollector) - .withInput(aPostOperationWithOutputRequest)); + .execute(new ClientExecutionParams() + .withOperationName("APostOperationWithOutput").withRequestConfiguration(clientConfiguration) + .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory)) + .withCombinedResponseHandler(responseHandler).withMetricCollector(apiCallMetricCollector) + .withInput(aPostOperationWithOutputRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -243,25 +267,27 @@ public CompletableFuture aPostOperationWithOut */ @Override public CompletableFuture bearerAuthOperation( - BearerAuthOperationRequest bearerAuthOperationRequest) { + BearerAuthOperationRequest bearerAuthOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(bearerAuthOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, bearerAuthOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "BearerAuthOperation"); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(BearerAuthOperationResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(BearerAuthOperationResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("BearerAuthOperation") - .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory)) - .withCombinedResponseHandler(responseHandler).credentialType(CredentialType.TOKEN) - .withMetricCollector(apiCallMetricCollector).withInput(bearerAuthOperationRequest)); + .execute(new ClientExecutionParams() + .withOperationName("BearerAuthOperation").withRequestConfiguration(clientConfiguration) + .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory)) + .withCombinedResponseHandler(responseHandler).credentialType(CredentialType.TOKEN) + .withMetricCollector(apiCallMetricCollector).withInput(bearerAuthOperationRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -295,48 +321,50 @@ public CompletableFuture bearerAuthOperation( */ @Override public CompletableFuture eventStreamOperation(EventStreamOperationRequest eventStreamOperationRequest, - EventStreamOperationResponseHandler asyncResponseHandler) { + EventStreamOperationResponseHandler asyncResponseHandler) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(eventStreamOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, eventStreamOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "EventStreamOperation"); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - EventStreamOperationResponse::builder, XmlOperationMetadata.builder().hasStreamingSuccessResponse(true) - .build()); + EventStreamOperationResponse::builder, XmlOperationMetadata.builder().hasStreamingSuccessResponse(true) + .build()); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); HttpResponseHandler eventResponseHandler = protocolFactory.createResponseHandler( - EventStreamTaggedUnionPojoSupplier.builder() - .putSdkPojoSupplier("EventPayloadEvent", EventStream::eventPayloadEventBuilder) - .putSdkPojoSupplier("NonEventPayloadEvent", EventStream::nonEventPayloadEventBuilder) - .putSdkPojoSupplier("SecondEventPayloadEvent", EventStream::secondEventPayloadEventBuilder) - .defaultSdkPojoSupplier(() -> new SdkPojoBuilder(EventStream.UNKNOWN)).build(), XmlOperationMetadata - .builder().hasStreamingSuccessResponse(false).build()); + EventStreamTaggedUnionPojoSupplier.builder() + .putSdkPojoSupplier("EventPayloadEvent", EventStream::eventPayloadEventBuilder) + .putSdkPojoSupplier("NonEventPayloadEvent", EventStream::nonEventPayloadEventBuilder) + .putSdkPojoSupplier("SecondEventPayloadEvent", EventStream::secondEventPayloadEventBuilder) + .defaultSdkPojoSupplier(() -> new SdkPojoBuilder(EventStream.UNKNOWN)).build(), XmlOperationMetadata + .builder().hasStreamingSuccessResponse(false).build()); CompletableFuture eventStreamTransformFuture = new CompletableFuture<>(); EventStreamAsyncResponseTransformer asyncResponseTransformer = EventStreamAsyncResponseTransformer - . builder().eventStreamResponseHandler(asyncResponseHandler) - .eventResponseHandler(eventResponseHandler).initialResponseHandler(responseHandler) - .exceptionResponseHandler(errorResponseHandler).future(eventStreamTransformFuture).executor(executor) - .serviceName(serviceName()).build(); + . builder().eventStreamResponseHandler(asyncResponseHandler) + .eventResponseHandler(eventResponseHandler).initialResponseHandler(responseHandler) + .exceptionResponseHandler(errorResponseHandler).future(eventStreamTransformFuture).executor(executor) + .serviceName(serviceName()).build(); RestEventStreamAsyncResponseTransformer restAsyncResponseTransformer = RestEventStreamAsyncResponseTransformer - . builder() - .eventStreamAsyncResponseTransformer(asyncResponseTransformer) - .eventStreamResponseHandler(asyncResponseHandler).build(); + . builder() + .eventStreamAsyncResponseTransformer(asyncResponseTransformer) + .eventStreamResponseHandler(asyncResponseHandler).build(); CompletableFuture executeFuture = clientHandler.execute( - new ClientExecutionParams() - .withOperationName("EventStreamOperation") - .withMarshaller(new EventStreamOperationRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(eventStreamOperationRequest), - restAsyncResponseTransformer); + new ClientExecutionParams() + .withOperationName("EventStreamOperation").withRequestConfiguration(clientConfiguration) + .withMarshaller(new EventStreamOperationRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withMetricCollector(apiCallMetricCollector).withInput(eventStreamOperationRequest), + restAsyncResponseTransformer); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { if (e != null) { runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> asyncResponseHandler.exceptionOccurred(e)); + () -> asyncResponseHandler.exceptionOccurred(e)); eventStreamTransformFuture.completeExceptionally(e); } metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -345,7 +373,7 @@ public CompletableFuture eventStreamOperation(EventStreamOperationRequest return CompletableFutureUtils.forwardExceptionTo(eventStreamTransformFuture, executeFuture); } catch (Throwable t) { runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> asyncResponseHandler.exceptionOccurred(t)); + () -> asyncResponseHandler.exceptionOccurred(t)); metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); return CompletableFutureUtils.failedFuture(t); } @@ -372,30 +400,33 @@ public CompletableFuture eventStreamOperation(EventStreamOperationRequest */ @Override public CompletableFuture getOperationWithChecksum( - GetOperationWithChecksumRequest getOperationWithChecksumRequest) { + GetOperationWithChecksumRequest getOperationWithChecksumRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "GetOperationWithChecksum"); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(GetOperationWithChecksumResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(GetOperationWithChecksumResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("GetOperationWithChecksum") - .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory)) - .withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(true) - .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) - .isRequestStreaming(false).build()).withInput(getOperationWithChecksumRequest)); + .execute(new ClientExecutionParams() + .withOperationName("GetOperationWithChecksum") + .withRequestConfiguration(clientConfiguration) + .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory)) + .withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(true) + .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) + .isRequestStreaming(false).build()).withInput(getOperationWithChecksumRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -430,27 +461,30 @@ public CompletableFuture getOperationWithCheck */ @Override public CompletableFuture operationWithChecksumRequired( - OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) { + OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithChecksumRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); + operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithChecksumRequired"); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(OperationWithChecksumRequiredResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(OperationWithChecksumRequiredResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithChecksumRequired") - .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory)) - .withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, - HttpChecksumRequired.create()).withInput(operationWithChecksumRequiredRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithChecksumRequired") + .withRequestConfiguration(clientConfiguration) + .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory)) + .withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, + HttpChecksumRequired.create()).withInput(operationWithChecksumRequiredRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -484,25 +518,27 @@ public CompletableFuture operationWithChe */ @Override public CompletableFuture operationWithNoneAuthType( - OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) { + OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(operationWithNoneAuthTypeRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithNoneAuthTypeRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithNoneAuthType"); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(OperationWithNoneAuthTypeResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(OperationWithNoneAuthTypeResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithNoneAuthType") - .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory)) - .withCombinedResponseHandler(responseHandler).withMetricCollector(apiCallMetricCollector) - .withInput(operationWithNoneAuthTypeRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithNoneAuthType").withRequestConfiguration(clientConfiguration) + .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory)) + .withCombinedResponseHandler(responseHandler).withMetricCollector(apiCallMetricCollector) + .withInput(operationWithNoneAuthTypeRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -537,28 +573,31 @@ public CompletableFuture operationWithNoneAut */ @Override public CompletableFuture operationWithRequestCompression( - OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithRequestCompressionRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); + operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithRequestCompression"); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(OperationWithRequestCompressionResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(OperationWithRequestCompressionResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithRequestCompression") - .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) - .withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, - RequestCompression.builder().encodings("gzip").isStreaming(false).build()) - .withInput(operationWithRequestCompressionRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithRequestCompression") + .withRequestConfiguration(clientConfiguration) + .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) + .withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, + RequestCompression.builder().encodings("gzip").isStreaming(false).build()) + .withInput(operationWithRequestCompressionRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -610,48 +649,51 @@ public CompletableFuture operationWithR */ @Override public CompletableFuture putOperationWithChecksum( - PutOperationWithChecksumRequest putOperationWithChecksumRequest, AsyncRequestBody requestBody, - AsyncResponseTransformer asyncResponseTransformer) { + PutOperationWithChecksumRequest putOperationWithChecksumRequest, AsyncRequestBody requestBody, + AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(putOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, putOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "PutOperationWithChecksum"); Pair, CompletableFuture> pair = AsyncResponseTransformerUtils - .wrapWithEndOfStreamFuture(asyncResponseTransformer); + .wrapWithEndOfStreamFuture(asyncResponseTransformer); asyncResponseTransformer = pair.left(); CompletableFuture endOfStreamFuture = pair.right(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - PutOperationWithChecksumResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); + PutOperationWithChecksumResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler.execute( - new ClientExecutionParams() - .withOperationName("PutOperationWithChecksum") - .withMarshaller( - AsyncStreamingRequestMarshaller.builder() - .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) - .asyncRequestBody(requestBody).build()) - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(false) - .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) - .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) - .build()).withAsyncRequestBody(requestBody) - .withInput(putOperationWithChecksumRequest), asyncResponseTransformer); + new ClientExecutionParams() + .withOperationName("PutOperationWithChecksum") + .withMarshaller( + AsyncStreamingRequestMarshaller.builder() + .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) + .asyncRequestBody(requestBody).build()) + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(false) + .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) + .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) + .build()).withAsyncRequestBody(requestBody) + .withInput(putOperationWithChecksumRequest), asyncResponseTransformer); CompletableFuture whenCompleteFuture = null; AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { if (e != null) { runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(e)); + () -> finalAsyncResponseTransformer.exceptionOccurred(e)); } endOfStreamFuture.whenComplete((r2, e2) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -661,7 +703,7 @@ public CompletableFuture putOperationWithChecksum( } catch (Throwable t) { AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(t)); + () -> finalAsyncResponseTransformer.exceptionOccurred(t)); metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); return CompletableFutureUtils.failedFuture(t); } @@ -693,28 +735,31 @@ public CompletableFuture putOperationWithChecksum( */ @Override public CompletableFuture streamingInputOperation( - StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) { + StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingInputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingInputOperation"); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(StreamingInputOperationResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(StreamingInputOperationResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("StreamingInputOperation") - .withMarshaller( - AsyncStreamingRequestMarshaller.builder() - .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) - .asyncRequestBody(requestBody).build()).withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector).withAsyncRequestBody(requestBody) - .withInput(streamingInputOperationRequest)); + .execute(new ClientExecutionParams() + .withOperationName("StreamingInputOperation") + .withRequestConfiguration(clientConfiguration) + .withMarshaller( + AsyncStreamingRequestMarshaller.builder() + .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) + .asyncRequestBody(requestBody).build()).withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector).withAsyncRequestBody(requestBody) + .withInput(streamingInputOperationRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -753,38 +798,40 @@ public CompletableFuture streamingInputOperatio */ @Override public CompletableFuture streamingOutputOperation( - StreamingOutputOperationRequest streamingOutputOperationRequest, - AsyncResponseTransformer asyncResponseTransformer) { + StreamingOutputOperationRequest streamingOutputOperationRequest, + AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingOutputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingOutputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingOutputOperation"); Pair, CompletableFuture> pair = AsyncResponseTransformerUtils - .wrapWithEndOfStreamFuture(asyncResponseTransformer); + .wrapWithEndOfStreamFuture(asyncResponseTransformer); asyncResponseTransformer = pair.left(); CompletableFuture endOfStreamFuture = pair.right(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - StreamingOutputOperationResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); + StreamingOutputOperationResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler.execute( - new ClientExecutionParams() - .withOperationName("StreamingOutputOperation") - .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(streamingOutputOperationRequest), - asyncResponseTransformer); + new ClientExecutionParams() + .withOperationName("StreamingOutputOperation") + .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(streamingOutputOperationRequest), asyncResponseTransformer); CompletableFuture whenCompleteFuture = null; AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { if (e != null) { runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(e)); + () -> finalAsyncResponseTransformer.exceptionOccurred(e)); } endOfStreamFuture.whenComplete((r2, e2) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -794,7 +841,7 @@ public CompletableFuture streamingOutputOperation( } catch (Throwable t) { AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(t)); + () -> finalAsyncResponseTransformer.exceptionOccurred(t)); metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); return CompletableFutureUtils.failedFuture(t); } @@ -812,15 +859,15 @@ public final String serviceName() { private AwsXmlProtocolFactory init() { return AwsXmlProtocolFactory - .builder() - .registerModeledException( - ExceptionMetadata.builder().errorCode("InvalidInput") - .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) - .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(XmlException::builder).build(); + .builder() + .registerModeledException( + ExceptionMetadata.builder().errorCode("InvalidInput") + .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) + .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(XmlException::builder).build(); } private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, - RequestOverrideConfiguration requestOverrideConfiguration) { + RequestOverrideConfiguration requestOverrideConfiguration) { List publishers = null; if (requestOverrideConfiguration != null) { publishers = requestOverrideConfiguration.metricPublishers(); diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-xml-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-xml-client-class.java index 612c4b1a3088..eb506d35bf65 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-xml-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/sra/test-xml-client-class.java @@ -2,6 +2,7 @@ import java.util.Collections; import java.util.List; +import java.util.function.BiFunction; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler; @@ -9,8 +10,13 @@ import software.amazon.awssdk.core.CredentialType; import software.amazon.awssdk.core.RequestOverrideConfiguration; import software.amazon.awssdk.core.Response; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.client.handler.SyncClientHandler; import software.amazon.awssdk.core.exception.SdkClientException; @@ -29,6 +35,7 @@ import software.amazon.awssdk.protocols.core.ExceptionMetadata; import software.amazon.awssdk.protocols.xml.AwsXmlProtocolFactory; import software.amazon.awssdk.protocols.xml.XmlOperationMetadata; +import software.amazon.awssdk.services.xml.internal.XmlServiceClientConfigurationBuilder; import software.amazon.awssdk.services.xml.model.APostOperationRequest; import software.amazon.awssdk.services.xml.model.APostOperationResponse; import software.amazon.awssdk.services.xml.model.APostOperationWithOutputRequest; @@ -81,11 +88,24 @@ final class DefaultXmlClient implements XmlClient { private final XmlServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + protected DefaultXmlClient(XmlServiceClientConfiguration serviceClientConfiguration, - SdkClientConfiguration clientConfiguration) { + SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsSyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + XmlServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = XmlServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(); } @@ -111,14 +131,16 @@ protected DefaultXmlClient(XmlServiceClientConfiguration serviceClientConfigurat */ @Override public APostOperationResponse aPostOperation(APostOperationRequest aPostOperationRequest) throws InvalidInputException, - AwsServiceException, SdkClientException, XmlException { + AwsServiceException, SdkClientException, XmlException { HttpResponseHandler> responseHandler = protocolFactory.createCombinedResponseHandler( - APostOperationResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + APostOperationResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperation"); @@ -126,9 +148,10 @@ public APostOperationResponse aPostOperation(APostOperationRequest aPostOperatio String resolvedHostExpression = "foo-"; return clientHandler.execute(new ClientExecutionParams() - .withOperationName("APostOperation").withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector).hostPrefixExpression(resolvedHostExpression) - .withInput(aPostOperationRequest).withMarshaller(new APostOperationRequestMarshaller(protocolFactory))); + .withOperationName("APostOperation").withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector).hostPrefixExpression(resolvedHostExpression) + .withRequestConfiguration(clientConfiguration).withInput(aPostOperationRequest) + .withMarshaller(new APostOperationRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -156,25 +179,28 @@ public APostOperationResponse aPostOperation(APostOperationRequest aPostOperatio */ @Override public APostOperationWithOutputResponse aPostOperationWithOutput( - APostOperationWithOutputRequest aPostOperationWithOutputRequest) throws InvalidInputException, AwsServiceException, - SdkClientException, XmlException { + APostOperationWithOutputRequest aPostOperationWithOutputRequest) throws InvalidInputException, AwsServiceException, + SdkClientException, XmlException { HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(APostOperationWithOutputResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(APostOperationWithOutputResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationWithOutputRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationWithOutputRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperationWithOutput"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("APostOperationWithOutput").withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(aPostOperationWithOutputRequest) - .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("APostOperationWithOutput").withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector).withRequestConfiguration(clientConfiguration) + .withInput(aPostOperationWithOutputRequest) + .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -198,23 +224,26 @@ public APostOperationWithOutputResponse aPostOperationWithOutput( */ @Override public BearerAuthOperationResponse bearerAuthOperation(BearerAuthOperationRequest bearerAuthOperationRequest) - throws AwsServiceException, SdkClientException, XmlException { + throws AwsServiceException, SdkClientException, XmlException { + HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(BearerAuthOperationResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(BearerAuthOperationResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(bearerAuthOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, bearerAuthOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "BearerAuthOperation"); return clientHandler.execute(new ClientExecutionParams() - .withOperationName("BearerAuthOperation").withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector).credentialType(CredentialType.TOKEN) - .withInput(bearerAuthOperationRequest) - .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory))); + .withOperationName("BearerAuthOperation").withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector).credentialType(CredentialType.TOKEN) + .withRequestConfiguration(clientConfiguration).withInput(bearerAuthOperationRequest) + .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -238,32 +267,35 @@ public BearerAuthOperationResponse bearerAuthOperation(BearerAuthOperationReques */ @Override public GetOperationWithChecksumResponse getOperationWithChecksum( - GetOperationWithChecksumRequest getOperationWithChecksumRequest) throws AwsServiceException, SdkClientException, - XmlException { + GetOperationWithChecksumRequest getOperationWithChecksumRequest) throws AwsServiceException, SdkClientException, + XmlException { HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(GetOperationWithChecksumResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(GetOperationWithChecksumResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "GetOperationWithChecksum"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("GetOperationWithChecksum") - .withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector) - .withInput(getOperationWithChecksumRequest) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(true) - .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) - .isRequestStreaming(false).build()) - .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("GetOperationWithChecksum") + .withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration) + .withInput(getOperationWithChecksumRequest) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(true) + .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) + .isRequestStreaming(false).build()) + .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -287,29 +319,32 @@ public GetOperationWithChecksumResponse getOperationWithChecksum( */ @Override public OperationWithChecksumRequiredResponse operationWithChecksumRequired( - OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) throws AwsServiceException, - SdkClientException, XmlException { + OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) throws AwsServiceException, + SdkClientException, XmlException { HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(OperationWithChecksumRequiredResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(OperationWithChecksumRequiredResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithChecksumRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); + operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithChecksumRequired"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithChecksumRequired") - .withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector) - .withInput(operationWithChecksumRequiredRequest) - .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, - HttpChecksumRequired.create()) - .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithChecksumRequired") + .withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration) + .withInput(operationWithChecksumRequiredRequest) + .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, + HttpChecksumRequired.create()) + .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -333,25 +368,28 @@ public OperationWithChecksumRequiredResponse operationWithChecksumRequired( */ @Override public OperationWithNoneAuthTypeResponse operationWithNoneAuthType( - OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) throws AwsServiceException, SdkClientException, - XmlException { + OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) throws AwsServiceException, SdkClientException, + XmlException { HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(OperationWithNoneAuthTypeResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(OperationWithNoneAuthTypeResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(operationWithNoneAuthTypeRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithNoneAuthTypeRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithNoneAuthType"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithNoneAuthType").withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(operationWithNoneAuthTypeRequest) - .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithNoneAuthType").withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector).withRequestConfiguration(clientConfiguration) + .withInput(operationWithNoneAuthTypeRequest) + .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -375,29 +413,32 @@ public OperationWithNoneAuthTypeResponse operationWithNoneAuthType( */ @Override public OperationWithRequestCompressionResponse operationWithRequestCompression( - OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) throws AwsServiceException, - SdkClientException, XmlException { + OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) throws AwsServiceException, + SdkClientException, XmlException { HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(OperationWithRequestCompressionResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(OperationWithRequestCompressionResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithRequestCompressionRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); + operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithRequestCompression"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithRequestCompression") - .withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector) - .withInput(operationWithRequestCompressionRequest) - .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, - RequestCompression.builder().encodings("gzip").isStreaming(false).build()) - .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithRequestCompression") + .withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration) + .withInput(operationWithRequestCompressionRequest) + .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, + RequestCompression.builder().encodings("gzip").isStreaming(false).build()) + .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -411,11 +452,11 @@ public OperationWithRequestCompressionResponse operationWithRequestCompression( * The content to send to the service. A {@link RequestBody} can be created using one of several factory * methods for various sources of data. For example, to create a request body from a file you can do the * following. - * + * *
      * {@code RequestBody.fromFile(new File("myfile.txt"))}
      * 
- * + * * See documentation in {@link RequestBody} for additional details and which sources of data are supported. * The service documentation for the request content is as follows ' *

@@ -447,39 +488,42 @@ public OperationWithRequestCompressionResponse operationWithRequestCompression( */ @Override public ReturnT putOperationWithChecksum(PutOperationWithChecksumRequest putOperationWithChecksumRequest, - RequestBody requestBody, ResponseTransformer responseTransformer) - throws AwsServiceException, SdkClientException, XmlException { + RequestBody requestBody, ResponseTransformer responseTransformer) + throws AwsServiceException, SdkClientException, XmlException { HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - PutOperationWithChecksumResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); + PutOperationWithChecksumResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(putOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, putOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "PutOperationWithChecksum"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("PutOperationWithChecksum") - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withInput(putOperationWithChecksumRequest) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(false) - .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) - .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) - .build()) - .withRequestBody(requestBody) - .withMarshaller( - StreamingRequestMarshaller.builder() - .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) - .requestBody(requestBody).build())); + .execute(new ClientExecutionParams() + .withOperationName("PutOperationWithChecksum") + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withInput(putOperationWithChecksumRequest) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(false) + .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) + .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) + .build()) + .withRequestBody(requestBody) + .withMarshaller( + StreamingRequestMarshaller.builder() + .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) + .requestBody(requestBody).build())); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -493,11 +537,11 @@ public ReturnT putOperationWithChecksum(PutOperationWithChecksumReques * The content to send to the service. A {@link RequestBody} can be created using one of several factory * methods for various sources of data. For example, to create a request body from a file you can do the * following. - * + * *

      * {@code RequestBody.fromFile(new File("myfile.txt"))}
      * 
- * + * * See documentation in {@link RequestBody} for additional details and which sources of data are supported. * The service documentation for the request content is as follows 'This be a stream' * @return Result of the StreamingInputOperation operation returned by the service. @@ -514,30 +558,33 @@ public ReturnT putOperationWithChecksum(PutOperationWithChecksumReques */ @Override public StreamingInputOperationResponse streamingInputOperation(StreamingInputOperationRequest streamingInputOperationRequest, - RequestBody requestBody) throws AwsServiceException, SdkClientException, XmlException { + RequestBody requestBody) throws AwsServiceException, SdkClientException, XmlException { HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(StreamingInputOperationResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(StreamingInputOperationResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingInputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingInputOperation"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("StreamingInputOperation") - .withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector) - .withInput(streamingInputOperationRequest) - .withRequestBody(requestBody) - .withMarshaller( - StreamingRequestMarshaller.builder() - .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) - .requestBody(requestBody).build())); + .execute(new ClientExecutionParams() + .withOperationName("StreamingInputOperation") + .withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration) + .withInput(streamingInputOperationRequest) + .withRequestBody(requestBody) + .withMarshaller( + StreamingRequestMarshaller.builder() + .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) + .requestBody(requestBody).build())); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -568,27 +615,29 @@ public StreamingInputOperationResponse streamingInputOperation(StreamingInputOpe */ @Override public ReturnT streamingOutputOperation(StreamingOutputOperationRequest streamingOutputOperationRequest, - ResponseTransformer responseTransformer) throws AwsServiceException, - SdkClientException, XmlException { + ResponseTransformer responseTransformer) throws AwsServiceException, + SdkClientException, XmlException { HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - StreamingOutputOperationResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); + StreamingOutputOperationResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingOutputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingOutputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingOutputOperation"); return clientHandler.execute( - new ClientExecutionParams() - .withOperationName("StreamingOutputOperation").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(streamingOutputOperationRequest) - .withMetricCollector(apiCallMetricCollector) - .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)), responseTransformer); + new ClientExecutionParams() + .withOperationName("StreamingOutputOperation").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(streamingOutputOperationRequest).withMetricCollector(apiCallMetricCollector) + .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)), responseTransformer); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -600,7 +649,7 @@ public final String serviceName() { } private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, - RequestOverrideConfiguration requestOverrideConfiguration) { + RequestOverrideConfiguration requestOverrideConfiguration) { List publishers = null; if (requestOverrideConfiguration != null) { publishers = requestOverrideConfiguration.metricPublishers(); @@ -616,11 +665,11 @@ private static List resolveMetricPublishers(SdkClientConfigurat private AwsXmlProtocolFactory init() { return AwsXmlProtocolFactory - .builder() - .registerModeledException( - ExceptionMetadata.builder().errorCode("InvalidInput") - .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) - .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(XmlException::builder).build(); + .builder() + .registerModeledException( + ExceptionMetadata.builder().errorCode("InvalidInput") + .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) + .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(XmlException::builder).build(); } @Override diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-aws-json-async-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-aws-json-async-client-class.java index e15641862b49..5bb64cd6ef97 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-aws-json-async-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-aws-json-async-client-class.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import java.util.function.BiFunction; import java.util.function.Consumer; import org.reactivestreams.Publisher; import org.slf4j.Logger; @@ -24,8 +25,11 @@ import software.amazon.awssdk.awscore.eventstream.EventStreamTaggedUnionPojoSupplier; import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; import software.amazon.awssdk.core.SdkPojoBuilder; +import software.amazon.awssdk.core.SdkRequest; import software.amazon.awssdk.core.SdkResponse; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.async.AsyncRequestBody; import software.amazon.awssdk.core.async.AsyncResponseTransformer; import software.amazon.awssdk.core.async.AsyncResponseTransformerUtils; @@ -33,6 +37,8 @@ import software.amazon.awssdk.core.client.config.SdkAdvancedAsyncClientOption; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.AsyncClientHandler; import software.amazon.awssdk.core.client.handler.AttachHttpMetadataResponseHandler; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; @@ -52,6 +58,7 @@ import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.JsonOperationMetadata; +import software.amazon.awssdk.services.json.internal.JsonServiceClientConfigurationBuilder; import software.amazon.awssdk.services.json.model.APostOperationRequest; import software.amazon.awssdk.services.json.model.APostOperationResponse; import software.amazon.awssdk.services.json.model.APostOperationWithOutputRequest; @@ -130,6 +137,8 @@ final class DefaultJsonAsyncClient implements JsonAsyncClient { private final JsonServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + private final Executor executor; protected DefaultJsonAsyncClient(JsonServiceClientConfiguration serviceClientConfiguration, @@ -137,6 +146,17 @@ protected DefaultJsonAsyncClient(JsonServiceClientConfiguration serviceClientCon this.clientHandler = new AwsAsyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + JsonServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = JsonServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(AwsJsonProtocolFactory.builder()).build(); this.executor = clientConfiguration.option(SdkAdvancedAsyncClientOption.FUTURE_COMPLETION_EXECUTOR); } @@ -171,6 +191,8 @@ public JsonUtilities utilities() { */ @Override public CompletableFuture aPostOperation(APostOperationRequest aPostOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -196,8 +218,8 @@ public CompletableFuture aPostOperation(APostOperationRe .withOperationName("APostOperation") .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).hostPrefixExpression(resolvedHostExpression) - .withInput(aPostOperationRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .hostPrefixExpression(resolvedHostExpression).withInput(aPostOperationRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -236,6 +258,8 @@ public CompletableFuture aPostOperation(APostOperationRe @Override public CompletableFuture aPostOperationWithOutput( APostOperationWithOutputRequest aPostOperationWithOutputRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationWithOutputRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationWithOutputRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -257,7 +281,8 @@ public CompletableFuture aPostOperationWithOut .withOperationName("APostOperationWithOutput") .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(aPostOperationWithOutputRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(aPostOperationWithOutputRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -291,6 +316,8 @@ public CompletableFuture aPostOperationWithOut @Override public CompletableFuture eventStreamOperation(EventStreamOperationRequest eventStreamOperationRequest, Publisher requestStream, EventStreamOperationResponseHandler asyncResponseHandler) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(eventStreamOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, eventStreamOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -336,8 +363,9 @@ public CompletableFuture eventStreamOperation(EventStreamOperationRequest .withMarshaller(new EventStreamOperationRequestMarshaller(protocolFactory)) .withAsyncRequestBody(AsyncRequestBody.fromPublisher(adapted)).withFullDuplex(true) .withInitialRequestEvent(true).withResponseHandler(voidResponseHandler) - .withErrorResponseHandler(errorResponseHandler).withMetricCollector(apiCallMetricCollector) - .withInput(eventStreamOperationRequest), asyncResponseTransformer); + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector).withInput(eventStreamOperationRequest), + asyncResponseTransformer); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { try { @@ -382,6 +410,8 @@ public CompletableFuture eventStreamOperation(EventStreamOperationRequest public CompletableFuture eventStreamOperationWithOnlyInput( EventStreamOperationWithOnlyInputRequest eventStreamOperationWithOnlyInputRequest, Publisher requestStream) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + eventStreamOperationWithOnlyInputRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, eventStreamOperationWithOnlyInputRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -390,7 +420,7 @@ public CompletableFuture eventStreamO apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "EventStreamOperationWithOnlyInput"); eventStreamOperationWithOnlyInputRequest = applySignerOverride(eventStreamOperationWithOnlyInputRequest, - EventStreamAws4Signer.create()); + EventStreamAws4Signer.create()); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) .isPayloadJson(true).build(); @@ -412,7 +442,8 @@ public CompletableFuture eventStreamO .withMarshaller(new EventStreamOperationWithOnlyInputRequestMarshaller(protocolFactory)) .withAsyncRequestBody(AsyncRequestBody.fromPublisher(adapted)).withInitialRequestEvent(true) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(eventStreamOperationWithOnlyInputRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(eventStreamOperationWithOnlyInputRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -448,6 +479,8 @@ public CompletableFuture eventStreamO public CompletableFuture eventStreamOperationWithOnlyOutput( EventStreamOperationWithOnlyOutputRequest eventStreamOperationWithOnlyOutputRequest, EventStreamOperationWithOnlyOutputResponseHandler asyncResponseHandler) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + eventStreamOperationWithOnlyOutputRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, eventStreamOperationWithOnlyOutputRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -486,8 +519,8 @@ public CompletableFuture eventStreamOperationWithOnlyOutput( .withOperationName("EventStreamOperationWithOnlyOutput") .withMarshaller(new EventStreamOperationWithOnlyOutputRequestMarshaller(protocolFactory)) .withResponseHandler(voidResponseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(eventStreamOperationWithOnlyOutputRequest), - asyncResponseTransformer); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(eventStreamOperationWithOnlyOutputRequest), asyncResponseTransformer); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { try { @@ -534,6 +567,8 @@ public CompletableFuture eventStreamOperationWithOnlyOutput( @Override public CompletableFuture getWithoutRequiredMembers( GetWithoutRequiredMembersRequest getWithoutRequiredMembersRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getWithoutRequiredMembersRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getWithoutRequiredMembersRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -555,7 +590,8 @@ public CompletableFuture getWithoutRequiredMe .withOperationName("GetWithoutRequiredMembers") .withMarshaller(new GetWithoutRequiredMembersRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(getWithoutRequiredMembersRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(getWithoutRequiredMembersRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -590,6 +626,8 @@ public CompletableFuture getWithoutRequiredMe @Override public CompletableFuture operationWithChecksumRequired( OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithChecksumRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -612,6 +650,7 @@ public CompletableFuture operationWithChe .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withMetricCollector(apiCallMetricCollector) .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, HttpChecksumRequired.create()).withInput(operationWithChecksumRequiredRequest)); @@ -648,6 +687,8 @@ public CompletableFuture operationWithChe @Override public CompletableFuture operationWithNoneAuthType( OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(operationWithNoneAuthTypeRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithNoneAuthTypeRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -669,7 +710,7 @@ public CompletableFuture operationWithNoneAut .withOperationName("OperationWithNoneAuthType") .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) .putExecutionAttribute(SdkInternalExecutionAttribute.IS_NONE_AUTH_TYPE_REQUEST, false) .withInput(operationWithNoneAuthTypeRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { @@ -705,33 +746,36 @@ public CompletableFuture operationWithNoneAut */ @Override public CompletableFuture operationWithRequestCompression( - OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithRequestCompressionRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); + operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithRequestCompression"); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - operationMetadata, OperationWithRequestCompressionResponse::builder); + operationMetadata, OperationWithRequestCompressionResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithRequestCompression") - .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, - RequestCompression.builder().encodings("gzip").isStreaming(false).build()) - .withInput(operationWithRequestCompressionRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithRequestCompression") + .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, + RequestCompression.builder().encodings("gzip").isStreaming(false).build()) + .withInput(operationWithRequestCompressionRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -766,6 +810,8 @@ public CompletableFuture operationWithR @Override public CompletableFuture paginatedOperationWithResultKey( PaginatedOperationWithResultKeyRequest paginatedOperationWithResultKeyRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + paginatedOperationWithResultKeyRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, paginatedOperationWithResultKeyRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -787,7 +833,8 @@ public CompletableFuture paginatedOpera .withOperationName("PaginatedOperationWithResultKey") .withMarshaller(new PaginatedOperationWithResultKeyRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(paginatedOperationWithResultKeyRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(paginatedOperationWithResultKeyRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -822,6 +869,8 @@ public CompletableFuture paginatedOpera @Override public CompletableFuture paginatedOperationWithoutResultKey( PaginatedOperationWithoutResultKeyRequest paginatedOperationWithoutResultKeyRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + paginatedOperationWithoutResultKeyRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, paginatedOperationWithoutResultKeyRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -843,7 +892,8 @@ public CompletableFuture paginatedOp .withOperationName("PaginatedOperationWithoutResultKey") .withMarshaller(new PaginatedOperationWithoutResultKeyRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(paginatedOperationWithoutResultKeyRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(paginatedOperationWithoutResultKeyRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -882,6 +932,8 @@ public CompletableFuture paginatedOp @Override public CompletableFuture streamingInputOperation( StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingInputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -908,8 +960,9 @@ public CompletableFuture streamingInputOperatio AsyncStreamingRequestMarshaller.builder() .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) .asyncRequestBody(requestBody).build()).withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withMetricCollector(apiCallMetricCollector) - .withAsyncRequestBody(requestBody).withInput(streamingInputOperationRequest)); + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector).withAsyncRequestBody(requestBody) + .withInput(streamingInputOperationRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -954,6 +1007,8 @@ public CompletableFuture streamingInputOperatio public CompletableFuture streamingInputOutputOperation( StreamingInputOutputOperationRequest streamingInputOutputOperationRequest, AsyncRequestBody requestBody, AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + streamingInputOutputOperationRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOutputOperationRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -966,7 +1021,7 @@ public CompletableFuture streamingInputOutputOperation( asyncResponseTransformer = pair.left(); CompletableFuture endOfStreamFuture = pair.right(); streamingInputOutputOperationRequest = applySignerOverride(streamingInputOutputOperationRequest, - Aws4UnsignedPayloadSigner.create()); + Aws4UnsignedPayloadSigner.create()); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(true) .isPayloadJson(false).build(); @@ -986,8 +1041,9 @@ public CompletableFuture streamingInputOutputOperation( new StreamingInputOutputOperationRequestMarshaller(protocolFactory)) .asyncRequestBody(requestBody).transferEncoding(true).build()) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withAsyncRequestBody(requestBody) - .withInput(streamingInputOutputOperationRequest), asyncResponseTransformer); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withAsyncRequestBody(requestBody).withInput(streamingInputOutputOperationRequest), + asyncResponseTransformer); AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { @@ -1037,6 +1093,8 @@ public CompletableFuture streamingInputOutputOperation( public CompletableFuture streamingOutputOperation( StreamingOutputOperationRequest streamingOutputOperationRequest, AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingOutputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingOutputOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -1062,8 +1120,8 @@ public CompletableFuture streamingOutputOperation( .withOperationName("StreamingOutputOperation") .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(streamingOutputOperationRequest), - asyncResponseTransformer); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(streamingOutputOperationRequest), asyncResponseTransformer); AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { @@ -1130,8 +1188,8 @@ private T applySignerOverride(T request, Signer signer) } Consumer signerOverride = b -> b.signer(signer).build(); AwsRequestOverrideConfiguration overrideConfiguration = request.overrideConfiguration() - .map(c -> c.toBuilder().applyMutation(signerOverride).build()) - .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(signerOverride).build())); + .map(c -> c.toBuilder().applyMutation(signerOverride).build()) + .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(signerOverride).build())); return (T) request.toBuilder().overrideConfiguration(overrideConfiguration).build(); } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-aws-query-compatible-json-async-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-aws-query-compatible-json-async-client-class.java index 38fab697c390..6ce17ef0b19b 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-aws-query-compatible-json-async-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-aws-query-compatible-json-async-client-class.java @@ -5,6 +5,7 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.function.BiFunction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.annotations.Generated; @@ -12,8 +13,13 @@ import software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler; import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.AsyncClientHandler; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.http.HttpResponseHandler; @@ -26,6 +32,7 @@ import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.JsonOperationMetadata; +import software.amazon.awssdk.services.querytojsoncompatible.internal.QueryToJsonCompatibleServiceClientConfigurationBuilder; import software.amazon.awssdk.services.querytojsoncompatible.model.APostOperationRequest; import software.amazon.awssdk.services.querytojsoncompatible.model.APostOperationResponse; import software.amazon.awssdk.services.querytojsoncompatible.model.InvalidInputException; @@ -52,11 +59,24 @@ final class DefaultQueryToJsonCompatibleAsyncClient implements QueryToJsonCompat private final QueryToJsonCompatibleServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + protected DefaultQueryToJsonCompatibleAsyncClient(QueryToJsonCompatibleServiceClientConfiguration serviceClientConfiguration, - SdkClientConfiguration clientConfiguration) { + SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsAsyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + QueryToJsonCompatibleServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = QueryToJsonCompatibleServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(AwsJsonProtocolFactory.builder()).build(); } @@ -85,33 +105,35 @@ protected DefaultQueryToJsonCompatibleAsyncClient(QueryToJsonCompatibleServiceCl */ @Override public CompletableFuture aPostOperation(APostOperationRequest aPostOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "QueryToJsonCompatibleService"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperation"); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - operationMetadata, APostOperationResponse::builder); + operationMetadata, APostOperationResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); String hostPrefix = "{StringMember}-foo."; HostnameValidator.validateHostnameCompliant(aPostOperationRequest.stringMember(), "StringMember", - "aPostOperationRequest"); + "aPostOperationRequest"); String resolvedHostExpression = String.format("%s-foo.", aPostOperationRequest.stringMember()); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("APostOperation") - .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).hostPrefixExpression(resolvedHostExpression) - .withInput(aPostOperationRequest)); + .execute(new ClientExecutionParams() + .withOperationName("APostOperation") + .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .hostPrefixExpression(resolvedHostExpression).withInput(aPostOperationRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -135,18 +157,18 @@ public final String serviceName() { private > T init(T builder) { return builder - .clientConfiguration(clientConfiguration) - .defaultServiceExceptionSupplier(QueryToJsonCompatibleException::builder) - .protocol(AwsJsonProtocol.AWS_JSON) - .protocolVersion("1.1") - .hasAwsQueryCompatible(true) - .registerModeledException( - ExceptionMetadata.builder().errorCode("InvalidInput") - .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()); + .clientConfiguration(clientConfiguration) + .defaultServiceExceptionSupplier(QueryToJsonCompatibleException::builder) + .protocol(AwsJsonProtocol.AWS_JSON) + .protocolVersion("1.1") + .hasAwsQueryCompatible(true) + .registerModeledException( + ExceptionMetadata.builder().errorCode("InvalidInput") + .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()); } private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, - RequestOverrideConfiguration requestOverrideConfiguration) { + RequestOverrideConfiguration requestOverrideConfiguration) { List publishers = null; if (requestOverrideConfiguration != null) { publishers = requestOverrideConfiguration.metricPublishers(); @@ -161,7 +183,7 @@ private static List resolveMetricPublishers(SdkClientConfigurat } private HttpResponseHandler createErrorResponseHandler(BaseAwsJsonProtocolFactory protocolFactory, - JsonOperationMetadata operationMetadata) { + JsonOperationMetadata operationMetadata) { return protocolFactory.createErrorResponseHandler(operationMetadata); } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-aws-query-compatible-json-sync-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-aws-query-compatible-json-sync-client-class.java index 42c98a423c77..722457c89eb7 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-aws-query-compatible-json-sync-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-aws-query-compatible-json-sync-client-class.java @@ -2,13 +2,19 @@ import java.util.Collections; import java.util.List; +import java.util.function.BiFunction; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler; import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.client.handler.SyncClientHandler; import software.amazon.awssdk.core.exception.SdkClientException; @@ -22,6 +28,7 @@ import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.JsonOperationMetadata; +import software.amazon.awssdk.services.querytojsoncompatible.internal.QueryToJsonCompatibleServiceClientConfigurationBuilder; import software.amazon.awssdk.services.querytojsoncompatible.model.APostOperationRequest; import software.amazon.awssdk.services.querytojsoncompatible.model.APostOperationResponse; import software.amazon.awssdk.services.querytojsoncompatible.model.InvalidInputException; @@ -48,11 +55,24 @@ final class DefaultQueryToJsonCompatibleClient implements QueryToJsonCompatibleC private final QueryToJsonCompatibleServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + protected DefaultQueryToJsonCompatibleClient(QueryToJsonCompatibleServiceClientConfiguration serviceClientConfiguration, - SdkClientConfiguration clientConfiguration) { + SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsSyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + QueryToJsonCompatibleServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = QueryToJsonCompatibleServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(AwsJsonProtocolFactory.builder()).build(); } @@ -78,32 +98,35 @@ protected DefaultQueryToJsonCompatibleClient(QueryToJsonCompatibleServiceClientC */ @Override public APostOperationResponse aPostOperation(APostOperationRequest aPostOperationRequest) throws InvalidInputException, - AwsServiceException, SdkClientException, QueryToJsonCompatibleException { + AwsServiceException, SdkClientException, QueryToJsonCompatibleException { JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler(operationMetadata, - APostOperationResponse::builder); + APostOperationResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "QueryToJsonCompatibleService"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperation"); String hostPrefix = "{StringMember}-foo."; HostnameValidator.validateHostnameCompliant(aPostOperationRequest.stringMember(), "StringMember", - "aPostOperationRequest"); + "aPostOperationRequest"); String resolvedHostExpression = String.format("%s-foo.", aPostOperationRequest.stringMember()); return clientHandler.execute(new ClientExecutionParams() - .withOperationName("APostOperation").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).hostPrefixExpression(resolvedHostExpression) - .withInput(aPostOperationRequest).withMetricCollector(apiCallMetricCollector) - .withMarshaller(new APostOperationRequestMarshaller(protocolFactory))); + .withOperationName("APostOperation").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).hostPrefixExpression(resolvedHostExpression) + .withRequestConfiguration(clientConfiguration).withInput(aPostOperationRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new APostOperationRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -115,7 +138,7 @@ public final String serviceName() { } private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, - RequestOverrideConfiguration requestOverrideConfiguration) { + RequestOverrideConfiguration requestOverrideConfiguration) { List publishers = null; if (requestOverrideConfiguration != null) { publishers = requestOverrideConfiguration.metricPublishers(); @@ -130,20 +153,20 @@ private static List resolveMetricPublishers(SdkClientConfigurat } private HttpResponseHandler createErrorResponseHandler(BaseAwsJsonProtocolFactory protocolFactory, - JsonOperationMetadata operationMetadata) { + JsonOperationMetadata operationMetadata) { return protocolFactory.createErrorResponseHandler(operationMetadata); } private > T init(T builder) { return builder - .clientConfiguration(clientConfiguration) - .defaultServiceExceptionSupplier(QueryToJsonCompatibleException::builder) - .protocol(AwsJsonProtocol.AWS_JSON) - .protocolVersion("1.1") - .hasAwsQueryCompatible(true) - .registerModeledException( - ExceptionMetadata.builder().errorCode("InvalidInput") - .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()); + .clientConfiguration(clientConfiguration) + .defaultServiceExceptionSupplier(QueryToJsonCompatibleException::builder) + .protocol(AwsJsonProtocol.AWS_JSON) + .protocolVersion("1.1") + .hasAwsQueryCompatible(true) + .registerModeledException( + ExceptionMetadata.builder().errorCode("InvalidInput") + .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()); } @Override diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-customservicemetadata-async.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-customservicemetadata-async.java index d3d543b062fd..6c8af2fc3b69 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-customservicemetadata-async.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-customservicemetadata-async.java @@ -5,6 +5,7 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.function.BiFunction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.annotations.Generated; @@ -12,8 +13,13 @@ import software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler; import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.AsyncClientHandler; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.http.HttpResponseHandler; @@ -25,6 +31,7 @@ import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.JsonOperationMetadata; +import software.amazon.awssdk.services.protocolrestjsonwithcustomcontenttype.internal.ProtocolRestJsonWithCustomContentTypeServiceClientConfigurationBuilder; import software.amazon.awssdk.services.protocolrestjsonwithcustomcontenttype.model.OneOperationRequest; import software.amazon.awssdk.services.protocolrestjsonwithcustomcontenttype.model.OneOperationResponse; import software.amazon.awssdk.services.protocolrestjsonwithcustomcontenttype.model.ProtocolRestJsonWithCustomContentTypeException; @@ -49,12 +56,25 @@ final class DefaultProtocolRestJsonWithCustomContentTypeAsyncClient implements P private final ProtocolRestJsonWithCustomContentTypeServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + protected DefaultProtocolRestJsonWithCustomContentTypeAsyncClient( - ProtocolRestJsonWithCustomContentTypeServiceClientConfiguration serviceClientConfiguration, - SdkClientConfiguration clientConfiguration) { + ProtocolRestJsonWithCustomContentTypeServiceClientConfiguration serviceClientConfiguration, + SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsAsyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + ProtocolRestJsonWithCustomContentTypeServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = ProtocolRestJsonWithCustomContentTypeServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(AwsJsonProtocolFactory.builder()).build(); } @@ -79,27 +99,30 @@ protected DefaultProtocolRestJsonWithCustomContentTypeAsyncClient( */ @Override public CompletableFuture oneOperation(OneOperationRequest oneOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(oneOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, oneOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "AmazonProtocolRestJsonWithCustomContentType"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OneOperation"); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler(operationMetadata, - OneOperationResponse::builder); + OneOperationResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OneOperation").withMarshaller(new OneOperationRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(oneOperationRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OneOperation").withMarshaller(new OneOperationRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(oneOperationRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -123,12 +146,12 @@ public final String serviceName() { private > T init(T builder) { return builder.clientConfiguration(clientConfiguration) - .defaultServiceExceptionSupplier(ProtocolRestJsonWithCustomContentTypeException::builder) - .protocol(AwsJsonProtocol.REST_JSON).protocolVersion("1.1").contentType("application/json"); + .defaultServiceExceptionSupplier(ProtocolRestJsonWithCustomContentTypeException::builder) + .protocol(AwsJsonProtocol.REST_JSON).protocolVersion("1.1").contentType("application/json"); } private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, - RequestOverrideConfiguration requestOverrideConfiguration) { + RequestOverrideConfiguration requestOverrideConfiguration) { List publishers = null; if (requestOverrideConfiguration != null) { publishers = requestOverrideConfiguration.metricPublishers(); @@ -143,7 +166,7 @@ private static List resolveMetricPublishers(SdkClientConfigurat } private HttpResponseHandler createErrorResponseHandler(BaseAwsJsonProtocolFactory protocolFactory, - JsonOperationMetadata operationMetadata) { + JsonOperationMetadata operationMetadata) { return protocolFactory.createErrorResponseHandler(operationMetadata); } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-customservicemetadata-sync.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-customservicemetadata-sync.java index 7adf676c8d8f..498dfb10f190 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-customservicemetadata-sync.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-customservicemetadata-sync.java @@ -2,13 +2,19 @@ import java.util.Collections; import java.util.List; +import java.util.function.BiFunction; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler; import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.client.handler.SyncClientHandler; import software.amazon.awssdk.core.exception.SdkClientException; @@ -21,6 +27,7 @@ import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.JsonOperationMetadata; +import software.amazon.awssdk.services.protocolrestjsonwithcustomcontenttype.internal.ProtocolRestJsonWithCustomContentTypeServiceClientConfigurationBuilder; import software.amazon.awssdk.services.protocolrestjsonwithcustomcontenttype.model.OneOperationRequest; import software.amazon.awssdk.services.protocolrestjsonwithcustomcontenttype.model.OneOperationResponse; import software.amazon.awssdk.services.protocolrestjsonwithcustomcontenttype.model.ProtocolRestJsonWithCustomContentTypeException; @@ -45,12 +52,25 @@ final class DefaultProtocolRestJsonWithCustomContentTypeClient implements Protoc private final ProtocolRestJsonWithCustomContentTypeServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + protected DefaultProtocolRestJsonWithCustomContentTypeClient( - ProtocolRestJsonWithCustomContentTypeServiceClientConfiguration serviceClientConfiguration, - SdkClientConfiguration clientConfiguration) { + ProtocolRestJsonWithCustomContentTypeServiceClientConfiguration serviceClientConfiguration, + SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsSyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + ProtocolRestJsonWithCustomContentTypeServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = ProtocolRestJsonWithCustomContentTypeServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(AwsJsonProtocolFactory.builder()).build(); } @@ -72,28 +92,30 @@ protected DefaultProtocolRestJsonWithCustomContentTypeClient( */ @Override public OneOperationResponse oneOperation(OneOperationRequest oneOperationRequest) throws AwsServiceException, - SdkClientException, ProtocolRestJsonWithCustomContentTypeException { + SdkClientException, ProtocolRestJsonWithCustomContentTypeException { JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler(operationMetadata, - OneOperationResponse::builder); + OneOperationResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(oneOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, oneOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "AmazonProtocolRestJsonWithCustomContentType"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OneOperation"); return clientHandler.execute(new ClientExecutionParams() - .withOperationName("OneOperation").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(oneOperationRequest) - .withMetricCollector(apiCallMetricCollector) - .withMarshaller(new OneOperationRequestMarshaller(protocolFactory))); + .withOperationName("OneOperation").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(oneOperationRequest).withMetricCollector(apiCallMetricCollector) + .withMarshaller(new OneOperationRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -105,7 +127,7 @@ public final String serviceName() { } private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, - RequestOverrideConfiguration requestOverrideConfiguration) { + RequestOverrideConfiguration requestOverrideConfiguration) { List publishers = null; if (requestOverrideConfiguration != null) { publishers = requestOverrideConfiguration.metricPublishers(); @@ -120,14 +142,14 @@ private static List resolveMetricPublishers(SdkClientConfigurat } private HttpResponseHandler createErrorResponseHandler(BaseAwsJsonProtocolFactory protocolFactory, - JsonOperationMetadata operationMetadata) { + JsonOperationMetadata operationMetadata) { return protocolFactory.createErrorResponseHandler(operationMetadata); } private > T init(T builder) { return builder.clientConfiguration(clientConfiguration) - .defaultServiceExceptionSupplier(ProtocolRestJsonWithCustomContentTypeException::builder) - .protocol(AwsJsonProtocol.REST_JSON).protocolVersion("1.1").contentType("application/json"); + .defaultServiceExceptionSupplier(ProtocolRestJsonWithCustomContentTypeException::builder) + .protocol(AwsJsonProtocol.REST_JSON).protocolVersion("1.1").contentType("application/json"); } @Override diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java index d408310a5d94..77de3357e230 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-async.java @@ -6,6 +6,7 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.function.BiFunction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.annotations.Generated; @@ -15,8 +16,13 @@ import software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler; import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.AsyncClientHandler; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.endpointdiscovery.EndpointDiscoveryRefreshCache; @@ -31,6 +37,7 @@ import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.JsonOperationMetadata; +import software.amazon.awssdk.services.endpointdiscoverytest.internal.EndpointDiscoveryTestServiceClientConfigurationBuilder; import software.amazon.awssdk.services.endpointdiscoverytest.model.DescribeEndpointsRequest; import software.amazon.awssdk.services.endpointdiscoverytest.model.DescribeEndpointsResponse; import software.amazon.awssdk.services.endpointdiscoverytest.model.EndpointDiscoveryTestException; @@ -64,17 +71,30 @@ final class DefaultEndpointDiscoveryTestAsyncClient implements EndpointDiscovery private final EndpointDiscoveryTestServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + private EndpointDiscoveryRefreshCache endpointDiscoveryCache; protected DefaultEndpointDiscoveryTestAsyncClient(EndpointDiscoveryTestServiceClientConfiguration serviceClientConfiguration, - SdkClientConfiguration clientConfiguration) { + SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsAsyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + EndpointDiscoveryTestServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = EndpointDiscoveryTestServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(AwsJsonProtocolFactory.builder()).build(); if (clientConfiguration.option(SdkClientOption.ENDPOINT_DISCOVERY_ENABLED)) { this.endpointDiscoveryCache = EndpointDiscoveryRefreshCache - .create(EndpointDiscoveryTestAsyncEndpointDiscoveryCacheLoader.create(this)); + .create(EndpointDiscoveryTestAsyncEndpointDiscoveryCacheLoader.create(this)); } } @@ -97,28 +117,31 @@ protected DefaultEndpointDiscoveryTestAsyncClient(EndpointDiscoveryTestServiceCl */ @Override public CompletableFuture describeEndpoints(DescribeEndpointsRequest describeEndpointsRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(describeEndpointsRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, describeEndpointsRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "AwsEndpointDiscoveryTest"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "DescribeEndpoints"); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - operationMetadata, DescribeEndpointsResponse::builder); + operationMetadata, DescribeEndpointsResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("DescribeEndpoints") - .withMarshaller(new DescribeEndpointsRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(describeEndpointsRequest)); + .execute(new ClientExecutionParams() + .withOperationName("DescribeEndpoints") + .withMarshaller(new DescribeEndpointsRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(describeEndpointsRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -150,56 +173,57 @@ public CompletableFuture describeEndpoints(DescribeEn */ @Override public CompletableFuture testDiscoveryIdentifiersRequired( - TestDiscoveryIdentifiersRequiredRequest testDiscoveryIdentifiersRequiredRequest) { + TestDiscoveryIdentifiersRequiredRequest testDiscoveryIdentifiersRequiredRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + testDiscoveryIdentifiersRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - testDiscoveryIdentifiersRequiredRequest.overrideConfiguration().orElse(null)); + testDiscoveryIdentifiersRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "AwsEndpointDiscoveryTest"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "TestDiscoveryIdentifiersRequired"); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(operationMetadata, TestDiscoveryIdentifiersRequiredResponse::builder); + .createResponseHandler(operationMetadata, TestDiscoveryIdentifiersRequiredResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); boolean endpointDiscoveryEnabled = clientConfiguration.option(SdkClientOption.ENDPOINT_DISCOVERY_ENABLED); boolean endpointOverridden = clientConfiguration.option(SdkClientOption.ENDPOINT_OVERRIDDEN) == Boolean.TRUE; if (endpointOverridden) { throw new IllegalStateException( - "This operation requires endpoint discovery, but an endpoint override was specified when the client was created. This is not supported."); + "This operation requires endpoint discovery, but an endpoint override was specified when the client was created. This is not supported."); } if (!endpointDiscoveryEnabled) { throw new IllegalStateException( - "This operation requires endpoint discovery, but endpoint discovery was disabled on the client."); + "This operation requires endpoint discovery, but endpoint discovery was disabled on the client."); } CompletableFuture endpointFuture = CompletableFuture.completedFuture(null); if (endpointDiscoveryEnabled) { - CompletableFuture identityFuture = - testDiscoveryIdentifiersRequiredRequest.overrideConfiguration() - .flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider) - .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)) - .resolveIdentity(); + CompletableFuture identityFuture = testDiscoveryIdentifiersRequiredRequest + .overrideConfiguration().flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider) + .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)) + .resolveIdentity(); endpointFuture = identityFuture.thenApply(credentials -> { EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(true) - .defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT)) - .overrideConfiguration(testDiscoveryIdentifiersRequiredRequest.overrideConfiguration().orElse(null)) - .build(); + .defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT)) + .overrideConfiguration(testDiscoveryIdentifiersRequiredRequest.overrideConfiguration().orElse(null)) + .build(); return endpointDiscoveryCache.get(credentials.accessKeyId(), endpointDiscoveryRequest); }); } - CompletableFuture executeFuture = - endpointFuture.thenCompose(cachedEndpoint -> - clientHandler.execute(new ClientExecutionParams() - .withOperationName("TestDiscoveryIdentifiersRequired") - .withMarshaller(new TestDiscoveryIdentifiersRequiredRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).discoveredEndpoint(cachedEndpoint) - .withInput(testDiscoveryIdentifiersRequiredRequest))); + CompletableFuture executeFuture = endpointFuture + .thenCompose(cachedEndpoint -> clientHandler + .execute(new ClientExecutionParams() + .withOperationName("TestDiscoveryIdentifiersRequired") + .withMarshaller(new TestDiscoveryIdentifiersRequiredRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .discoveredEndpoint(cachedEndpoint).withInput(testDiscoveryIdentifiersRequiredRequest))); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -230,47 +254,48 @@ public CompletableFuture testDiscovery */ @Override public CompletableFuture testDiscoveryOptional( - TestDiscoveryOptionalRequest testDiscoveryOptionalRequest) { + TestDiscoveryOptionalRequest testDiscoveryOptionalRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(testDiscoveryOptionalRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, testDiscoveryOptionalRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "AwsEndpointDiscoveryTest"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "TestDiscoveryOptional"); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - operationMetadata, TestDiscoveryOptionalResponse::builder); + operationMetadata, TestDiscoveryOptionalResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); boolean endpointDiscoveryEnabled = clientConfiguration.option(SdkClientOption.ENDPOINT_DISCOVERY_ENABLED); boolean endpointOverridden = clientConfiguration.option(SdkClientOption.ENDPOINT_OVERRIDDEN) == Boolean.TRUE; CompletableFuture endpointFuture = CompletableFuture.completedFuture(null); if (endpointDiscoveryEnabled) { - CompletableFuture identityFuture = - testDiscoveryOptionalRequest.overrideConfiguration() - .flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider) - .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)) - .resolveIdentity(); + CompletableFuture identityFuture = testDiscoveryOptionalRequest + .overrideConfiguration().flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider) + .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)) + .resolveIdentity(); endpointFuture = identityFuture.thenApply(credentials -> { EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(false) - .defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT)) - .overrideConfiguration(testDiscoveryOptionalRequest.overrideConfiguration().orElse(null)).build(); + .defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT)) + .overrideConfiguration(testDiscoveryOptionalRequest.overrideConfiguration().orElse(null)).build(); return endpointDiscoveryCache.get(credentials.accessKeyId(), endpointDiscoveryRequest); }); } - CompletableFuture executeFuture = - endpointFuture.thenCompose(cachedEndpoint -> - clientHandler.execute(new ClientExecutionParams() - .withOperationName("TestDiscoveryOptional") - .withMarshaller(new TestDiscoveryOptionalRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).discoveredEndpoint(cachedEndpoint) - .withInput(testDiscoveryOptionalRequest))); + CompletableFuture executeFuture = endpointFuture + .thenCompose(cachedEndpoint -> clientHandler + .execute(new ClientExecutionParams() + .withOperationName("TestDiscoveryOptional") + .withMarshaller(new TestDiscoveryOptionalRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .discoveredEndpoint(cachedEndpoint).withInput(testDiscoveryOptionalRequest))); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -301,55 +326,56 @@ public CompletableFuture testDiscoveryOptional( */ @Override public CompletableFuture testDiscoveryRequired( - TestDiscoveryRequiredRequest testDiscoveryRequiredRequest) { + TestDiscoveryRequiredRequest testDiscoveryRequiredRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(testDiscoveryRequiredRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, testDiscoveryRequiredRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "AwsEndpointDiscoveryTest"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "TestDiscoveryRequired"); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - operationMetadata, TestDiscoveryRequiredResponse::builder); + operationMetadata, TestDiscoveryRequiredResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); boolean endpointDiscoveryEnabled = clientConfiguration.option(SdkClientOption.ENDPOINT_DISCOVERY_ENABLED); boolean endpointOverridden = clientConfiguration.option(SdkClientOption.ENDPOINT_OVERRIDDEN) == Boolean.TRUE; if (endpointOverridden) { throw new IllegalStateException( - "This operation requires endpoint discovery, but an endpoint override was specified when the client was created. This is not supported."); + "This operation requires endpoint discovery, but an endpoint override was specified when the client was created. This is not supported."); } if (!endpointDiscoveryEnabled) { throw new IllegalStateException( - "This operation requires endpoint discovery, but endpoint discovery was disabled on the client."); + "This operation requires endpoint discovery, but endpoint discovery was disabled on the client."); } CompletableFuture endpointFuture = CompletableFuture.completedFuture(null); if (endpointDiscoveryEnabled) { - CompletableFuture identityFuture = - testDiscoveryRequiredRequest.overrideConfiguration() - .flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider) - .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)) - .resolveIdentity(); + CompletableFuture identityFuture = testDiscoveryRequiredRequest + .overrideConfiguration().flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider) + .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)) + .resolveIdentity(); endpointFuture = identityFuture.thenApply(credentials -> { EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(true) - .defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT)) - .overrideConfiguration(testDiscoveryRequiredRequest.overrideConfiguration().orElse(null)).build(); + .defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT)) + .overrideConfiguration(testDiscoveryRequiredRequest.overrideConfiguration().orElse(null)).build(); return endpointDiscoveryCache.get(credentials.accessKeyId(), endpointDiscoveryRequest); }); } - CompletableFuture executeFuture = - endpointFuture.thenCompose(cachedEndpoint -> - clientHandler.execute(new ClientExecutionParams() - .withOperationName("TestDiscoveryRequired") - .withMarshaller(new TestDiscoveryRequiredRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).discoveredEndpoint(cachedEndpoint) - .withInput(testDiscoveryRequiredRequest))); + CompletableFuture executeFuture = endpointFuture + .thenCompose(cachedEndpoint -> clientHandler + .execute(new ClientExecutionParams() + .withOperationName("TestDiscoveryRequired") + .withMarshaller(new TestDiscoveryRequiredRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .discoveredEndpoint(cachedEndpoint).withInput(testDiscoveryRequiredRequest))); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -373,12 +399,12 @@ public final String serviceName() { private > T init(T builder) { return builder.clientConfiguration(clientConfiguration) - .defaultServiceExceptionSupplier(EndpointDiscoveryTestException::builder).protocol(AwsJsonProtocol.AWS_JSON) - .protocolVersion("1.1"); + .defaultServiceExceptionSupplier(EndpointDiscoveryTestException::builder).protocol(AwsJsonProtocol.AWS_JSON) + .protocolVersion("1.1"); } private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, - RequestOverrideConfiguration requestOverrideConfiguration) { + RequestOverrideConfiguration requestOverrideConfiguration) { List publishers = null; if (requestOverrideConfiguration != null) { publishers = requestOverrideConfiguration.metricPublishers(); @@ -393,7 +419,7 @@ private static List resolveMetricPublishers(SdkClientConfigurat } private HttpResponseHandler createErrorResponseHandler(BaseAwsJsonProtocolFactory protocolFactory, - JsonOperationMetadata operationMetadata) { + JsonOperationMetadata operationMetadata) { return protocolFactory.createErrorResponseHandler(operationMetadata); } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-sync.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-sync.java index 1e4df5c706ec..1d4098abb7de 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-sync.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-endpoint-discovery-sync.java @@ -4,6 +4,7 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.function.BiFunction; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration; @@ -11,8 +12,13 @@ import software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler; import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.client.handler.SyncClientHandler; import software.amazon.awssdk.core.endpointdiscovery.EndpointDiscoveryRefreshCache; @@ -28,6 +34,7 @@ import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.JsonOperationMetadata; +import software.amazon.awssdk.services.endpointdiscoverytest.internal.EndpointDiscoveryTestServiceClientConfigurationBuilder; import software.amazon.awssdk.services.endpointdiscoverytest.model.DescribeEndpointsRequest; import software.amazon.awssdk.services.endpointdiscoverytest.model.DescribeEndpointsResponse; import software.amazon.awssdk.services.endpointdiscoverytest.model.EndpointDiscoveryTestException; @@ -62,17 +69,30 @@ final class DefaultEndpointDiscoveryTestClient implements EndpointDiscoveryTestC private final EndpointDiscoveryTestServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + private EndpointDiscoveryRefreshCache endpointDiscoveryCache; protected DefaultEndpointDiscoveryTestClient(EndpointDiscoveryTestServiceClientConfiguration serviceClientConfiguration, - SdkClientConfiguration clientConfiguration) { + SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsSyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + EndpointDiscoveryTestServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = EndpointDiscoveryTestServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(AwsJsonProtocolFactory.builder()).build(); if (clientConfiguration.option(SdkClientOption.ENDPOINT_DISCOVERY_ENABLED)) { this.endpointDiscoveryCache = EndpointDiscoveryRefreshCache.create(EndpointDiscoveryTestEndpointDiscoveryCacheLoader - .create(this)); + .create(this)); } } @@ -92,28 +112,30 @@ protected DefaultEndpointDiscoveryTestClient(EndpointDiscoveryTestServiceClientC */ @Override public DescribeEndpointsResponse describeEndpoints(DescribeEndpointsRequest describeEndpointsRequest) - throws AwsServiceException, SdkClientException, EndpointDiscoveryTestException { + throws AwsServiceException, SdkClientException, EndpointDiscoveryTestException { JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler(operationMetadata, - DescribeEndpointsResponse::builder); + DescribeEndpointsResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(describeEndpointsRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, describeEndpointsRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "AwsEndpointDiscoveryTest"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "DescribeEndpoints"); return clientHandler.execute(new ClientExecutionParams() - .withOperationName("DescribeEndpoints").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(describeEndpointsRequest) - .withMetricCollector(apiCallMetricCollector) - .withMarshaller(new DescribeEndpointsRequestMarshaller(protocolFactory))); + .withOperationName("DescribeEndpoints").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(describeEndpointsRequest).withMetricCollector(apiCallMetricCollector) + .withMarshaller(new DescribeEndpointsRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -135,53 +157,54 @@ public DescribeEndpointsResponse describeEndpoints(DescribeEndpointsRequest desc */ @Override public TestDiscoveryIdentifiersRequiredResponse testDiscoveryIdentifiersRequired( - TestDiscoveryIdentifiersRequiredRequest testDiscoveryIdentifiersRequiredRequest) throws AwsServiceException, - SdkClientException, EndpointDiscoveryTestException { + TestDiscoveryIdentifiersRequiredRequest testDiscoveryIdentifiersRequiredRequest) throws AwsServiceException, + SdkClientException, EndpointDiscoveryTestException { JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - operationMetadata, TestDiscoveryIdentifiersRequiredResponse::builder); + operationMetadata, TestDiscoveryIdentifiersRequiredResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); boolean endpointDiscoveryEnabled = clientConfiguration.option(SdkClientOption.ENDPOINT_DISCOVERY_ENABLED); boolean endpointOverridden = clientConfiguration.option(SdkClientOption.ENDPOINT_OVERRIDDEN) == Boolean.TRUE; if (endpointOverridden) { throw new IllegalStateException( - "This operation requires endpoint discovery, but an endpoint override was specified when the client was created. This is not supported."); + "This operation requires endpoint discovery, but an endpoint override was specified when the client was created. This is not supported."); } if (!endpointDiscoveryEnabled) { throw new IllegalStateException( - "This operation requires endpoint discovery, but endpoint discovery was disabled on the client."); + "This operation requires endpoint discovery, but endpoint discovery was disabled on the client."); } URI cachedEndpoint = null; if (endpointDiscoveryEnabled) { - CompletableFuture identityFuture = - testDiscoveryIdentifiersRequiredRequest.overrideConfiguration() - .flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider) - .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)) - .resolveIdentity(); + CompletableFuture identityFuture = testDiscoveryIdentifiersRequiredRequest + .overrideConfiguration().flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider) + .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)).resolveIdentity(); String key = CompletableFutureUtils.joinLikeSync(identityFuture).accessKeyId(); EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(true) - .defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT)) - .overrideConfiguration(testDiscoveryIdentifiersRequiredRequest.overrideConfiguration().orElse(null)).build(); + .defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT)) + .overrideConfiguration(testDiscoveryIdentifiersRequiredRequest.overrideConfiguration().orElse(null)).build(); cachedEndpoint = endpointDiscoveryCache.get(key, endpointDiscoveryRequest); } + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + testDiscoveryIdentifiersRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - testDiscoveryIdentifiersRequiredRequest.overrideConfiguration().orElse(null)); + testDiscoveryIdentifiersRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "AwsEndpointDiscoveryTest"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "TestDiscoveryIdentifiersRequired"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("TestDiscoveryIdentifiersRequired").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).discoveredEndpoint(cachedEndpoint) - .withInput(testDiscoveryIdentifiersRequiredRequest).withMetricCollector(apiCallMetricCollector) - .withMarshaller(new TestDiscoveryIdentifiersRequiredRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("TestDiscoveryIdentifiersRequired").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).discoveredEndpoint(cachedEndpoint) + .withRequestConfiguration(clientConfiguration).withInput(testDiscoveryIdentifiersRequiredRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new TestDiscoveryIdentifiersRequiredRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -203,43 +226,44 @@ public TestDiscoveryIdentifiersRequiredResponse testDiscoveryIdentifiersRequired */ @Override public TestDiscoveryOptionalResponse testDiscoveryOptional(TestDiscoveryOptionalRequest testDiscoveryOptionalRequest) - throws AwsServiceException, SdkClientException, EndpointDiscoveryTestException { + throws AwsServiceException, SdkClientException, EndpointDiscoveryTestException { JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - operationMetadata, TestDiscoveryOptionalResponse::builder); + operationMetadata, TestDiscoveryOptionalResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); boolean endpointDiscoveryEnabled = clientConfiguration.option(SdkClientOption.ENDPOINT_DISCOVERY_ENABLED); boolean endpointOverridden = clientConfiguration.option(SdkClientOption.ENDPOINT_OVERRIDDEN) == Boolean.TRUE; URI cachedEndpoint = null; if (endpointDiscoveryEnabled) { - CompletableFuture identityFuture = - testDiscoveryOptionalRequest.overrideConfiguration() - .flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider) - .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)) - .resolveIdentity(); + CompletableFuture identityFuture = testDiscoveryOptionalRequest + .overrideConfiguration().flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider) + .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)).resolveIdentity(); String key = CompletableFutureUtils.joinLikeSync(identityFuture).accessKeyId(); EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(false) - .defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT)) - .overrideConfiguration(testDiscoveryOptionalRequest.overrideConfiguration().orElse(null)).build(); + .defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT)) + .overrideConfiguration(testDiscoveryOptionalRequest.overrideConfiguration().orElse(null)).build(); cachedEndpoint = endpointDiscoveryCache.get(key, endpointDiscoveryRequest); } + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(testDiscoveryOptionalRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, testDiscoveryOptionalRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "AwsEndpointDiscoveryTest"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "TestDiscoveryOptional"); return clientHandler.execute(new ClientExecutionParams() - .withOperationName("TestDiscoveryOptional").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).discoveredEndpoint(cachedEndpoint) - .withInput(testDiscoveryOptionalRequest).withMetricCollector(apiCallMetricCollector) - .withMarshaller(new TestDiscoveryOptionalRequestMarshaller(protocolFactory))); + .withOperationName("TestDiscoveryOptional").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).discoveredEndpoint(cachedEndpoint) + .withRequestConfiguration(clientConfiguration).withInput(testDiscoveryOptionalRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new TestDiscoveryOptionalRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -261,51 +285,52 @@ public TestDiscoveryOptionalResponse testDiscoveryOptional(TestDiscoveryOptional */ @Override public TestDiscoveryRequiredResponse testDiscoveryRequired(TestDiscoveryRequiredRequest testDiscoveryRequiredRequest) - throws AwsServiceException, SdkClientException, EndpointDiscoveryTestException { + throws AwsServiceException, SdkClientException, EndpointDiscoveryTestException { JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - operationMetadata, TestDiscoveryRequiredResponse::builder); + operationMetadata, TestDiscoveryRequiredResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); boolean endpointDiscoveryEnabled = clientConfiguration.option(SdkClientOption.ENDPOINT_DISCOVERY_ENABLED); boolean endpointOverridden = clientConfiguration.option(SdkClientOption.ENDPOINT_OVERRIDDEN) == Boolean.TRUE; if (endpointOverridden) { throw new IllegalStateException( - "This operation requires endpoint discovery, but an endpoint override was specified when the client was created. This is not supported."); + "This operation requires endpoint discovery, but an endpoint override was specified when the client was created. This is not supported."); } if (!endpointDiscoveryEnabled) { throw new IllegalStateException( - "This operation requires endpoint discovery, but endpoint discovery was disabled on the client."); + "This operation requires endpoint discovery, but endpoint discovery was disabled on the client."); } URI cachedEndpoint = null; if (endpointDiscoveryEnabled) { - CompletableFuture identityFuture = - testDiscoveryRequiredRequest.overrideConfiguration() - .flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider) - .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)) - .resolveIdentity(); + CompletableFuture identityFuture = testDiscoveryRequiredRequest + .overrideConfiguration().flatMap(AwsRequestOverrideConfiguration::credentialsIdentityProvider) + .orElseGet(() -> clientConfiguration.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER)).resolveIdentity(); String key = CompletableFutureUtils.joinLikeSync(identityFuture).accessKeyId(); EndpointDiscoveryRequest endpointDiscoveryRequest = EndpointDiscoveryRequest.builder().required(true) - .defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT)) - .overrideConfiguration(testDiscoveryRequiredRequest.overrideConfiguration().orElse(null)).build(); + .defaultEndpoint(clientConfiguration.option(SdkClientOption.ENDPOINT)) + .overrideConfiguration(testDiscoveryRequiredRequest.overrideConfiguration().orElse(null)).build(); cachedEndpoint = endpointDiscoveryCache.get(key, endpointDiscoveryRequest); } + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(testDiscoveryRequiredRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, testDiscoveryRequiredRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "AwsEndpointDiscoveryTest"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "TestDiscoveryRequired"); return clientHandler.execute(new ClientExecutionParams() - .withOperationName("TestDiscoveryRequired").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).discoveredEndpoint(cachedEndpoint) - .withInput(testDiscoveryRequiredRequest).withMetricCollector(apiCallMetricCollector) - .withMarshaller(new TestDiscoveryRequiredRequestMarshaller(protocolFactory))); + .withOperationName("TestDiscoveryRequired").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).discoveredEndpoint(cachedEndpoint) + .withRequestConfiguration(clientConfiguration).withInput(testDiscoveryRequiredRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new TestDiscoveryRequiredRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -317,7 +342,7 @@ public final String serviceName() { } private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, - RequestOverrideConfiguration requestOverrideConfiguration) { + RequestOverrideConfiguration requestOverrideConfiguration) { List publishers = null; if (requestOverrideConfiguration != null) { publishers = requestOverrideConfiguration.metricPublishers(); @@ -332,14 +357,14 @@ private static List resolveMetricPublishers(SdkClientConfigurat } private HttpResponseHandler createErrorResponseHandler(BaseAwsJsonProtocolFactory protocolFactory, - JsonOperationMetadata operationMetadata) { + JsonOperationMetadata operationMetadata) { return protocolFactory.createErrorResponseHandler(operationMetadata); } private > T init(T builder) { return builder.clientConfiguration(clientConfiguration) - .defaultServiceExceptionSupplier(EndpointDiscoveryTestException::builder).protocol(AwsJsonProtocol.AWS_JSON) - .protocolVersion("1.1"); + .defaultServiceExceptionSupplier(EndpointDiscoveryTestException::builder).protocol(AwsJsonProtocol.AWS_JSON) + .protocolVersion("1.1"); } @Override diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-class.java index 9cb6a021f1b2..a8c715686d11 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-class.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import java.util.function.BiFunction; import java.util.function.Consumer; import org.reactivestreams.Publisher; import org.slf4j.Logger; @@ -27,8 +28,11 @@ import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.CredentialType; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; import software.amazon.awssdk.core.SdkPojoBuilder; +import software.amazon.awssdk.core.SdkRequest; import software.amazon.awssdk.core.SdkResponse; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.async.AsyncRequestBody; import software.amazon.awssdk.core.async.AsyncResponseTransformer; import software.amazon.awssdk.core.async.AsyncResponseTransformerUtils; @@ -36,6 +40,8 @@ import software.amazon.awssdk.core.client.config.SdkAdvancedAsyncClientOption; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.AsyncClientHandler; import software.amazon.awssdk.core.client.handler.AttachHttpMetadataResponseHandler; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; @@ -56,6 +62,7 @@ import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.JsonOperationMetadata; +import software.amazon.awssdk.services.json.internal.JsonServiceClientConfigurationBuilder; import software.amazon.awssdk.services.json.model.APostOperationRequest; import software.amazon.awssdk.services.json.model.APostOperationResponse; import software.amazon.awssdk.services.json.model.APostOperationWithOutputRequest; @@ -139,6 +146,8 @@ final class DefaultJsonAsyncClient implements JsonAsyncClient { private final JsonServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + private final Executor executor; protected DefaultJsonAsyncClient(JsonServiceClientConfiguration serviceClientConfiguration, @@ -146,6 +155,17 @@ protected DefaultJsonAsyncClient(JsonServiceClientConfiguration serviceClientCon this.clientHandler = new AwsAsyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + JsonServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = JsonServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(AwsJsonProtocolFactory.builder()).build(); this.executor = clientConfiguration.option(SdkAdvancedAsyncClientOption.FUTURE_COMPLETION_EXECUTOR); } @@ -180,6 +200,8 @@ public JsonUtilities utilities() { */ @Override public CompletableFuture aPostOperation(APostOperationRequest aPostOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -205,8 +227,8 @@ public CompletableFuture aPostOperation(APostOperationRe .withOperationName("APostOperation") .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).hostPrefixExpression(resolvedHostExpression) - .withInput(aPostOperationRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .hostPrefixExpression(resolvedHostExpression).withInput(aPostOperationRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -244,6 +266,8 @@ public CompletableFuture aPostOperation(APostOperationRe @Override public CompletableFuture aPostOperationWithOutput( APostOperationWithOutputRequest aPostOperationWithOutputRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationWithOutputRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationWithOutputRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -265,7 +289,8 @@ public CompletableFuture aPostOperationWithOut .withOperationName("APostOperationWithOutput") .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(aPostOperationWithOutputRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(aPostOperationWithOutputRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -299,6 +324,8 @@ public CompletableFuture aPostOperationWithOut @Override public CompletableFuture bearerAuthOperation( BearerAuthOperationRequest bearerAuthOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(bearerAuthOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, bearerAuthOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -321,8 +348,8 @@ public CompletableFuture bearerAuthOperation( .withOperationName("BearerAuthOperation") .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).credentialType(CredentialType.TOKEN) - .withInput(bearerAuthOperationRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .credentialType(CredentialType.TOKEN).withInput(bearerAuthOperationRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -356,6 +383,8 @@ public CompletableFuture bearerAuthOperation( @Override public CompletableFuture eventStreamOperation(EventStreamOperationRequest eventStreamOperationRequest, Publisher requestStream, EventStreamOperationResponseHandler asyncResponseHandler) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(eventStreamOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, eventStreamOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -405,8 +434,8 @@ public CompletableFuture eventStreamOperation(EventStreamOperationRequest .withMarshaller(new EventStreamOperationRequestMarshaller(protocolFactory)) .withAsyncRequestBody(AsyncRequestBody.fromPublisher(adapted)).withFullDuplex(true) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(eventStreamOperationRequest), - restAsyncResponseTransformer); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(eventStreamOperationRequest), restAsyncResponseTransformer); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { try { @@ -451,6 +480,8 @@ public CompletableFuture eventStreamOperation(EventStreamOperationRequest public CompletableFuture eventStreamOperationWithOnlyInput( EventStreamOperationWithOnlyInputRequest eventStreamOperationWithOnlyInputRequest, Publisher requestStream) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + eventStreamOperationWithOnlyInputRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, eventStreamOperationWithOnlyInputRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -459,7 +490,7 @@ public CompletableFuture eventStreamO apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "EventStreamOperationWithOnlyInput"); eventStreamOperationWithOnlyInputRequest = applySignerOverride(eventStreamOperationWithOnlyInputRequest, - EventStreamAws4Signer.create()); + EventStreamAws4Signer.create()); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) .isPayloadJson(true).build(); @@ -480,8 +511,8 @@ public CompletableFuture eventStreamO .withOperationName("EventStreamOperationWithOnlyInput") .withMarshaller(new EventStreamOperationWithOnlyInputRequestMarshaller(protocolFactory)) .withAsyncRequestBody(AsyncRequestBody.fromPublisher(adapted)).withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withMetricCollector(apiCallMetricCollector) - .withInput(eventStreamOperationWithOnlyInputRequest)); + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector).withInput(eventStreamOperationWithOnlyInputRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -517,6 +548,8 @@ public CompletableFuture eventStreamO public CompletableFuture eventStreamOperationWithOnlyOutput( EventStreamOperationWithOnlyOutputRequest eventStreamOperationWithOnlyOutputRequest, EventStreamOperationWithOnlyOutputResponseHandler asyncResponseHandler) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + eventStreamOperationWithOnlyOutputRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, eventStreamOperationWithOnlyOutputRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -560,7 +593,7 @@ public CompletableFuture eventStreamOperationWithOnlyOutput( .withOperationName("EventStreamOperationWithOnlyOutput") .withMarshaller(new EventStreamOperationWithOnlyOutputRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) .withInput(eventStreamOperationWithOnlyOutputRequest), restAsyncResponseTransformer); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { @@ -604,6 +637,8 @@ public CompletableFuture eventStreamOperationWithOnlyOutput( @Override public CompletableFuture getOperationWithChecksum( GetOperationWithChecksumRequest getOperationWithChecksumRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getOperationWithChecksumRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -626,6 +661,7 @@ public CompletableFuture getOperationWithCheck .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withMetricCollector(apiCallMetricCollector) .putExecutionAttribute( SdkInternalExecutionAttribute.HTTP_CHECKSUM, @@ -669,6 +705,8 @@ public CompletableFuture getOperationWithCheck @Override public CompletableFuture getWithoutRequiredMembers( GetWithoutRequiredMembersRequest getWithoutRequiredMembersRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getWithoutRequiredMembersRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getWithoutRequiredMembersRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -690,7 +728,8 @@ public CompletableFuture getWithoutRequiredMe .withOperationName("GetWithoutRequiredMembers") .withMarshaller(new GetWithoutRequiredMembersRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(getWithoutRequiredMembersRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(getWithoutRequiredMembersRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -725,6 +764,8 @@ public CompletableFuture getWithoutRequiredMe @Override public CompletableFuture operationWithChecksumRequired( OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithChecksumRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -747,6 +788,7 @@ public CompletableFuture operationWithChe .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withMetricCollector(apiCallMetricCollector) .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, HttpChecksumRequired.create()).withInput(operationWithChecksumRequiredRequest)); @@ -783,33 +825,36 @@ public CompletableFuture operationWithChe */ @Override public CompletableFuture operationWithRequestCompression( - OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithRequestCompressionRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); + operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithRequestCompression"); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - operationMetadata, OperationWithRequestCompressionResponse::builder); + operationMetadata, OperationWithRequestCompressionResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); + operationMetadata); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithRequestCompression") - .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, - RequestCompression.builder().encodings("gzip").isStreaming(false).build()) - .withInput(operationWithRequestCompressionRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithRequestCompression") + .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, + RequestCompression.builder().encodings("gzip").isStreaming(false).build()) + .withInput(operationWithRequestCompressionRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -844,6 +889,8 @@ public CompletableFuture operationWithR @Override public CompletableFuture paginatedOperationWithResultKey( PaginatedOperationWithResultKeyRequest paginatedOperationWithResultKeyRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + paginatedOperationWithResultKeyRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, paginatedOperationWithResultKeyRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -865,7 +912,8 @@ public CompletableFuture paginatedOpera .withOperationName("PaginatedOperationWithResultKey") .withMarshaller(new PaginatedOperationWithResultKeyRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(paginatedOperationWithResultKeyRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(paginatedOperationWithResultKeyRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -900,6 +948,8 @@ public CompletableFuture paginatedOpera @Override public CompletableFuture paginatedOperationWithoutResultKey( PaginatedOperationWithoutResultKeyRequest paginatedOperationWithoutResultKeyRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + paginatedOperationWithoutResultKeyRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, paginatedOperationWithoutResultKeyRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -921,7 +971,8 @@ public CompletableFuture paginatedOp .withOperationName("PaginatedOperationWithoutResultKey") .withMarshaller(new PaginatedOperationWithoutResultKeyRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(paginatedOperationWithoutResultKeyRequest)); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(paginatedOperationWithoutResultKeyRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -974,6 +1025,8 @@ public CompletableFuture paginatedOp public CompletableFuture putOperationWithChecksum( PutOperationWithChecksumRequest putOperationWithChecksumRequest, AsyncRequestBody requestBody, AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(putOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, putOperationWithChecksumRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -1006,6 +1059,7 @@ public CompletableFuture putOperationWithChecksum( .asyncRequestBody(requestBody).build()) .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withMetricCollector(apiCallMetricCollector) .withAsyncRequestBody(requestBody) .putExecutionAttribute( @@ -1062,6 +1116,8 @@ public CompletableFuture putOperationWithChecksum( @Override public CompletableFuture streamingInputOperation( StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingInputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -1088,8 +1144,9 @@ public CompletableFuture streamingInputOperatio AsyncStreamingRequestMarshaller.builder() .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) .asyncRequestBody(requestBody).build()).withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withMetricCollector(apiCallMetricCollector) - .withAsyncRequestBody(requestBody).withInput(streamingInputOperationRequest)); + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector).withAsyncRequestBody(requestBody) + .withInput(streamingInputOperationRequest)); CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); }); @@ -1134,6 +1191,8 @@ public CompletableFuture streamingInputOperatio public CompletableFuture streamingInputOutputOperation( StreamingInputOutputOperationRequest streamingInputOutputOperationRequest, AsyncRequestBody requestBody, AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + streamingInputOutputOperationRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOutputOperationRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -1146,7 +1205,7 @@ public CompletableFuture streamingInputOutputOperation( asyncResponseTransformer = pair.left(); CompletableFuture endOfStreamFuture = pair.right(); streamingInputOutputOperationRequest = applySignerOverride(streamingInputOutputOperationRequest, - Aws4UnsignedPayloadSigner.create()); + Aws4UnsignedPayloadSigner.create()); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(true) .isPayloadJson(false).build(); @@ -1166,8 +1225,9 @@ public CompletableFuture streamingInputOutputOperation( new StreamingInputOutputOperationRequestMarshaller(protocolFactory)) .asyncRequestBody(requestBody).transferEncoding(true).build()) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withAsyncRequestBody(requestBody) - .withInput(streamingInputOutputOperationRequest), asyncResponseTransformer); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withAsyncRequestBody(requestBody).withInput(streamingInputOutputOperationRequest), + asyncResponseTransformer); AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { @@ -1217,6 +1277,8 @@ public CompletableFuture streamingInputOutputOperation( public CompletableFuture streamingOutputOperation( StreamingOutputOperationRequest streamingOutputOperationRequest, AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingOutputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingOutputOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -1242,8 +1304,8 @@ public CompletableFuture streamingOutputOperation( .withOperationName("StreamingOutputOperation") .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)) .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(streamingOutputOperationRequest), - asyncResponseTransformer); + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(streamingOutputOperationRequest), asyncResponseTransformer); AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { if (e != null) { @@ -1307,8 +1369,8 @@ private T applySignerOverride(T request, Signer signer) } Consumer signerOverride = b -> b.signer(signer).build(); AwsRequestOverrideConfiguration overrideConfiguration = request.overrideConfiguration() - .map(c -> c.toBuilder().applyMutation(signerOverride).build()) - .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(signerOverride).build())); + .map(c -> c.toBuilder().applyMutation(signerOverride).build()) + .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(signerOverride).build())); return (T) request.toBuilder().overrideConfiguration(overrideConfiguration).build(); } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-client-class.java index a8cc9e5e5b02..116cbd0de9ab 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-client-class.java @@ -2,6 +2,7 @@ import java.util.Collections; import java.util.List; +import java.util.function.BiFunction; import java.util.function.Consumer; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.SdkInternalApi; @@ -12,8 +13,13 @@ import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.CredentialType; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.client.handler.SyncClientHandler; import software.amazon.awssdk.core.exception.SdkClientException; @@ -35,6 +41,7 @@ import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.JsonOperationMetadata; +import software.amazon.awssdk.services.json.internal.JsonServiceClientConfigurationBuilder; import software.amazon.awssdk.services.json.model.APostOperationRequest; import software.amazon.awssdk.services.json.model.APostOperationResponse; import software.amazon.awssdk.services.json.model.APostOperationWithOutputRequest; @@ -98,11 +105,24 @@ final class DefaultJsonClient implements JsonClient { private final JsonServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + protected DefaultJsonClient(JsonServiceClientConfiguration serviceClientConfiguration, SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsSyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + JsonServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = JsonServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(AwsJsonProtocolFactory.builder()).build(); } @@ -137,6 +157,8 @@ public APostOperationResponse aPostOperation(APostOperationRequest aPostOperatio HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -152,7 +174,8 @@ public APostOperationResponse aPostOperation(APostOperationRequest aPostOperatio return clientHandler.execute(new ClientExecutionParams() .withOperationName("APostOperation").withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler).hostPrefixExpression(resolvedHostExpression) - .withInput(aPostOperationRequest).withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration).withInput(aPostOperationRequest) + .withMetricCollector(apiCallMetricCollector) .withMarshaller(new APostOperationRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -191,6 +214,8 @@ public APostOperationWithOutputResponse aPostOperationWithOutput( HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationWithOutputRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationWithOutputRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -202,8 +227,8 @@ public APostOperationWithOutputResponse aPostOperationWithOutput( return clientHandler .execute(new ClientExecutionParams() .withOperationName("APostOperationWithOutput").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(aPostOperationWithOutputRequest) - .withMetricCollector(apiCallMetricCollector) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(aPostOperationWithOutputRequest).withMetricCollector(apiCallMetricCollector) .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -238,6 +263,8 @@ public BearerAuthOperationResponse bearerAuthOperation(BearerAuthOperationReques HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(bearerAuthOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, bearerAuthOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -249,7 +276,8 @@ public BearerAuthOperationResponse bearerAuthOperation(BearerAuthOperationReques return clientHandler.execute(new ClientExecutionParams() .withOperationName("BearerAuthOperation").withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler).credentialType(CredentialType.TOKEN) - .withInput(bearerAuthOperationRequest).withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration).withInput(bearerAuthOperationRequest) + .withMetricCollector(apiCallMetricCollector) .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -284,6 +312,8 @@ public GetOperationWithChecksumResponse getOperationWithChecksum( HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getOperationWithChecksumRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -297,6 +327,7 @@ public GetOperationWithChecksumResponse getOperationWithChecksum( .withOperationName("GetOperationWithChecksum") .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withInput(getOperationWithChecksumRequest) .withMetricCollector(apiCallMetricCollector) .putExecutionAttribute( @@ -342,6 +373,8 @@ public GetWithoutRequiredMembersResponse getWithoutRequiredMembers( HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getWithoutRequiredMembersRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getWithoutRequiredMembersRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -353,8 +386,8 @@ public GetWithoutRequiredMembersResponse getWithoutRequiredMembers( return clientHandler .execute(new ClientExecutionParams() .withOperationName("GetWithoutRequiredMembers").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(getWithoutRequiredMembersRequest) - .withMetricCollector(apiCallMetricCollector) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(getWithoutRequiredMembersRequest).withMetricCollector(apiCallMetricCollector) .withMarshaller(new GetWithoutRequiredMembersRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -389,6 +422,8 @@ public OperationWithChecksumRequiredResponse operationWithChecksumRequired( HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithChecksumRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -402,6 +437,7 @@ public OperationWithChecksumRequiredResponse operationWithChecksumRequired( .withOperationName("OperationWithChecksumRequired") .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withInput(operationWithChecksumRequiredRequest) .withMetricCollector(apiCallMetricCollector) .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, @@ -440,6 +476,8 @@ public OperationWithRequestCompressionResponse operationWithRequestCompression( HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithRequestCompressionRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -453,6 +491,7 @@ public OperationWithRequestCompressionResponse operationWithRequestCompression( .withOperationName("OperationWithRequestCompression") .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withInput(operationWithRequestCompressionRequest) .withMetricCollector(apiCallMetricCollector) .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, @@ -491,6 +530,8 @@ public PaginatedOperationWithResultKeyResponse paginatedOperationWithResultKey( HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + paginatedOperationWithResultKeyRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, paginatedOperationWithResultKeyRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -502,8 +543,8 @@ public PaginatedOperationWithResultKeyResponse paginatedOperationWithResultKey( return clientHandler .execute(new ClientExecutionParams() .withOperationName("PaginatedOperationWithResultKey").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(paginatedOperationWithResultKeyRequest) - .withMetricCollector(apiCallMetricCollector) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(paginatedOperationWithResultKeyRequest).withMetricCollector(apiCallMetricCollector) .withMarshaller(new PaginatedOperationWithResultKeyRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -538,6 +579,8 @@ public PaginatedOperationWithoutResultKeyResponse paginatedOperationWithoutResul HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + paginatedOperationWithoutResultKeyRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, paginatedOperationWithoutResultKeyRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -549,8 +592,8 @@ public PaginatedOperationWithoutResultKeyResponse paginatedOperationWithoutResul return clientHandler .execute(new ClientExecutionParams() .withOperationName("PaginatedOperationWithoutResultKey").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(paginatedOperationWithoutResultKeyRequest) - .withMetricCollector(apiCallMetricCollector) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(paginatedOperationWithoutResultKeyRequest).withMetricCollector(apiCallMetricCollector) .withMarshaller(new PaginatedOperationWithoutResultKeyRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -611,6 +654,8 @@ public ReturnT putOperationWithChecksum(PutOperationWithChecksumReques HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(putOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, putOperationWithChecksumRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -624,6 +669,7 @@ public ReturnT putOperationWithChecksum(PutOperationWithChecksumReques .withOperationName("PutOperationWithChecksum") .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withInput(putOperationWithChecksumRequest) .withMetricCollector(apiCallMetricCollector) .putExecutionAttribute( @@ -680,6 +726,8 @@ public StreamingInputOperationResponse streamingInputOperation(StreamingInputOpe HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingInputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -693,6 +741,7 @@ public StreamingInputOperationResponse streamingInputOperation(StreamingInputOpe .withOperationName("StreamingInputOperation") .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withInput(streamingInputOperationRequest) .withMetricCollector(apiCallMetricCollector) .withRequestBody(requestBody) @@ -745,7 +794,7 @@ public ReturnT streamingInputOutputOperation( ResponseTransformer responseTransformer) throws AwsServiceException, SdkClientException, JsonException { streamingInputOutputOperationRequest = applySignerOverride(streamingInputOutputOperationRequest, - Aws4UnsignedPayloadSigner.create()); + Aws4UnsignedPayloadSigner.create()); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(true) .isPayloadJson(false).build(); @@ -754,6 +803,8 @@ public ReturnT streamingInputOutputOperation( HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + streamingInputOutputOperationRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOutputOperationRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -767,6 +818,7 @@ public ReturnT streamingInputOutputOperation( .withOperationName("StreamingInputOutputOperation") .withResponseHandler(responseHandler) .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) .withInput(streamingInputOutputOperationRequest) .withMetricCollector(apiCallMetricCollector) .withRequestBody(requestBody) @@ -816,6 +868,8 @@ public ReturnT streamingOutputOperation(StreamingOutputOperationReques HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, operationMetadata); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingOutputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingOutputOperationRequest .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector @@ -827,8 +881,8 @@ public ReturnT streamingOutputOperation(StreamingOutputOperationReques return clientHandler.execute( new ClientExecutionParams() .withOperationName("StreamingOutputOperation").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(streamingOutputOperationRequest) - .withMetricCollector(apiCallMetricCollector) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(streamingOutputOperationRequest).withMetricCollector(apiCallMetricCollector) .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)), responseTransformer); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -849,8 +903,8 @@ private T applySignerOverride(T request, Signer signer) } Consumer signerOverride = b -> b.signer(signer).build(); AwsRequestOverrideConfiguration overrideConfiguration = request.overrideConfiguration() - .map(c -> c.toBuilder().applyMutation(signerOverride).build()) - .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(signerOverride).build())); + .map(c -> c.toBuilder().applyMutation(signerOverride).build()) + .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(signerOverride).build())); return (T) request.toBuilder().overrideConfiguration(overrideConfiguration).build(); } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-async-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-async-client-class.java index b0ca9683c0c5..538e5123efa6 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-async-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-async-client-class.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ScheduledExecutorService; +import java.util.function.BiFunction; import java.util.function.Consumer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,11 +19,16 @@ import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.CredentialType; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.async.AsyncRequestBody; import software.amazon.awssdk.core.async.AsyncResponseTransformer; import software.amazon.awssdk.core.async.AsyncResponseTransformerUtils; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.AsyncClientHandler; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.http.HttpResponseHandler; @@ -38,6 +44,7 @@ import software.amazon.awssdk.metrics.NoOpMetricCollector; import software.amazon.awssdk.protocols.core.ExceptionMetadata; import software.amazon.awssdk.protocols.query.AwsQueryProtocolFactory; +import software.amazon.awssdk.services.query.internal.QueryServiceClientConfigurationBuilder; import software.amazon.awssdk.services.query.model.APostOperationRequest; import software.amazon.awssdk.services.query.model.APostOperationResponse; import software.amazon.awssdk.services.query.model.APostOperationWithOutputRequest; @@ -99,13 +106,26 @@ final class DefaultQueryAsyncClient implements QueryAsyncClient { private final QueryServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + private final ScheduledExecutorService executorService; protected DefaultQueryAsyncClient(QueryServiceClientConfiguration serviceClientConfiguration, - SdkClientConfiguration clientConfiguration) { + SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsAsyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + QueryServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = QueryServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(); this.executorService = clientConfiguration.option(SdkClientOption.SCHEDULED_EXECUTOR_SERVICE); } @@ -135,28 +155,30 @@ protected DefaultQueryAsyncClient(QueryServiceClientConfiguration serviceClientC */ @Override public CompletableFuture aPostOperation(APostOperationRequest aPostOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperation"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(APostOperationResponse::builder); + .createResponseHandler(APostOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); String hostPrefix = "foo-"; String resolvedHostExpression = "foo-"; CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("APostOperation") - .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).hostPrefixExpression(resolvedHostExpression) - .withInput(aPostOperationRequest)); + .execute(new ClientExecutionParams() + .withOperationName("APostOperation") + .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .hostPrefixExpression(resolvedHostExpression).withInput(aPostOperationRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -193,26 +215,29 @@ public CompletableFuture aPostOperation(APostOperationRe */ @Override public CompletableFuture aPostOperationWithOutput( - APostOperationWithOutputRequest aPostOperationWithOutputRequest) { + APostOperationWithOutputRequest aPostOperationWithOutputRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationWithOutputRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationWithOutputRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperationWithOutput"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(APostOperationWithOutputResponse::builder); + .createResponseHandler(APostOperationWithOutputResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("APostOperationWithOutput") - .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(aPostOperationWithOutputRequest)); + .execute(new ClientExecutionParams() + .withOperationName("APostOperationWithOutput") + .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(aPostOperationWithOutputRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -245,28 +270,30 @@ public CompletableFuture aPostOperationWithOut */ @Override public CompletableFuture bearerAuthOperation( - BearerAuthOperationRequest bearerAuthOperationRequest) { + BearerAuthOperationRequest bearerAuthOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(bearerAuthOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, bearerAuthOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "BearerAuthOperation"); bearerAuthOperationRequest = applySignerOverride(bearerAuthOperationRequest, BearerTokenSigner.create()); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(BearerAuthOperationResponse::builder); + .createResponseHandler(BearerAuthOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("BearerAuthOperation") - .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .credentialType(CredentialType.TOKEN).withMetricCollector(apiCallMetricCollector) - .withInput(bearerAuthOperationRequest)); + .execute(new ClientExecutionParams() + .withOperationName("BearerAuthOperation") + .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .credentialType(CredentialType.TOKEN).withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector).withInput(bearerAuthOperationRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -299,32 +326,35 @@ public CompletableFuture bearerAuthOperation( */ @Override public CompletableFuture getOperationWithChecksum( - GetOperationWithChecksumRequest getOperationWithChecksumRequest) { + GetOperationWithChecksumRequest getOperationWithChecksumRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "GetOperationWithChecksum"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(GetOperationWithChecksumResponse::builder); + .createResponseHandler(GetOperationWithChecksumResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("GetOperationWithChecksum") - .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(true) - .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) - .isRequestStreaming(false).build()).withInput(getOperationWithChecksumRequest)); + .execute(new ClientExecutionParams() + .withOperationName("GetOperationWithChecksum") + .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(true) + .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) + .isRequestStreaming(false).build()).withInput(getOperationWithChecksumRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -358,29 +388,32 @@ public CompletableFuture getOperationWithCheck */ @Override public CompletableFuture operationWithChecksumRequired( - OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) { + OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithChecksumRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); + operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithChecksumRequired"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithChecksumRequiredResponse::builder); + .createResponseHandler(OperationWithChecksumRequiredResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithChecksumRequired") - .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, - HttpChecksumRequired.create()).withInput(operationWithChecksumRequiredRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithChecksumRequired") + .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, + HttpChecksumRequired.create()).withInput(operationWithChecksumRequiredRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -413,26 +446,29 @@ public CompletableFuture operationWithChe */ @Override public CompletableFuture operationWithContextParam( - OperationWithContextParamRequest operationWithContextParamRequest) { + OperationWithContextParamRequest operationWithContextParamRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(operationWithContextParamRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithContextParamRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithContextParam"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithContextParamResponse::builder); + .createResponseHandler(OperationWithContextParamResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithContextParam") - .withMarshaller(new OperationWithContextParamRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(operationWithContextParamRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithContextParam") + .withMarshaller(new OperationWithContextParamRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(operationWithContextParamRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -465,28 +501,30 @@ public CompletableFuture operationWithContext */ @Override public CompletableFuture operationWithNoneAuthType( - OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) { + OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(operationWithNoneAuthTypeRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithNoneAuthTypeRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithNoneAuthType"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithNoneAuthTypeResponse::builder); + .createResponseHandler(OperationWithNoneAuthTypeResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithNoneAuthType") - .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.IS_NONE_AUTH_TYPE_REQUEST, false) - .withInput(operationWithNoneAuthTypeRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithNoneAuthType") + .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.IS_NONE_AUTH_TYPE_REQUEST, false) + .withInput(operationWithNoneAuthTypeRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -520,30 +558,33 @@ public CompletableFuture operationWithNoneAut */ @Override public CompletableFuture operationWithRequestCompression( - OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithRequestCompressionRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); + operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithRequestCompression"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithRequestCompressionResponse::builder); + .createResponseHandler(OperationWithRequestCompressionResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithRequestCompression") - .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, - RequestCompression.builder().encodings("gzip").isStreaming(false).build()) - .withInput(operationWithRequestCompressionRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithRequestCompression") + .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, + RequestCompression.builder().encodings("gzip").isStreaming(false).build()) + .withInput(operationWithRequestCompressionRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -577,26 +618,29 @@ public CompletableFuture operationWithR */ @Override public CompletableFuture operationWithStaticContextParams( - OperationWithStaticContextParamsRequest operationWithStaticContextParamsRequest) { + OperationWithStaticContextParamsRequest operationWithStaticContextParamsRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithStaticContextParamsRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithStaticContextParamsRequest.overrideConfiguration().orElse(null)); + operationWithStaticContextParamsRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithStaticContextParams"); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithStaticContextParamsResponse::builder); + .createResponseHandler(OperationWithStaticContextParamsResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithStaticContextParams") - .withMarshaller(new OperationWithStaticContextParamsRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(operationWithStaticContextParamsRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithStaticContextParams") + .withMarshaller(new OperationWithStaticContextParamsRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(operationWithStaticContextParamsRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -647,17 +691,19 @@ public CompletableFuture operationWith */ @Override public CompletableFuture putOperationWithChecksum( - PutOperationWithChecksumRequest putOperationWithChecksumRequest, AsyncRequestBody requestBody, - AsyncResponseTransformer asyncResponseTransformer) { + PutOperationWithChecksumRequest putOperationWithChecksumRequest, AsyncRequestBody requestBody, + AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(putOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, putOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "PutOperationWithChecksum"); Pair, CompletableFuture> pair = AsyncResponseTransformerUtils - .wrapWithEndOfStreamFuture(asyncResponseTransformer); + .wrapWithEndOfStreamFuture(asyncResponseTransformer); asyncResponseTransformer = pair.left(); CompletableFuture endOfStreamFuture = pair.right(); if (!isSignerOverridden(clientConfiguration)) { @@ -665,33 +711,34 @@ public CompletableFuture putOperationWithChecksum( } HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(PutOperationWithChecksumResponse::builder); + .createResponseHandler(PutOperationWithChecksumResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler.execute( - new ClientExecutionParams() - .withOperationName("PutOperationWithChecksum") - .withMarshaller( - AsyncStreamingRequestMarshaller.builder() - .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) - .asyncRequestBody(requestBody).build()) - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(false) - .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) - .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) - .build()).withAsyncRequestBody(requestBody) - .withInput(putOperationWithChecksumRequest), asyncResponseTransformer); + new ClientExecutionParams() + .withOperationName("PutOperationWithChecksum") + .withMarshaller( + AsyncStreamingRequestMarshaller.builder() + .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) + .asyncRequestBody(requestBody).build()) + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(false) + .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) + .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) + .build()).withAsyncRequestBody(requestBody) + .withInput(putOperationWithChecksumRequest), asyncResponseTransformer); CompletableFuture whenCompleteFuture = null; AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { if (e != null) { runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(e)); + () -> finalAsyncResponseTransformer.exceptionOccurred(e)); } endOfStreamFuture.whenComplete((r2, e2) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -701,7 +748,7 @@ public CompletableFuture putOperationWithChecksum( } catch (Throwable t) { AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(t)); + () -> finalAsyncResponseTransformer.exceptionOccurred(t)); metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); return CompletableFutureUtils.failedFuture(t); } @@ -733,11 +780,13 @@ public CompletableFuture putOperationWithChecksum( */ @Override public CompletableFuture streamingInputOperation( - StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) { + StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingInputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingInputOperation"); @@ -746,19 +795,20 @@ public CompletableFuture streamingInputOperatio } HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(StreamingInputOperationResponse::builder); + .createResponseHandler(StreamingInputOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("StreamingInputOperation") - .withMarshaller( - AsyncStreamingRequestMarshaller.builder() - .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) - .asyncRequestBody(requestBody).build()).withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withMetricCollector(apiCallMetricCollector) - .withAsyncRequestBody(requestBody).withInput(streamingInputOperationRequest)); + .execute(new ClientExecutionParams() + .withOperationName("StreamingInputOperation") + .withMarshaller( + AsyncStreamingRequestMarshaller.builder() + .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) + .asyncRequestBody(requestBody).build()).withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector).withAsyncRequestBody(requestBody) + .withInput(streamingInputOperationRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -796,38 +846,40 @@ public CompletableFuture streamingInputOperatio */ @Override public CompletableFuture streamingOutputOperation( - StreamingOutputOperationRequest streamingOutputOperationRequest, - AsyncResponseTransformer asyncResponseTransformer) { + StreamingOutputOperationRequest streamingOutputOperationRequest, + AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingOutputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingOutputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingOutputOperation"); Pair, CompletableFuture> pair = AsyncResponseTransformerUtils - .wrapWithEndOfStreamFuture(asyncResponseTransformer); + .wrapWithEndOfStreamFuture(asyncResponseTransformer); asyncResponseTransformer = pair.left(); CompletableFuture endOfStreamFuture = pair.right(); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(StreamingOutputOperationResponse::builder); + .createResponseHandler(StreamingOutputOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler.execute( - new ClientExecutionParams() - .withOperationName("StreamingOutputOperation") - .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(streamingOutputOperationRequest), - asyncResponseTransformer); + new ClientExecutionParams() + .withOperationName("StreamingOutputOperation") + .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(streamingOutputOperationRequest), asyncResponseTransformer); CompletableFuture whenCompleteFuture = null; AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { if (e != null) { runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(e)); + () -> finalAsyncResponseTransformer.exceptionOccurred(e)); } endOfStreamFuture.whenComplete((r2, e2) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -837,7 +889,7 @@ public CompletableFuture streamingOutputOperation( } catch (Throwable t) { AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(t)); + () -> finalAsyncResponseTransformer.exceptionOccurred(t)); metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); return CompletableFutureUtils.failedFuture(t); } @@ -860,15 +912,15 @@ public final String serviceName() { private AwsQueryProtocolFactory init() { return AwsQueryProtocolFactory - .builder() - .registerModeledException( - ExceptionMetadata.builder().errorCode("InvalidInput") - .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) - .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(QueryException::builder).build(); + .builder() + .registerModeledException( + ExceptionMetadata.builder().errorCode("InvalidInput") + .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) + .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(QueryException::builder).build(); } private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, - RequestOverrideConfiguration requestOverrideConfiguration) { + RequestOverrideConfiguration requestOverrideConfiguration) { List publishers = null; if (requestOverrideConfiguration != null) { publishers = requestOverrideConfiguration.metricPublishers(); @@ -888,8 +940,8 @@ private T applySignerOverride(T request, Signer signer) } Consumer signerOverride = b -> b.signer(signer).build(); AwsRequestOverrideConfiguration overrideConfiguration = request.overrideConfiguration() - .map(c -> c.toBuilder().applyMutation(signerOverride).build()) - .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(signerOverride).build())); + .map(c -> c.toBuilder().applyMutation(signerOverride).build()) + .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(signerOverride).build())); return (T) request.toBuilder().overrideConfiguration(overrideConfiguration).build(); } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-client-class.java index 0ca5d7837899..a71e182db016 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-client-class.java @@ -2,6 +2,7 @@ import java.util.Collections; import java.util.List; +import java.util.function.BiFunction; import java.util.function.Consumer; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.SdkInternalApi; @@ -11,8 +12,13 @@ import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.CredentialType; import software.amazon.awssdk.core.RequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.client.handler.SyncClientHandler; import software.amazon.awssdk.core.exception.SdkClientException; @@ -31,6 +37,7 @@ import software.amazon.awssdk.metrics.NoOpMetricCollector; import software.amazon.awssdk.protocols.core.ExceptionMetadata; import software.amazon.awssdk.protocols.query.AwsQueryProtocolFactory; +import software.amazon.awssdk.services.query.internal.QueryServiceClientConfigurationBuilder; import software.amazon.awssdk.services.query.model.APostOperationRequest; import software.amazon.awssdk.services.query.model.APostOperationResponse; import software.amazon.awssdk.services.query.model.APostOperationWithOutputRequest; @@ -91,11 +98,24 @@ final class DefaultQueryClient implements QueryClient { private final QueryServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + protected DefaultQueryClient(QueryServiceClientConfiguration serviceClientConfiguration, - SdkClientConfiguration clientConfiguration) { + SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsSyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + QueryServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = QueryServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(); } @@ -121,16 +141,18 @@ protected DefaultQueryClient(QueryServiceClientConfiguration serviceClientConfig */ @Override public APostOperationResponse aPostOperation(APostOperationRequest aPostOperationRequest) throws InvalidInputException, - AwsServiceException, SdkClientException, QueryException { + AwsServiceException, SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(APostOperationResponse::builder); + .createResponseHandler(APostOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperation"); @@ -138,10 +160,11 @@ public APostOperationResponse aPostOperation(APostOperationRequest aPostOperatio String resolvedHostExpression = "foo-"; return clientHandler.execute(new ClientExecutionParams() - .withOperationName("APostOperation").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).hostPrefixExpression(resolvedHostExpression) - .withInput(aPostOperationRequest).withMetricCollector(apiCallMetricCollector) - .withMarshaller(new APostOperationRequestMarshaller(protocolFactory))); + .withOperationName("APostOperation").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).hostPrefixExpression(resolvedHostExpression) + .withRequestConfiguration(clientConfiguration).withInput(aPostOperationRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new APostOperationRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -169,27 +192,29 @@ public APostOperationResponse aPostOperation(APostOperationRequest aPostOperatio */ @Override public APostOperationWithOutputResponse aPostOperationWithOutput( - APostOperationWithOutputRequest aPostOperationWithOutputRequest) throws InvalidInputException, AwsServiceException, - SdkClientException, QueryException { + APostOperationWithOutputRequest aPostOperationWithOutputRequest) throws InvalidInputException, AwsServiceException, + SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(APostOperationWithOutputResponse::builder); + .createResponseHandler(APostOperationWithOutputResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationWithOutputRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationWithOutputRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperationWithOutput"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("APostOperationWithOutput").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(aPostOperationWithOutputRequest) - .withMetricCollector(apiCallMetricCollector) - .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("APostOperationWithOutput").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(aPostOperationWithOutputRequest).withMetricCollector(apiCallMetricCollector) + .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -213,26 +238,29 @@ public APostOperationWithOutputResponse aPostOperationWithOutput( */ @Override public BearerAuthOperationResponse bearerAuthOperation(BearerAuthOperationRequest bearerAuthOperationRequest) - throws AwsServiceException, SdkClientException, QueryException { + throws AwsServiceException, SdkClientException, QueryException { bearerAuthOperationRequest = applySignerOverride(bearerAuthOperationRequest, BearerTokenSigner.create()); HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(BearerAuthOperationResponse::builder); + .createResponseHandler(BearerAuthOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(bearerAuthOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, bearerAuthOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "BearerAuthOperation"); return clientHandler.execute(new ClientExecutionParams() - .withOperationName("BearerAuthOperation").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).credentialType(CredentialType.TOKEN) - .withInput(bearerAuthOperationRequest).withMetricCollector(apiCallMetricCollector) - .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory))); + .withOperationName("BearerAuthOperation").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).credentialType(CredentialType.TOKEN) + .withRequestConfiguration(clientConfiguration).withInput(bearerAuthOperationRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -256,34 +284,37 @@ public BearerAuthOperationResponse bearerAuthOperation(BearerAuthOperationReques */ @Override public GetOperationWithChecksumResponse getOperationWithChecksum( - GetOperationWithChecksumRequest getOperationWithChecksumRequest) throws AwsServiceException, SdkClientException, - QueryException { + GetOperationWithChecksumRequest getOperationWithChecksumRequest) throws AwsServiceException, SdkClientException, + QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(GetOperationWithChecksumResponse::builder); + .createResponseHandler(GetOperationWithChecksumResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "GetOperationWithChecksum"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("GetOperationWithChecksum") - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withInput(getOperationWithChecksumRequest) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(true) - .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) - .isRequestStreaming(false).build()) - .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("GetOperationWithChecksum") + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withInput(getOperationWithChecksumRequest) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(true) + .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) + .isRequestStreaming(false).build()) + .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -307,31 +338,34 @@ public GetOperationWithChecksumResponse getOperationWithChecksum( */ @Override public OperationWithChecksumRequiredResponse operationWithChecksumRequired( - OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) throws AwsServiceException, - SdkClientException, QueryException { + OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) throws AwsServiceException, + SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithChecksumRequiredResponse::builder); + .createResponseHandler(OperationWithChecksumRequiredResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithChecksumRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); + operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithChecksumRequired"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithChecksumRequired") - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withInput(operationWithChecksumRequiredRequest) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, - HttpChecksumRequired.create()) - .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithChecksumRequired") + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withInput(operationWithChecksumRequiredRequest) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, + HttpChecksumRequired.create()) + .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -355,27 +389,29 @@ public OperationWithChecksumRequiredResponse operationWithChecksumRequired( */ @Override public OperationWithContextParamResponse operationWithContextParam( - OperationWithContextParamRequest operationWithContextParamRequest) throws AwsServiceException, SdkClientException, - QueryException { + OperationWithContextParamRequest operationWithContextParamRequest) throws AwsServiceException, SdkClientException, + QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithContextParamResponse::builder); + .createResponseHandler(OperationWithContextParamResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(operationWithContextParamRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithContextParamRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithContextParam"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithContextParam").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(operationWithContextParamRequest) - .withMetricCollector(apiCallMetricCollector) - .withMarshaller(new OperationWithContextParamRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithContextParam").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(operationWithContextParamRequest).withMetricCollector(apiCallMetricCollector) + .withMarshaller(new OperationWithContextParamRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -399,28 +435,30 @@ public OperationWithContextParamResponse operationWithContextParam( */ @Override public OperationWithNoneAuthTypeResponse operationWithNoneAuthType( - OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) throws AwsServiceException, SdkClientException, - QueryException { + OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) throws AwsServiceException, SdkClientException, + QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithNoneAuthTypeResponse::builder); + .createResponseHandler(OperationWithNoneAuthTypeResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(operationWithNoneAuthTypeRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithNoneAuthTypeRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithNoneAuthType"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithNoneAuthType").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(operationWithNoneAuthTypeRequest) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.IS_NONE_AUTH_TYPE_REQUEST, false) - .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithNoneAuthType").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(operationWithNoneAuthTypeRequest).withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.IS_NONE_AUTH_TYPE_REQUEST, false) + .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -444,31 +482,34 @@ public OperationWithNoneAuthTypeResponse operationWithNoneAuthType( */ @Override public OperationWithRequestCompressionResponse operationWithRequestCompression( - OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) throws AwsServiceException, - SdkClientException, QueryException { + OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) throws AwsServiceException, + SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithRequestCompressionResponse::builder); + .createResponseHandler(OperationWithRequestCompressionResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithRequestCompressionRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); + operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithRequestCompression"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithRequestCompression") - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withInput(operationWithRequestCompressionRequest) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, - RequestCompression.builder().encodings("gzip").isStreaming(false).build()) - .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithRequestCompression") + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withInput(operationWithRequestCompressionRequest) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, + RequestCompression.builder().encodings("gzip").isStreaming(false).build()) + .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -492,27 +533,29 @@ public OperationWithRequestCompressionResponse operationWithRequestCompression( */ @Override public OperationWithStaticContextParamsResponse operationWithStaticContextParams( - OperationWithStaticContextParamsRequest operationWithStaticContextParamsRequest) throws AwsServiceException, - SdkClientException, QueryException { + OperationWithStaticContextParamsRequest operationWithStaticContextParamsRequest) throws AwsServiceException, + SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(OperationWithStaticContextParamsResponse::builder); + .createResponseHandler(OperationWithStaticContextParamsResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithStaticContextParamsRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithStaticContextParamsRequest.overrideConfiguration().orElse(null)); + operationWithStaticContextParamsRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithStaticContextParams"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithStaticContextParams").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(operationWithStaticContextParamsRequest) - .withMetricCollector(apiCallMetricCollector) - .withMarshaller(new OperationWithStaticContextParamsRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithStaticContextParams").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(operationWithStaticContextParamsRequest).withMetricCollector(apiCallMetricCollector) + .withMarshaller(new OperationWithStaticContextParamsRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -526,11 +569,11 @@ public OperationWithStaticContextParamsResponse operationWithStaticContextParams * The content to send to the service. A {@link RequestBody} can be created using one of several factory * methods for various sources of data. For example, to create a request body from a file you can do the * following. - * + * *
      * {@code RequestBody.fromFile(new File("myfile.txt"))}
      * 
- * + * * See documentation in {@link RequestBody} for additional details and which sources of data are supported. * The service documentation for the request content is as follows ' *

@@ -562,39 +605,42 @@ public OperationWithStaticContextParamsResponse operationWithStaticContextParams */ @Override public ReturnT putOperationWithChecksum(PutOperationWithChecksumRequest putOperationWithChecksumRequest, - RequestBody requestBody, ResponseTransformer responseTransformer) - throws AwsServiceException, SdkClientException, QueryException { + RequestBody requestBody, ResponseTransformer responseTransformer) + throws AwsServiceException, SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(PutOperationWithChecksumResponse::builder); + .createResponseHandler(PutOperationWithChecksumResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(putOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, putOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "PutOperationWithChecksum"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("PutOperationWithChecksum") - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withInput(putOperationWithChecksumRequest) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(false) - .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) - .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) - .build()) - .withRequestBody(requestBody) - .withMarshaller( - StreamingRequestMarshaller.builder() - .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) - .requestBody(requestBody).build())); + .execute(new ClientExecutionParams() + .withOperationName("PutOperationWithChecksum") + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withInput(putOperationWithChecksumRequest) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(false) + .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) + .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) + .build()) + .withRequestBody(requestBody) + .withMarshaller( + StreamingRequestMarshaller.builder() + .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) + .requestBody(requestBody).build())); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -608,11 +654,11 @@ public ReturnT putOperationWithChecksum(PutOperationWithChecksumReques * The content to send to the service. A {@link RequestBody} can be created using one of several factory * methods for various sources of data. For example, to create a request body from a file you can do the * following. - * + * *

      * {@code RequestBody.fromFile(new File("myfile.txt"))}
      * 
- * + * * See documentation in {@link RequestBody} for additional details and which sources of data are supported. * The service documentation for the request content is as follows 'This be a stream' * @return Result of the StreamingInputOperation operation returned by the service. @@ -629,32 +675,35 @@ public ReturnT putOperationWithChecksum(PutOperationWithChecksumReques */ @Override public StreamingInputOperationResponse streamingInputOperation(StreamingInputOperationRequest streamingInputOperationRequest, - RequestBody requestBody) throws AwsServiceException, SdkClientException, QueryException { + RequestBody requestBody) throws AwsServiceException, SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(StreamingInputOperationResponse::builder); + .createResponseHandler(StreamingInputOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingInputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingInputOperation"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("StreamingInputOperation") - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withInput(streamingInputOperationRequest) - .withMetricCollector(apiCallMetricCollector) - .withRequestBody(requestBody) - .withMarshaller( - StreamingRequestMarshaller.builder() - .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) - .requestBody(requestBody).build())); + .execute(new ClientExecutionParams() + .withOperationName("StreamingInputOperation") + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withInput(streamingInputOperationRequest) + .withMetricCollector(apiCallMetricCollector) + .withRequestBody(requestBody) + .withMarshaller( + StreamingRequestMarshaller.builder() + .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) + .requestBody(requestBody).build())); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -685,27 +734,29 @@ public StreamingInputOperationResponse streamingInputOperation(StreamingInputOpe */ @Override public ReturnT streamingOutputOperation(StreamingOutputOperationRequest streamingOutputOperationRequest, - ResponseTransformer responseTransformer) throws AwsServiceException, - SdkClientException, QueryException { + ResponseTransformer responseTransformer) throws AwsServiceException, + SdkClientException, QueryException { HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(StreamingOutputOperationResponse::builder); + .createResponseHandler(StreamingOutputOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingOutputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingOutputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingOutputOperation"); return clientHandler.execute( - new ClientExecutionParams() - .withOperationName("StreamingOutputOperation").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(streamingOutputOperationRequest) - .withMetricCollector(apiCallMetricCollector) - .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)), responseTransformer); + new ClientExecutionParams() + .withOperationName("StreamingOutputOperation").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(streamingOutputOperationRequest).withMetricCollector(apiCallMetricCollector) + .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)), responseTransformer); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -730,8 +781,8 @@ private T applySignerOverride(T request, Signer signer) } Consumer signerOverride = b -> b.signer(signer).build(); AwsRequestOverrideConfiguration overrideConfiguration = request.overrideConfiguration() - .map(c -> c.toBuilder().applyMutation(signerOverride).build()) - .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(signerOverride).build())); + .map(c -> c.toBuilder().applyMutation(signerOverride).build()) + .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(signerOverride).build())); return (T) request.toBuilder().overrideConfiguration(overrideConfiguration).build(); } @@ -741,7 +792,7 @@ public final String serviceName() { } private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, - RequestOverrideConfiguration requestOverrideConfiguration) { + RequestOverrideConfiguration requestOverrideConfiguration) { List publishers = null; if (requestOverrideConfiguration != null) { publishers = requestOverrideConfiguration.metricPublishers(); @@ -757,11 +808,11 @@ private static List resolveMetricPublishers(SdkClientConfigurat private AwsQueryProtocolFactory init() { return AwsQueryProtocolFactory - .builder() - .registerModeledException( - ExceptionMetadata.builder().errorCode("InvalidInput") - .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) - .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(QueryException::builder).build(); + .builder() + .registerModeledException( + ExceptionMetadata.builder().errorCode("InvalidInput") + .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) + .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(QueryException::builder).build(); } @Override diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-xml-async-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-xml-async-client-class.java index 959bfd8618bf..a78e1d4a08b4 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-xml-async-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-xml-async-client-class.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import java.util.function.BiFunction; import java.util.function.Consumer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,13 +23,18 @@ import software.amazon.awssdk.core.CredentialType; import software.amazon.awssdk.core.RequestOverrideConfiguration; import software.amazon.awssdk.core.Response; +import software.amazon.awssdk.core.SdkPlugin; import software.amazon.awssdk.core.SdkPojoBuilder; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.async.AsyncRequestBody; import software.amazon.awssdk.core.async.AsyncResponseTransformer; import software.amazon.awssdk.core.async.AsyncResponseTransformerUtils; import software.amazon.awssdk.core.client.config.SdkAdvancedAsyncClientOption; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.AsyncClientHandler; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.http.HttpResponseHandler; @@ -45,6 +51,7 @@ import software.amazon.awssdk.protocols.core.ExceptionMetadata; import software.amazon.awssdk.protocols.xml.AwsXmlProtocolFactory; import software.amazon.awssdk.protocols.xml.XmlOperationMetadata; +import software.amazon.awssdk.services.xml.internal.XmlServiceClientConfigurationBuilder; import software.amazon.awssdk.services.xml.model.APostOperationRequest; import software.amazon.awssdk.services.xml.model.APostOperationResponse; import software.amazon.awssdk.services.xml.model.APostOperationWithOutputRequest; @@ -104,13 +111,26 @@ final class DefaultXmlAsyncClient implements XmlAsyncClient { private final XmlServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + private final Executor executor; protected DefaultXmlAsyncClient(XmlServiceClientConfiguration serviceClientConfiguration, - SdkClientConfiguration clientConfiguration) { + SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsAsyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + XmlServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = XmlServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(); this.executor = clientConfiguration.option(SdkAdvancedAsyncClientOption.FUTURE_COMPLETION_EXECUTOR); } @@ -140,26 +160,28 @@ protected DefaultXmlAsyncClient(XmlServiceClientConfiguration serviceClientConfi */ @Override public CompletableFuture aPostOperation(APostOperationRequest aPostOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperation"); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(APostOperationResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(APostOperationResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); String hostPrefix = "foo-"; String resolvedHostExpression = "foo-"; CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("APostOperation") - .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) - .withCombinedResponseHandler(responseHandler).hostPrefixExpression(resolvedHostExpression) - .withMetricCollector(apiCallMetricCollector).withInput(aPostOperationRequest)); + .execute(new ClientExecutionParams() + .withOperationName("APostOperation").withRequestConfiguration(clientConfiguration) + .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) + .withCombinedResponseHandler(responseHandler).hostPrefixExpression(resolvedHostExpression) + .withMetricCollector(apiCallMetricCollector).withInput(aPostOperationRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -197,25 +219,27 @@ public CompletableFuture aPostOperation(APostOperationRe */ @Override public CompletableFuture aPostOperationWithOutput( - APostOperationWithOutputRequest aPostOperationWithOutputRequest) { + APostOperationWithOutputRequest aPostOperationWithOutputRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationWithOutputRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationWithOutputRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperationWithOutput"); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(APostOperationWithOutputResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(APostOperationWithOutputResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("APostOperationWithOutput") - .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory)) - .withCombinedResponseHandler(responseHandler).withMetricCollector(apiCallMetricCollector) - .withInput(aPostOperationWithOutputRequest)); + .execute(new ClientExecutionParams() + .withOperationName("APostOperationWithOutput").withRequestConfiguration(clientConfiguration) + .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory)) + .withCombinedResponseHandler(responseHandler).withMetricCollector(apiCallMetricCollector) + .withInput(aPostOperationWithOutputRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -249,26 +273,28 @@ public CompletableFuture aPostOperationWithOut */ @Override public CompletableFuture bearerAuthOperation( - BearerAuthOperationRequest bearerAuthOperationRequest) { + BearerAuthOperationRequest bearerAuthOperationRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(bearerAuthOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, bearerAuthOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "BearerAuthOperation"); bearerAuthOperationRequest = applySignerOverride(bearerAuthOperationRequest, BearerTokenSigner.create()); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(BearerAuthOperationResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(BearerAuthOperationResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("BearerAuthOperation") - .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory)) - .withCombinedResponseHandler(responseHandler).credentialType(CredentialType.TOKEN) - .withMetricCollector(apiCallMetricCollector).withInput(bearerAuthOperationRequest)); + .execute(new ClientExecutionParams() + .withOperationName("BearerAuthOperation").withRequestConfiguration(clientConfiguration) + .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory)) + .withCombinedResponseHandler(responseHandler).credentialType(CredentialType.TOKEN) + .withMetricCollector(apiCallMetricCollector).withInput(bearerAuthOperationRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -302,48 +328,50 @@ public CompletableFuture bearerAuthOperation( */ @Override public CompletableFuture eventStreamOperation(EventStreamOperationRequest eventStreamOperationRequest, - EventStreamOperationResponseHandler asyncResponseHandler) { + EventStreamOperationResponseHandler asyncResponseHandler) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(eventStreamOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, eventStreamOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "EventStreamOperation"); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - EventStreamOperationResponse::builder, XmlOperationMetadata.builder().hasStreamingSuccessResponse(true) - .build()); + EventStreamOperationResponse::builder, XmlOperationMetadata.builder().hasStreamingSuccessResponse(true) + .build()); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); HttpResponseHandler eventResponseHandler = protocolFactory.createResponseHandler( - EventStreamTaggedUnionPojoSupplier.builder() - .putSdkPojoSupplier("EventPayloadEvent", EventStream::eventPayloadEventBuilder) - .putSdkPojoSupplier("NonEventPayloadEvent", EventStream::nonEventPayloadEventBuilder) - .putSdkPojoSupplier("SecondEventPayloadEvent", EventStream::secondEventPayloadEventBuilder) - .defaultSdkPojoSupplier(() -> new SdkPojoBuilder(EventStream.UNKNOWN)).build(), XmlOperationMetadata - .builder().hasStreamingSuccessResponse(false).build()); + EventStreamTaggedUnionPojoSupplier.builder() + .putSdkPojoSupplier("EventPayloadEvent", EventStream::eventPayloadEventBuilder) + .putSdkPojoSupplier("NonEventPayloadEvent", EventStream::nonEventPayloadEventBuilder) + .putSdkPojoSupplier("SecondEventPayloadEvent", EventStream::secondEventPayloadEventBuilder) + .defaultSdkPojoSupplier(() -> new SdkPojoBuilder(EventStream.UNKNOWN)).build(), XmlOperationMetadata + .builder().hasStreamingSuccessResponse(false).build()); CompletableFuture eventStreamTransformFuture = new CompletableFuture<>(); EventStreamAsyncResponseTransformer asyncResponseTransformer = EventStreamAsyncResponseTransformer - . builder().eventStreamResponseHandler(asyncResponseHandler) - .eventResponseHandler(eventResponseHandler).initialResponseHandler(responseHandler) - .exceptionResponseHandler(errorResponseHandler).future(eventStreamTransformFuture).executor(executor) - .serviceName(serviceName()).build(); + . builder().eventStreamResponseHandler(asyncResponseHandler) + .eventResponseHandler(eventResponseHandler).initialResponseHandler(responseHandler) + .exceptionResponseHandler(errorResponseHandler).future(eventStreamTransformFuture).executor(executor) + .serviceName(serviceName()).build(); RestEventStreamAsyncResponseTransformer restAsyncResponseTransformer = RestEventStreamAsyncResponseTransformer - . builder() - .eventStreamAsyncResponseTransformer(asyncResponseTransformer) - .eventStreamResponseHandler(asyncResponseHandler).build(); + . builder() + .eventStreamAsyncResponseTransformer(asyncResponseTransformer) + .eventStreamResponseHandler(asyncResponseHandler).build(); CompletableFuture executeFuture = clientHandler.execute( - new ClientExecutionParams() - .withOperationName("EventStreamOperation") - .withMarshaller(new EventStreamOperationRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(eventStreamOperationRequest), - restAsyncResponseTransformer); + new ClientExecutionParams() + .withOperationName("EventStreamOperation").withRequestConfiguration(clientConfiguration) + .withMarshaller(new EventStreamOperationRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withMetricCollector(apiCallMetricCollector).withInput(eventStreamOperationRequest), + restAsyncResponseTransformer); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { if (e != null) { runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> asyncResponseHandler.exceptionOccurred(e)); + () -> asyncResponseHandler.exceptionOccurred(e)); eventStreamTransformFuture.completeExceptionally(e); } metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -352,7 +380,7 @@ public CompletableFuture eventStreamOperation(EventStreamOperationRequest return CompletableFutureUtils.forwardExceptionTo(eventStreamTransformFuture, executeFuture); } catch (Throwable t) { runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> asyncResponseHandler.exceptionOccurred(t)); + () -> asyncResponseHandler.exceptionOccurred(t)); metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); return CompletableFutureUtils.failedFuture(t); } @@ -379,30 +407,33 @@ public CompletableFuture eventStreamOperation(EventStreamOperationRequest */ @Override public CompletableFuture getOperationWithChecksum( - GetOperationWithChecksumRequest getOperationWithChecksumRequest) { + GetOperationWithChecksumRequest getOperationWithChecksumRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "GetOperationWithChecksum"); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(GetOperationWithChecksumResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(GetOperationWithChecksumResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("GetOperationWithChecksum") - .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory)) - .withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(true) - .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) - .isRequestStreaming(false).build()).withInput(getOperationWithChecksumRequest)); + .execute(new ClientExecutionParams() + .withOperationName("GetOperationWithChecksum") + .withRequestConfiguration(clientConfiguration) + .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory)) + .withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(true) + .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) + .isRequestStreaming(false).build()).withInput(getOperationWithChecksumRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -437,27 +468,30 @@ public CompletableFuture getOperationWithCheck */ @Override public CompletableFuture operationWithChecksumRequired( - OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) { + OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithChecksumRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); + operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithChecksumRequired"); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(OperationWithChecksumRequiredResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(OperationWithChecksumRequiredResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithChecksumRequired") - .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory)) - .withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, - HttpChecksumRequired.create()).withInput(operationWithChecksumRequiredRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithChecksumRequired") + .withRequestConfiguration(clientConfiguration) + .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory)) + .withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, + HttpChecksumRequired.create()).withInput(operationWithChecksumRequiredRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -491,26 +525,28 @@ public CompletableFuture operationWithChe */ @Override public CompletableFuture operationWithNoneAuthType( - OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) { + OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(operationWithNoneAuthTypeRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithNoneAuthTypeRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithNoneAuthType"); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(OperationWithNoneAuthTypeResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(OperationWithNoneAuthTypeResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithNoneAuthType") - .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory)) - .withCombinedResponseHandler(responseHandler).withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.IS_NONE_AUTH_TYPE_REQUEST, false) - .withInput(operationWithNoneAuthTypeRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithNoneAuthType").withRequestConfiguration(clientConfiguration) + .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory)) + .withCombinedResponseHandler(responseHandler).withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.IS_NONE_AUTH_TYPE_REQUEST, false) + .withInput(operationWithNoneAuthTypeRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -545,28 +581,31 @@ public CompletableFuture operationWithNoneAut */ @Override public CompletableFuture operationWithRequestCompression( - OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithRequestCompressionRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); + operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithRequestCompression"); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(OperationWithRequestCompressionResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(OperationWithRequestCompressionResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithRequestCompression") - .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) - .withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, - RequestCompression.builder().encodings("gzip").isStreaming(false).build()) - .withInput(operationWithRequestCompressionRequest)); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithRequestCompression") + .withRequestConfiguration(clientConfiguration) + .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory)) + .withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, + RequestCompression.builder().encodings("gzip").isStreaming(false).build()) + .withInput(operationWithRequestCompressionRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -618,17 +657,19 @@ public CompletableFuture operationWithR */ @Override public CompletableFuture putOperationWithChecksum( - PutOperationWithChecksumRequest putOperationWithChecksumRequest, AsyncRequestBody requestBody, - AsyncResponseTransformer asyncResponseTransformer) { + PutOperationWithChecksumRequest putOperationWithChecksumRequest, AsyncRequestBody requestBody, + AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(putOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, putOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "PutOperationWithChecksum"); Pair, CompletableFuture> pair = AsyncResponseTransformerUtils - .wrapWithEndOfStreamFuture(asyncResponseTransformer); + .wrapWithEndOfStreamFuture(asyncResponseTransformer); asyncResponseTransformer = pair.left(); CompletableFuture endOfStreamFuture = pair.right(); if (!isSignerOverridden(clientConfiguration)) { @@ -636,33 +677,34 @@ public CompletableFuture putOperationWithChecksum( } HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - PutOperationWithChecksumResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); + PutOperationWithChecksumResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler.execute( - new ClientExecutionParams() - .withOperationName("PutOperationWithChecksum") - .withMarshaller( - AsyncStreamingRequestMarshaller.builder() - .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) - .asyncRequestBody(requestBody).build()) - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(false) - .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) - .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) - .build()).withAsyncRequestBody(requestBody) - .withInput(putOperationWithChecksumRequest), asyncResponseTransformer); + new ClientExecutionParams() + .withOperationName("PutOperationWithChecksum") + .withMarshaller( + AsyncStreamingRequestMarshaller.builder() + .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) + .asyncRequestBody(requestBody).build()) + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(false) + .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) + .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) + .build()).withAsyncRequestBody(requestBody) + .withInput(putOperationWithChecksumRequest), asyncResponseTransformer); CompletableFuture whenCompleteFuture = null; AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { if (e != null) { runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(e)); + () -> finalAsyncResponseTransformer.exceptionOccurred(e)); } endOfStreamFuture.whenComplete((r2, e2) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -672,7 +714,7 @@ public CompletableFuture putOperationWithChecksum( } catch (Throwable t) { AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(t)); + () -> finalAsyncResponseTransformer.exceptionOccurred(t)); metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); return CompletableFutureUtils.failedFuture(t); } @@ -704,11 +746,13 @@ public CompletableFuture putOperationWithChecksum( */ @Override public CompletableFuture streamingInputOperation( - StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) { + StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingInputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingInputOperation"); @@ -717,18 +761,19 @@ public CompletableFuture streamingInputOperatio } HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(StreamingInputOperationResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(StreamingInputOperationResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams() - .withOperationName("StreamingInputOperation") - .withMarshaller( - AsyncStreamingRequestMarshaller.builder() - .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) - .asyncRequestBody(requestBody).build()).withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector).withAsyncRequestBody(requestBody) - .withInput(streamingInputOperationRequest)); + .execute(new ClientExecutionParams() + .withOperationName("StreamingInputOperation") + .withRequestConfiguration(clientConfiguration) + .withMarshaller( + AsyncStreamingRequestMarshaller.builder() + .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) + .asyncRequestBody(requestBody).build()).withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector).withAsyncRequestBody(requestBody) + .withInput(streamingInputOperationRequest)); CompletableFuture whenCompleteFuture = null; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -767,38 +812,40 @@ public CompletableFuture streamingInputOperatio */ @Override public CompletableFuture streamingOutputOperation( - StreamingOutputOperationRequest streamingOutputOperationRequest, - AsyncResponseTransformer asyncResponseTransformer) { + StreamingOutputOperationRequest streamingOutputOperationRequest, + AsyncResponseTransformer asyncResponseTransformer) { + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingOutputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingOutputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingOutputOperation"); Pair, CompletableFuture> pair = AsyncResponseTransformerUtils - .wrapWithEndOfStreamFuture(asyncResponseTransformer); + .wrapWithEndOfStreamFuture(asyncResponseTransformer); asyncResponseTransformer = pair.left(); CompletableFuture endOfStreamFuture = pair.right(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - StreamingOutputOperationResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); + StreamingOutputOperationResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler.execute( - new ClientExecutionParams() - .withOperationName("StreamingOutputOperation") - .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(streamingOutputOperationRequest), - asyncResponseTransformer); + new ClientExecutionParams() + .withOperationName("StreamingOutputOperation") + .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration).withMetricCollector(apiCallMetricCollector) + .withInput(streamingOutputOperationRequest), asyncResponseTransformer); CompletableFuture whenCompleteFuture = null; AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; whenCompleteFuture = executeFuture.whenComplete((r, e) -> { if (e != null) { runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(e)); + () -> finalAsyncResponseTransformer.exceptionOccurred(e)); } endOfStreamFuture.whenComplete((r2, e2) -> { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); @@ -808,7 +855,7 @@ public CompletableFuture streamingOutputOperation( } catch (Throwable t) { AsyncResponseTransformer finalAsyncResponseTransformer = asyncResponseTransformer; runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> finalAsyncResponseTransformer.exceptionOccurred(t)); + () -> finalAsyncResponseTransformer.exceptionOccurred(t)); metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); return CompletableFutureUtils.failedFuture(t); } @@ -826,15 +873,15 @@ public final String serviceName() { private AwsXmlProtocolFactory init() { return AwsXmlProtocolFactory - .builder() - .registerModeledException( - ExceptionMetadata.builder().errorCode("InvalidInput") - .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) - .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(XmlException::builder).build(); + .builder() + .registerModeledException( + ExceptionMetadata.builder().errorCode("InvalidInput") + .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) + .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(XmlException::builder).build(); } private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, - RequestOverrideConfiguration requestOverrideConfiguration) { + RequestOverrideConfiguration requestOverrideConfiguration) { List publishers = null; if (requestOverrideConfiguration != null) { publishers = requestOverrideConfiguration.metricPublishers(); @@ -854,8 +901,8 @@ private T applySignerOverride(T request, Signer signer) { } Consumer signerOverride = b -> b.signer(signer).build(); AwsRequestOverrideConfiguration overrideConfiguration = request.overrideConfiguration() - .map(c -> c.toBuilder().applyMutation(signerOverride).build()) - .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(signerOverride).build())); + .map(c -> c.toBuilder().applyMutation(signerOverride).build()) + .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(signerOverride).build())); return (T) request.toBuilder().overrideConfiguration(overrideConfiguration).build(); } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-xml-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-xml-client-class.java index d52550654b17..6145b555a8fc 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-xml-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-xml-client-class.java @@ -2,6 +2,7 @@ import java.util.Collections; import java.util.List; +import java.util.function.BiFunction; import java.util.function.Consumer; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.SdkInternalApi; @@ -12,8 +13,13 @@ import software.amazon.awssdk.core.CredentialType; import software.amazon.awssdk.core.RequestOverrideConfiguration; import software.amazon.awssdk.core.Response; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.config.internal.ConfigurationUpdater; +import software.amazon.awssdk.core.client.config.internal.SdkClientConfigurationUtil; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.client.handler.SyncClientHandler; import software.amazon.awssdk.core.exception.SdkClientException; @@ -33,6 +39,7 @@ import software.amazon.awssdk.protocols.core.ExceptionMetadata; import software.amazon.awssdk.protocols.xml.AwsXmlProtocolFactory; import software.amazon.awssdk.protocols.xml.XmlOperationMetadata; +import software.amazon.awssdk.services.xml.internal.XmlServiceClientConfigurationBuilder; import software.amazon.awssdk.services.xml.model.APostOperationRequest; import software.amazon.awssdk.services.xml.model.APostOperationResponse; import software.amazon.awssdk.services.xml.model.APostOperationWithOutputRequest; @@ -86,11 +93,24 @@ final class DefaultXmlClient implements XmlClient { private final XmlServiceClientConfiguration serviceClientConfiguration; + private final BiFunction clientConfigurationForRequest; + protected DefaultXmlClient(XmlServiceClientConfiguration serviceClientConfiguration, - SdkClientConfiguration clientConfiguration) { + SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsSyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.serviceClientConfiguration = serviceClientConfiguration; + ConfigurationUpdater configurationUpdater = (consumer, configBuilder) -> { + XmlServiceClientConfigurationBuilder.BuilderInternal serviceConfigBuilder = XmlServiceClientConfigurationBuilder + .builder(configBuilder); + consumer.accept(serviceConfigBuilder); + return serviceConfigBuilder.buildSdkClientConfiguration(); + }; + this.clientConfigurationForRequest = (request, config) -> { + List plugins = request.overrideConfiguration().map(c -> c.registeredPlugins()) + .orElse(Collections.emptyList()); + return SdkClientConfigurationUtil.invokePlugins(config, plugins, configurationUpdater); + }; this.protocolFactory = init(); } @@ -116,14 +136,16 @@ protected DefaultXmlClient(XmlServiceClientConfiguration serviceClientConfigurat */ @Override public APostOperationResponse aPostOperation(APostOperationRequest aPostOperationRequest) throws InvalidInputException, - AwsServiceException, SdkClientException, XmlException { + AwsServiceException, SdkClientException, XmlException { HttpResponseHandler> responseHandler = protocolFactory.createCombinedResponseHandler( - APostOperationResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + APostOperationResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperation"); @@ -131,9 +153,10 @@ public APostOperationResponse aPostOperation(APostOperationRequest aPostOperatio String resolvedHostExpression = "foo-"; return clientHandler.execute(new ClientExecutionParams() - .withOperationName("APostOperation").withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector).hostPrefixExpression(resolvedHostExpression) - .withInput(aPostOperationRequest).withMarshaller(new APostOperationRequestMarshaller(protocolFactory))); + .withOperationName("APostOperation").withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector).hostPrefixExpression(resolvedHostExpression) + .withRequestConfiguration(clientConfiguration).withInput(aPostOperationRequest) + .withMarshaller(new APostOperationRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -161,25 +184,28 @@ public APostOperationResponse aPostOperation(APostOperationRequest aPostOperatio */ @Override public APostOperationWithOutputResponse aPostOperationWithOutput( - APostOperationWithOutputRequest aPostOperationWithOutputRequest) throws InvalidInputException, AwsServiceException, - SdkClientException, XmlException { + APostOperationWithOutputRequest aPostOperationWithOutputRequest) throws InvalidInputException, AwsServiceException, + SdkClientException, XmlException { HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(APostOperationWithOutputResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(APostOperationWithOutputResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(aPostOperationWithOutputRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, aPostOperationWithOutputRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperationWithOutput"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("APostOperationWithOutput").withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(aPostOperationWithOutputRequest) - .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("APostOperationWithOutput").withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector).withRequestConfiguration(clientConfiguration) + .withInput(aPostOperationWithOutputRequest) + .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -203,25 +229,27 @@ public APostOperationWithOutputResponse aPostOperationWithOutput( */ @Override public BearerAuthOperationResponse bearerAuthOperation(BearerAuthOperationRequest bearerAuthOperationRequest) - throws AwsServiceException, SdkClientException, XmlException { + throws AwsServiceException, SdkClientException, XmlException { bearerAuthOperationRequest = applySignerOverride(bearerAuthOperationRequest, BearerTokenSigner.create()); HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(BearerAuthOperationResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(BearerAuthOperationResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(bearerAuthOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, bearerAuthOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "BearerAuthOperation"); return clientHandler.execute(new ClientExecutionParams() - .withOperationName("BearerAuthOperation").withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector).credentialType(CredentialType.TOKEN) - .withInput(bearerAuthOperationRequest) - .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory))); + .withOperationName("BearerAuthOperation").withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector).credentialType(CredentialType.TOKEN) + .withRequestConfiguration(clientConfiguration).withInput(bearerAuthOperationRequest) + .withMarshaller(new BearerAuthOperationRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -245,32 +273,35 @@ public BearerAuthOperationResponse bearerAuthOperation(BearerAuthOperationReques */ @Override public GetOperationWithChecksumResponse getOperationWithChecksum( - GetOperationWithChecksumRequest getOperationWithChecksumRequest) throws AwsServiceException, SdkClientException, - XmlException { + GetOperationWithChecksumRequest getOperationWithChecksumRequest) throws AwsServiceException, SdkClientException, + XmlException { HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(GetOperationWithChecksumResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(GetOperationWithChecksumResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(getOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, getOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "GetOperationWithChecksum"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("GetOperationWithChecksum") - .withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector) - .withInput(getOperationWithChecksumRequest) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(true) - .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) - .isRequestStreaming(false).build()) - .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("GetOperationWithChecksum") + .withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration) + .withInput(getOperationWithChecksumRequest) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(true) + .requestAlgorithm(getOperationWithChecksumRequest.checksumAlgorithmAsString()) + .isRequestStreaming(false).build()) + .withMarshaller(new GetOperationWithChecksumRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -294,29 +325,32 @@ public GetOperationWithChecksumResponse getOperationWithChecksum( */ @Override public OperationWithChecksumRequiredResponse operationWithChecksumRequired( - OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) throws AwsServiceException, - SdkClientException, XmlException { + OperationWithChecksumRequiredRequest operationWithChecksumRequiredRequest) throws AwsServiceException, + SdkClientException, XmlException { HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(OperationWithChecksumRequiredResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(OperationWithChecksumRequiredResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithChecksumRequiredRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); + operationWithChecksumRequiredRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithChecksumRequired"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithChecksumRequired") - .withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector) - .withInput(operationWithChecksumRequiredRequest) - .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, - HttpChecksumRequired.create()) - .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithChecksumRequired") + .withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration) + .withInput(operationWithChecksumRequiredRequest) + .putExecutionAttribute(SdkInternalExecutionAttribute.HTTP_CHECKSUM_REQUIRED, + HttpChecksumRequired.create()) + .withMarshaller(new OperationWithChecksumRequiredRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -340,26 +374,29 @@ public OperationWithChecksumRequiredResponse operationWithChecksumRequired( */ @Override public OperationWithNoneAuthTypeResponse operationWithNoneAuthType( - OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) throws AwsServiceException, SdkClientException, - XmlException { + OperationWithNoneAuthTypeRequest operationWithNoneAuthTypeRequest) throws AwsServiceException, SdkClientException, + XmlException { HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(OperationWithNoneAuthTypeResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(OperationWithNoneAuthTypeResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(operationWithNoneAuthTypeRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, operationWithNoneAuthTypeRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithNoneAuthType"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithNoneAuthType").withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector).withInput(operationWithNoneAuthTypeRequest) - .putExecutionAttribute(SdkInternalExecutionAttribute.IS_NONE_AUTH_TYPE_REQUEST, false) - .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithNoneAuthType").withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector).withRequestConfiguration(clientConfiguration) + .withInput(operationWithNoneAuthTypeRequest) + .putExecutionAttribute(SdkInternalExecutionAttribute.IS_NONE_AUTH_TYPE_REQUEST, false) + .withMarshaller(new OperationWithNoneAuthTypeRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -383,29 +420,32 @@ public OperationWithNoneAuthTypeResponse operationWithNoneAuthType( */ @Override public OperationWithRequestCompressionResponse operationWithRequestCompression( - OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) throws AwsServiceException, - SdkClientException, XmlException { + OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) throws AwsServiceException, + SdkClientException, XmlException { HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(OperationWithRequestCompressionResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(OperationWithRequestCompressionResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply( + operationWithRequestCompressionRequest, this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, - operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); + operationWithRequestCompressionRequest.overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "OperationWithRequestCompression"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("OperationWithRequestCompression") - .withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector) - .withInput(operationWithRequestCompressionRequest) - .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, - RequestCompression.builder().encodings("gzip").isStreaming(false).build()) - .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory))); + .execute(new ClientExecutionParams() + .withOperationName("OperationWithRequestCompression") + .withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration) + .withInput(operationWithRequestCompressionRequest) + .putExecutionAttribute(SdkInternalExecutionAttribute.REQUEST_COMPRESSION, + RequestCompression.builder().encodings("gzip").isStreaming(false).build()) + .withMarshaller(new OperationWithRequestCompressionRequestMarshaller(protocolFactory))); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -419,11 +459,11 @@ public OperationWithRequestCompressionResponse operationWithRequestCompression( * The content to send to the service. A {@link RequestBody} can be created using one of several factory * methods for various sources of data. For example, to create a request body from a file you can do the * following. - * + * *
      * {@code RequestBody.fromFile(new File("myfile.txt"))}
      * 
- * + * * See documentation in {@link RequestBody} for additional details and which sources of data are supported. * The service documentation for the request content is as follows ' *

@@ -455,39 +495,42 @@ public OperationWithRequestCompressionResponse operationWithRequestCompression( */ @Override public ReturnT putOperationWithChecksum(PutOperationWithChecksumRequest putOperationWithChecksumRequest, - RequestBody requestBody, ResponseTransformer responseTransformer) - throws AwsServiceException, SdkClientException, XmlException { + RequestBody requestBody, ResponseTransformer responseTransformer) + throws AwsServiceException, SdkClientException, XmlException { HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - PutOperationWithChecksumResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); + PutOperationWithChecksumResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(putOperationWithChecksumRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, putOperationWithChecksumRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "PutOperationWithChecksum"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("PutOperationWithChecksum") - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withInput(putOperationWithChecksumRequest) - .withMetricCollector(apiCallMetricCollector) - .putExecutionAttribute( - SdkInternalExecutionAttribute.HTTP_CHECKSUM, - HttpChecksum.builder().requestChecksumRequired(false) - .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) - .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) - .build()) - .withRequestBody(requestBody) - .withMarshaller( - StreamingRequestMarshaller.builder() - .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) - .requestBody(requestBody).build())); + .execute(new ClientExecutionParams() + .withOperationName("PutOperationWithChecksum") + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withRequestConfiguration(clientConfiguration) + .withInput(putOperationWithChecksumRequest) + .withMetricCollector(apiCallMetricCollector) + .putExecutionAttribute( + SdkInternalExecutionAttribute.HTTP_CHECKSUM, + HttpChecksum.builder().requestChecksumRequired(false) + .requestValidationMode(putOperationWithChecksumRequest.checksumModeAsString()) + .responseAlgorithms("CRC32C", "CRC32", "SHA1", "SHA256").isRequestStreaming(true) + .build()) + .withRequestBody(requestBody) + .withMarshaller( + StreamingRequestMarshaller.builder() + .delegateMarshaller(new PutOperationWithChecksumRequestMarshaller(protocolFactory)) + .requestBody(requestBody).build())); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -501,11 +544,11 @@ public ReturnT putOperationWithChecksum(PutOperationWithChecksumReques * The content to send to the service. A {@link RequestBody} can be created using one of several factory * methods for various sources of data. For example, to create a request body from a file you can do the * following. - * + * *

      * {@code RequestBody.fromFile(new File("myfile.txt"))}
      * 
- * + * * See documentation in {@link RequestBody} for additional details and which sources of data are supported. * The service documentation for the request content is as follows 'This be a stream' * @return Result of the StreamingInputOperation operation returned by the service. @@ -522,30 +565,33 @@ public ReturnT putOperationWithChecksum(PutOperationWithChecksumReques */ @Override public StreamingInputOperationResponse streamingInputOperation(StreamingInputOperationRequest streamingInputOperationRequest, - RequestBody requestBody) throws AwsServiceException, SdkClientException, XmlException { + RequestBody requestBody) throws AwsServiceException, SdkClientException, XmlException { HttpResponseHandler> responseHandler = protocolFactory - .createCombinedResponseHandler(StreamingInputOperationResponse::builder, - new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + .createCombinedResponseHandler(StreamingInputOperationResponse::builder, + new XmlOperationMetadata().withHasStreamingSuccessResponse(false)); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingInputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingInputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingInputOperation"); return clientHandler - .execute(new ClientExecutionParams() - .withOperationName("StreamingInputOperation") - .withCombinedResponseHandler(responseHandler) - .withMetricCollector(apiCallMetricCollector) - .withInput(streamingInputOperationRequest) - .withRequestBody(requestBody) - .withMarshaller( - StreamingRequestMarshaller.builder() - .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) - .requestBody(requestBody).build())); + .execute(new ClientExecutionParams() + .withOperationName("StreamingInputOperation") + .withCombinedResponseHandler(responseHandler) + .withMetricCollector(apiCallMetricCollector) + .withRequestConfiguration(clientConfiguration) + .withInput(streamingInputOperationRequest) + .withRequestBody(requestBody) + .withMarshaller( + StreamingRequestMarshaller.builder() + .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) + .requestBody(requestBody).build())); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -576,27 +622,29 @@ public StreamingInputOperationResponse streamingInputOperation(StreamingInputOpe */ @Override public ReturnT streamingOutputOperation(StreamingOutputOperationRequest streamingOutputOperationRequest, - ResponseTransformer responseTransformer) throws AwsServiceException, - SdkClientException, XmlException { + ResponseTransformer responseTransformer) throws AwsServiceException, + SdkClientException, XmlException { HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - StreamingOutputOperationResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); + StreamingOutputOperationResponse::builder, new XmlOperationMetadata().withHasStreamingSuccessResponse(true)); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + SdkClientConfiguration clientConfiguration = this.clientConfigurationForRequest.apply(streamingOutputOperationRequest, + this.clientConfiguration); List metricPublishers = resolveMetricPublishers(clientConfiguration, streamingOutputOperationRequest - .overrideConfiguration().orElse(null)); + .overrideConfiguration().orElse(null)); MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector - .create("ApiCall"); + .create("ApiCall"); try { apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Xml Service"); apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingOutputOperation"); return clientHandler.execute( - new ClientExecutionParams() - .withOperationName("StreamingOutputOperation").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(streamingOutputOperationRequest) - .withMetricCollector(apiCallMetricCollector) - .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)), responseTransformer); + new ClientExecutionParams() + .withOperationName("StreamingOutputOperation").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withRequestConfiguration(clientConfiguration) + .withInput(streamingOutputOperationRequest).withMetricCollector(apiCallMetricCollector) + .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)), responseTransformer); } finally { metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); } @@ -608,8 +656,8 @@ private T applySignerOverride(T request, Signer signer) { } Consumer signerOverride = b -> b.signer(signer).build(); AwsRequestOverrideConfiguration overrideConfiguration = request.overrideConfiguration() - .map(c -> c.toBuilder().applyMutation(signerOverride).build()) - .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(signerOverride).build())); + .map(c -> c.toBuilder().applyMutation(signerOverride).build()) + .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(signerOverride).build())); return (T) request.toBuilder().overrideConfiguration(overrideConfiguration).build(); } @@ -619,7 +667,7 @@ public final String serviceName() { } private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, - RequestOverrideConfiguration requestOverrideConfiguration) { + RequestOverrideConfiguration requestOverrideConfiguration) { List publishers = null; if (requestOverrideConfiguration != null) { publishers = requestOverrideConfiguration.metricPublishers(); @@ -635,11 +683,11 @@ private static List resolveMetricPublishers(SdkClientConfigurat private AwsXmlProtocolFactory init() { return AwsXmlProtocolFactory - .builder() - .registerModeledException( - ExceptionMetadata.builder().errorCode("InvalidInput") - .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) - .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(XmlException::builder).build(); + .builder() + .registerModeledException( + ExceptionMetadata.builder().errorCode("InvalidInput") + .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()) + .clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(XmlException::builder).build(); } @Override diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/serviceclientconfiguration-builder.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/serviceclientconfiguration-builder.java index 4afcc913838d..a096a667424f 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/serviceclientconfiguration-builder.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/serviceclientconfiguration-builder.java @@ -12,6 +12,7 @@ import software.amazon.awssdk.http.auth.spi.scheme.AuthSchemeProvider; import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity; import software.amazon.awssdk.identity.spi.IdentityProvider; +import software.amazon.awssdk.identity.spi.IdentityProviders; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.jsonprotocoltests.JsonProtocolTestsServiceClientConfiguration; import software.amazon.awssdk.services.jsonprotocoltests.auth.scheme.JsonProtocolTestsAuthSchemeProvider; @@ -39,6 +40,8 @@ public static class BuilderImpl implements BuilderInternal { private URI endpointOverride; + private IdentityProvider credentialsProvider; + private BuilderImpl() { this.internalBuilder = SdkClientConfiguration.builder(); } @@ -50,6 +53,7 @@ private BuilderImpl(SdkClientConfiguration.Builder internalBuilder) { if (Boolean.TRUE.equals(internalBuilder.option(SdkClientOption.ENDPOINT_OVERRIDDEN))) { this.endpointOverride = internalBuilder.option(SdkClientOption.ENDPOINT); } + this.credentialsProvider = internalBuilder.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER); } /** @@ -127,7 +131,7 @@ public Region region() { @Override public JsonProtocolTestsServiceClientConfiguration.Builder credentialsProvider( IdentityProvider credentialsProvider) { - internalBuilder.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER, credentialsProvider); + this.credentialsProvider = credentialsProvider; return this; } @@ -136,7 +140,7 @@ public JsonProtocolTestsServiceClientConfiguration.Builder credentialsProvider( */ @Override public IdentityProvider credentialsProvider() { - return internalBuilder.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER); + return credentialsProvider; } /** @@ -176,6 +180,17 @@ public SdkClientConfiguration buildSdkClientConfiguration() { internalBuilder.option(SdkClientOption.ENDPOINT, endpointOverride); internalBuilder.option(SdkClientOption.ENDPOINT_OVERRIDDEN, true); } + if (credentialsProvider != null + && !credentialsProvider.equals(internalBuilder.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER))) { + internalBuilder.option(AwsClientOption.CREDENTIALS_IDENTITY_PROVIDER, credentialsProvider); + IdentityProviders identityProviders = internalBuilder.option(SdkClientOption.IDENTITY_PROVIDERS); + if (identityProviders == null) { + identityProviders = IdentityProviders.builder().putIdentityProvider(credentialsProvider).build(); + } else { + identityProviders = identityProviders.toBuilder().putIdentityProvider(credentialsProvider).build(); + } + internalBuilder.option(SdkClientOption.IDENTITY_PROVIDERS, identityProviders); + } return internalBuilder.build(); } } diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequest.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequest.java index 406a5e58ecb8..e993a66cbc2c 100644 --- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequest.java +++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequest.java @@ -15,14 +15,10 @@ package software.amazon.awssdk.awscore; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.function.Consumer; import software.amazon.awssdk.annotations.SdkPublicApi; -import software.amazon.awssdk.core.SdkPlugin; import software.amazon.awssdk.core.SdkRequest; /** @@ -31,11 +27,9 @@ @SdkPublicApi public abstract class AwsRequest extends SdkRequest { private final AwsRequestOverrideConfiguration requestOverrideConfig; - private final List registeredPlugins; protected AwsRequest(Builder builder) { this.requestOverrideConfig = builder.overrideConfiguration(); - this.registeredPlugins = Collections.unmodifiableList(new ArrayList<>(builder.registeredPlugins())); } @Override @@ -43,11 +37,6 @@ public final Optional overrideConfiguration() { return Optional.ofNullable(requestOverrideConfig); } - @Override - public List registeredPlugins() { - return registeredPlugins; - } - @Override public abstract Builder toBuilder(); @@ -96,7 +85,6 @@ public interface Builder extends SdkRequest.Builder { protected abstract static class BuilderImpl implements Builder { private AwsRequestOverrideConfiguration awsRequestOverrideConfig; - private final List registeredPlugins = new ArrayList<>(); protected BuilderImpl() { } @@ -119,17 +107,6 @@ public Builder overrideConfiguration(Consumer registeredPlugins() { - return registeredPlugins; - } - - @Override - public Builder addPlugin(SdkPlugin plugin) { - this.registeredPlugins.add(plugin); - return this; - } - @Override public final AwsRequestOverrideConfiguration overrideConfiguration() { return awsRequestOverrideConfig; diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java index 71701767533b..14e492d2a2d0 100644 --- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java +++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java @@ -386,8 +386,6 @@ private AwsCredentialsProvider toCredentialsProvider(IdentityProvider Complet @Override protected ExecutionContext - invokeInterceptorsAndCreateExecutionContext(ClientExecutionParams executionParams) { + invokeInterceptorsAndCreateExecutionContext(ClientExecutionParams executionParams, + SdkClientConfiguration clientConfiguration) { return AwsExecutionContextBuilder.invokeInterceptorsAndCreateExecutionContext(executionParams, clientConfiguration); } } diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/handler/AwsSyncClientHandler.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/handler/AwsSyncClientHandler.java index 08d74bee972d..4f1648ac7421 100644 --- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/handler/AwsSyncClientHandler.java +++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/handler/AwsSyncClientHandler.java @@ -41,11 +41,8 @@ @SdkProtectedApi public final class AwsSyncClientHandler extends SdkSyncClientHandler implements SyncClientHandler { - private final SdkClientConfiguration clientConfiguration; - public AwsSyncClientHandler(SdkClientConfiguration clientConfiguration) { super(clientConfiguration); - this.clientConfiguration = clientConfiguration; AwsClientOptionValidation.validateSyncClientOptions(clientConfiguration); } @@ -65,7 +62,8 @@ public ReturnT @Override protected ExecutionContext - invokeInterceptorsAndCreateExecutionContext(ClientExecutionParams executionParams) { + invokeInterceptorsAndCreateExecutionContext(ClientExecutionParams executionParams, + SdkClientConfiguration clientConfiguration) { return AwsExecutionContextBuilder.invokeInterceptorsAndCreateExecutionContext(executionParams, clientConfiguration); } diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/RequestOverrideConfiguration.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/RequestOverrideConfiguration.java index 9dc55c2ee910..2b105f4521a1 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/RequestOverrideConfiguration.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/RequestOverrideConfiguration.java @@ -53,6 +53,7 @@ public abstract class RequestOverrideConfiguration { private final ExecutionAttributes executionAttributes; private final EndpointProvider endpointProvider; private final CompressionConfiguration compressionConfiguration; + private final List registeredPlugins; protected RequestOverrideConfiguration(Builder builder) { this.headers = CollectionUtils.deepUnmodifiableMap(builder.headers(), () -> new TreeMap<>(String.CASE_INSENSITIVE_ORDER)); @@ -65,6 +66,7 @@ protected RequestOverrideConfiguration(Builder builder) { this.executionAttributes = ExecutionAttributes.unmodifiableExecutionAttributes(builder.executionAttributes()); this.endpointProvider = builder.endpointProvider(); this.compressionConfiguration = builder.compressionConfiguration(); + this.registeredPlugins = builder.registeredPlugins(); } /** @@ -148,6 +150,13 @@ public List metricPublishers() { return metricPublishers; } + /** + * Return the plugins that will be used to update the configuration used by the request. + */ + public List registeredPlugins() { + return registeredPlugins; + } + /** * 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. @@ -193,7 +202,8 @@ public boolean equals(Object o) { Objects.equals(metricPublishers, that.metricPublishers) && Objects.equals(executionAttributes, that.executionAttributes) && Objects.equals(endpointProvider, that.endpointProvider) && - Objects.equals(compressionConfiguration, that.compressionConfiguration); + Objects.equals(compressionConfiguration, that.compressionConfiguration) && + Objects.equals(registeredPlugins, that.registeredPlugins); } @Override @@ -209,6 +219,7 @@ public int hashCode() { hashCode = 31 * hashCode + Objects.hashCode(executionAttributes); hashCode = 31 * hashCode + Objects.hashCode(endpointProvider); hashCode = 31 * hashCode + Objects.hashCode(compressionConfiguration); + hashCode = 31 * hashCode + Objects.hashCode(registeredPlugins); return hashCode; } @@ -470,6 +481,26 @@ default B putRawQueryParameter(String name, String value) { 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. + */ + B plugins(List plugins); + + /** + * Add a plugin used to update the configuration used by this request. + * + * @param plugin The plugin to add. + */ + B addPlugin(SdkPlugin plugin); + + /** + * Returns the list of registered plugins + */ + List registeredPlugins(); + /** * Create a new {@code SdkRequestOverrideConfiguration} with the properties set on this builder. * @@ -489,6 +520,8 @@ protected abstract static class BuilderImpl implements Builde private ExecutionAttributes.Builder executionAttributesBuilder = ExecutionAttributes.builder(); private EndpointProvider endpointProvider; private CompressionConfiguration compressionConfiguration; + private List registeredPlugins = new ArrayList<>(); + protected BuilderImpl() { } @@ -504,6 +537,7 @@ protected BuilderImpl(RequestOverrideConfiguration sdkRequestOverrideConfig) { executionAttributes(sdkRequestOverrideConfig.executionAttributes()); endpointProvider(sdkRequestOverrideConfig.endpointProvider); compressionConfiguration(sdkRequestOverrideConfig.compressionConfiguration); + plugins(sdkRequestOverrideConfig.registeredPlugins); } @Override @@ -691,5 +725,22 @@ public B compressionConfiguration(Consumer com public CompressionConfiguration compressionConfiguration() { return compressionConfiguration; } + + @Override + public B plugins(List plugins) { + this.registeredPlugins = new ArrayList<>(plugins); + return (B) this; + } + + @Override + public B addPlugin(SdkPlugin plugin) { + this.registeredPlugins.add(plugin); + return (B) this; + } + + @Override + public List registeredPlugins() { + return Collections.unmodifiableList(registeredPlugins); + } } } diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/builder/SdkDefaultClientBuilder.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/builder/SdkDefaultClientBuilder.java index dcbc7ea71b97..f2aab87ce9c9 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/builder/SdkDefaultClientBuilder.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/builder/SdkDefaultClientBuilder.java @@ -187,7 +187,6 @@ protected final SdkClientConfiguration syncClientConfiguration() { configuration = finalizeSyncConfiguration(configuration); configuration = finalizeConfiguration(configuration); - return configuration; } diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/handler/ClientExecutionParams.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/handler/ClientExecutionParams.java index b7ad38664c37..017b94cc57a0 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/handler/ClientExecutionParams.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/handler/ClientExecutionParams.java @@ -22,6 +22,7 @@ import software.amazon.awssdk.core.Response; import software.amazon.awssdk.core.SdkRequest; import software.amazon.awssdk.core.async.AsyncRequestBody; +import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.exception.SdkException; import software.amazon.awssdk.core.http.HttpResponseHandler; import software.amazon.awssdk.core.interceptor.ExecutionAttribute; @@ -55,6 +56,7 @@ public final class ClientExecutionParams { private CredentialType credentialType; private MetricCollector metricCollector; private final ExecutionAttributes attributes = new ExecutionAttributes(); + private SdkClientConfiguration requestConfiguration; public Marshaller getMarshaller() { return marshaller; @@ -213,4 +215,13 @@ public ExecutionAttributes executionAttributes() { public MetricCollector getMetricCollector() { return metricCollector; } + + public SdkClientConfiguration requestConfiguration() { + return requestConfiguration; + } + + public ClientExecutionParams withRequestConfiguration(SdkClientConfiguration requestConfiguration) { + this.requestConfiguration = requestConfiguration; + return this; + } } diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseAsyncClientHandler.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseAsyncClientHandler.java index 67f81c65711b..0c2f91a3a424 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseAsyncClientHandler.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseAsyncClientHandler.java @@ -56,14 +56,12 @@ @SdkInternalApi public abstract class BaseAsyncClientHandler extends BaseClientHandler implements AsyncClientHandler { private static final Logger log = Logger.loggerFor(BaseAsyncClientHandler.class); - private final SdkClientConfiguration clientConfiguration; private final AmazonAsyncHttpClient client; private final Function crc32Validator; protected BaseAsyncClientHandler(SdkClientConfiguration clientConfiguration, AmazonAsyncHttpClient client) { super(clientConfiguration); - this.clientConfiguration = clientConfiguration; this.client = client; this.crc32Validator = response -> Crc32Validation.validate(isCalculateCrc32FromCompressedData(), response); } @@ -201,7 +199,8 @@ private Comple InterceptorContext finalizeSdkHttpRequestContext = finalizeSdkHttpFullRequest(executionParams, executionContext, inputT, - clientConfiguration); + resolveRequestConfiguration( + executionParams)); SdkHttpFullRequest marshalled = (SdkHttpFullRequest) finalizeSdkHttpRequestContext.httpRequest(); @@ -223,8 +222,10 @@ private Comple .build(); } + SdkClientConfiguration clientConfiguration = resolveRequestConfiguration(executionParams); CompletableFuture invokeFuture = - invoke(marshalled, + invoke(clientConfiguration, + marshalled, finalizeSdkHttpRequestContext.asyncRequestBody().orElse(null), inputT, executionContext, @@ -272,6 +273,7 @@ private TransformingAsyncResponseHandler resolveErrorRes * configured in the ExecutionContext beforehand. **/ private CompletableFuture invoke( + SdkClientConfiguration clientConfiguration, SdkHttpFullRequest request, AsyncRequestBody requestProvider, InputT originalRequest, @@ -282,6 +284,7 @@ private CompletableFuture invoke( .request(request) .originalRequest(originalRequest) .executionContext(executionContext) + .httpClientDependencies(c -> c.clientConfiguration(clientConfiguration)) .execute(responseHandler); } diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseClientHandler.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseClientHandler.java index 21421eeb911a..fbbb8e6c084b 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseClientHandler.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseClientHandler.java @@ -192,6 +192,15 @@ private static InterceptorContext runModifyHttpRequestAndHttpContentInterceptors protected ExecutionContext invokeInterceptorsAndCreateExecutionContext( ClientExecutionParams params) { + SdkClientConfiguration clientConfiguration = resolveRequestConfiguration(params); + return invokeInterceptorsAndCreateExecutionContext(params, clientConfiguration); + } + + // This method is only called from tests, since the subclasses in aws-core override it. + protected ExecutionContext + invokeInterceptorsAndCreateExecutionContext( + ClientExecutionParams params, + SdkClientConfiguration clientConfiguration) { SdkRequest originalRequest = params.getInput(); ExecutionAttributes executionAttributes = params.executionAttributes(); @@ -247,6 +256,14 @@ protected void validateSigningConfiguration(SdkHttpRequest request, Signer signe } } + protected SdkClientConfiguration resolveRequestConfiguration(ClientExecutionParams params) { + SdkClientConfiguration config = params.requestConfiguration(); + if (config != null) { + return config; + } + return clientConfiguration; + } + /** * Decorate response handlers by running after unmarshalling Interceptors and adding http response metadata. */ diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseSyncClientHandler.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseSyncClientHandler.java index 3a6466ac79c3..03ea0683397b 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseSyncClientHandler.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseSyncClientHandler.java @@ -44,13 +44,11 @@ @SdkInternalApi public abstract class BaseSyncClientHandler extends BaseClientHandler implements SyncClientHandler { - private final SdkClientConfiguration clientConfiguration; private final AmazonSyncHttpClient client; protected BaseSyncClientHandler(SdkClientConfiguration clientConfiguration, AmazonSyncHttpClient client) { super(clientConfiguration); - this.clientConfiguration = clientConfiguration; this.client = client; } @@ -92,14 +90,16 @@ public void close() { * Invoke the request using the http client. Assumes credentials (or lack thereof) have been * configured in the OldExecutionContext beforehand. **/ - private OutputT invoke(SdkHttpFullRequest request, - SdkRequest originalRequest, - ExecutionContext executionContext, - HttpResponseHandler> responseHandler) { + private OutputT invoke(SdkClientConfiguration clientConfiguration, + SdkHttpFullRequest request, + SdkRequest originalRequest, + ExecutionContext executionContext, + HttpResponseHandler> responseHandler) { return client.requestExecutionBuilder() .request(request) .originalRequest(originalRequest) .executionContext(executionContext) + .httpClientDependencies(c -> c.clientConfiguration(clientConfiguration)) .execute(responseHandler); } @@ -151,7 +151,8 @@ private ReturnT doExecute( InterceptorContext sdkHttpFullRequestContext = finalizeSdkHttpFullRequest(executionParams, executionContext, inputT, - clientConfiguration); + resolveRequestConfiguration( + executionParams)); SdkHttpFullRequest marshalled = (SdkHttpFullRequest) sdkHttpFullRequestContext.httpRequest(); @@ -168,7 +169,9 @@ private ReturnT doExecute( .build(); } - return invoke(marshalled, + SdkClientConfiguration clientConfiguration = resolveRequestConfiguration(executionParams); + return invoke(clientConfiguration, + marshalled, inputT, executionContext, responseHandler); diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonAsyncHttpClient.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonAsyncHttpClient.java index 5f00eb4cfc71..b531bf7fe956 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonAsyncHttpClient.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonAsyncHttpClient.java @@ -18,6 +18,7 @@ import static software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder.async; import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.annotations.ThreadSafe; import software.amazon.awssdk.core.ClientType; @@ -77,14 +78,14 @@ public void close() { * @return A builder used to configure and execute a HTTP request. */ public RequestExecutionBuilder requestExecutionBuilder() { - return new RequestExecutionBuilderImpl(); + return new RequestExecutionBuilderImpl() + .httpClientDependencies(httpClientDependencies); } /** * Interface to configure a request execution and execute the request. */ public interface RequestExecutionBuilder { - /** * Fluent setter for {@link AsyncRequestBody} * @@ -117,6 +118,16 @@ public interface RequestExecutionBuilder { */ RequestExecutionBuilder originalRequest(SdkRequest originalRequest); + RequestExecutionBuilder httpClientDependencies(HttpClientDependencies httpClientDependencies); + + HttpClientDependencies httpClientDependencies(); + + default RequestExecutionBuilder httpClientDependencies(Consumer mutator) { + HttpClientDependencies.Builder builder = httpClientDependencies().toBuilder(); + mutator.accept(builder); + return httpClientDependencies(builder.build()); + } + /** * Executes the request with the given configuration. * @@ -128,13 +139,25 @@ public interface RequestExecutionBuilder { CompletableFuture execute(TransformingAsyncResponseHandler> responseHandler); } - private class RequestExecutionBuilderImpl implements RequestExecutionBuilder { + private static class RequestExecutionBuilderImpl implements RequestExecutionBuilder { + private HttpClientDependencies httpClientDependencies; private AsyncRequestBody requestProvider; private SdkHttpFullRequest request; private SdkRequest originalRequest; private ExecutionContext executionContext; + @Override + public RequestExecutionBuilder httpClientDependencies(HttpClientDependencies httpClientDependencies) { + this.httpClientDependencies = httpClientDependencies; + return this; + } + + @Override + public HttpClientDependencies httpClientDependencies() { + return httpClientDependencies; + } + @Override public RequestExecutionBuilder requestProvider(AsyncRequestBody requestProvider) { this.requestProvider = requestProvider; @@ -202,6 +225,5 @@ private RequestExecutionContext createRequestExecutionDependencies() { .executionContext(executionContext) .build(); } - } } diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonSyncHttpClient.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonSyncHttpClient.java index aed81c4c0aed..2e8de0e2979d 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonSyncHttpClient.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonSyncHttpClient.java @@ -15,6 +15,7 @@ package software.amazon.awssdk.core.internal.http; +import java.util.function.Consumer; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.annotations.ThreadSafe; import software.amazon.awssdk.core.ClientType; @@ -80,7 +81,8 @@ public void close() { * @return A builder used to configure and execute a HTTP request. */ public RequestExecutionBuilder requestExecutionBuilder() { - return new RequestExecutionBuilderImpl(); + return new RequestExecutionBuilderImpl() + .httpClientDependencies(httpClientDependencies); } /** @@ -106,6 +108,16 @@ public interface RequestExecutionBuilder { */ RequestExecutionBuilder executionContext(ExecutionContext executionContext); + RequestExecutionBuilder httpClientDependencies(HttpClientDependencies httpClientDependencies); + + HttpClientDependencies httpClientDependencies(); + + default RequestExecutionBuilder httpClientDependencies(Consumer mutator) { + HttpClientDependencies.Builder builder = httpClientDependencies().toBuilder(); + mutator.accept(builder); + return httpClientDependencies(builder.build()); + } + /** * Executes the request with the given configuration. * @@ -129,8 +141,9 @@ public boolean needsConnectionLeftOpen() { } } - private class RequestExecutionBuilderImpl implements RequestExecutionBuilder { + private static class RequestExecutionBuilderImpl implements RequestExecutionBuilder { + private HttpClientDependencies httpClientDependencies; private SdkHttpFullRequest request; private SdkRequest originalRequest; private ExecutionContext executionContext; @@ -154,6 +167,17 @@ public RequestExecutionBuilder executionContext(ExecutionContext executionContex return this; } + @Override + public RequestExecutionBuilder httpClientDependencies(HttpClientDependencies httpClientDependencies) { + this.httpClientDependencies = httpClientDependencies; + return this; + } + + @Override + public HttpClientDependencies httpClientDependencies() { + return this.httpClientDependencies; + } + @Override public OutputT execute(HttpResponseHandler> responseHandler) { // TODO: We currently have two ways of passing messages to the HTTP client: through the request or through the @@ -209,7 +233,5 @@ private RequestExecutionContext createRequestExecutionDependencies() { .executionContext(executionContext) .build(); } - } - } diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/HttpClientDependencies.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/HttpClientDependencies.java index b85218e9ce8e..951aaee3361d 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/HttpClientDependencies.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/HttpClientDependencies.java @@ -75,6 +75,10 @@ public void updateTimeOffset(int timeOffset) { SdkGlobalTime.setGlobalTimeOffset(timeOffset); } + public Builder toBuilder() { + return new Builder(this); + } + @Override public void close() { this.clientConfiguration.close(); @@ -90,6 +94,11 @@ public static class Builder { private Builder() { } + private Builder(HttpClientDependencies from) { + this.clientConfiguration = from.clientConfiguration; + this.clockSkewAdjuster = from.clockSkewAdjuster; + } + public Builder clockSkewAdjuster(ClockSkewAdjuster clockSkewAdjuster) { this.clockSkewAdjuster = clockSkewAdjuster; return this; diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/SraIdentityResolutionUsingPluginsTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/SraIdentityResolutionUsingPluginsTest.java index 1326e8e8c4b8..96cef695d64c 100644 --- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/SraIdentityResolutionUsingPluginsTest.java +++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/SraIdentityResolutionUsingPluginsTest.java @@ -64,7 +64,7 @@ public void testIdentityBasedPluginsResolutionIsUsedAndNotAnotherIdentityResolut .build(); assertThatThrownBy(() -> syncClient.allTypes(r -> {})).hasMessageContaining("boom"); - verify(credentialsProvider, times(2)).identityType(); + verify(credentialsProvider, times(3)).identityType(); // This asserts that the identity used is the one from resolveIdentity() called by SRA AuthSchemeInterceptor and not // from another call like from AwsCredentialsAuthorizationStrategy.addCredentialsToExecutionAttributes, asserted by diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/SraIdentityResolutionUsingRequestPluginsTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/SraIdentityResolutionUsingRequestPluginsTest.java new file mode 100644 index 000000000000..550e9198d4ad --- /dev/null +++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/SraIdentityResolutionUsingRequestPluginsTest.java @@ -0,0 +1,94 @@ +/* + * 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; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import java.util.concurrent.CompletableFuture; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; +import software.amazon.awssdk.core.SdkPlugin; +import software.amazon.awssdk.core.SdkServiceClientConfiguration; +import software.amazon.awssdk.http.SdkHttpClient; +import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity; +import software.amazon.awssdk.identity.spi.ResolveIdentityRequest; +import software.amazon.awssdk.services.protocolquery.ProtocolQueryClient; +import software.amazon.awssdk.services.protocolquery.ProtocolQueryServiceClientConfiguration; +import software.amazon.awssdk.services.protocolquery.model.AllTypesRequest; +import software.amazon.awssdk.utils.Validate; + +@RunWith(MockitoJUnitRunner.class) +public class SraIdentityResolutionUsingRequestPluginsTest { + + @Mock + private AwsCredentialsProvider credentialsProvider; + + @Test + public void testIdentityBasedPluginsResolutionIsUsedAndNotAnotherIdentityResolution() { + SdkHttpClient mockClient = mock(SdkHttpClient.class); + when(mockClient.prepareRequest(any())).thenThrow(new RuntimeException("boom")); + + when(credentialsProvider.identityType()).thenReturn(AwsCredentialsIdentity.class); + when(credentialsProvider.resolveIdentity(any(ResolveIdentityRequest.class))) + .thenReturn(CompletableFuture.completedFuture(AwsBasicCredentials.create("akid1", "skid2"))); + + ProtocolQueryClient syncClient = ProtocolQueryClient + .builder() + .httpClient(mockClient) + .build(); + + AllTypesRequest request = AllTypesRequest.builder() + .overrideConfiguration(c -> c.addPlugin(new TestPlugin(credentialsProvider))) + .build(); + assertThatThrownBy(() -> syncClient.allTypes(request)) + .hasMessageContaining("boom"); + + verify(credentialsProvider, times(2)).identityType(); + // This asserts that the identity used is the one from resolveIdentity() called by SRA AuthSchemeInterceptor and not + // from another call like from AwsCredentialsAuthorizationStrategy.addCredentialsToExecutionAttributes, asserted by + // combination of times(1) and verifyNoMoreInteractions. + verify(credentialsProvider, times(1)).resolveIdentity(any(ResolveIdentityRequest.class)); + verifyNoMoreInteractions(credentialsProvider); + } + + static class TestPlugin implements SdkPlugin { + private final AwsCredentialsProvider credentialsProvider; + + TestPlugin(AwsCredentialsProvider credentialsProvider) { + this.credentialsProvider = credentialsProvider; + } + + @Override + public void configureClient(SdkServiceClientConfiguration.Builder config) { + ProtocolQueryServiceClientConfiguration.Builder builder = + Validate.isInstanceOf(ProtocolQueryServiceClientConfiguration.Builder.class, + config, + "Expecting an instance of " + + ProtocolQueryServiceClientConfiguration.class); + builder.credentialsProvider(credentialsProvider); + } + } +}