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 b7045285fd95..084c9415ed8d 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
@@ -32,6 +32,7 @@
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.List;
+import java.util.Optional;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;
import javax.lang.model.element.Modifier;
@@ -61,11 +62,17 @@
import software.amazon.awssdk.core.client.handler.AsyncClientHandler;
import software.amazon.awssdk.core.endpointdiscovery.EndpointDiscoveryRefreshCache;
import software.amazon.awssdk.core.endpointdiscovery.EndpointDiscoveryRequest;
+import software.amazon.awssdk.core.internal.util.MetricUtils;
+import software.amazon.awssdk.core.metrics.CoreMetric;
+import software.amazon.awssdk.metrics.MetricCollector;
+import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory;
import software.amazon.awssdk.utils.CompletableFutureUtils;
import software.amazon.awssdk.utils.FunctionalUtils;
public final class AsyncClientClass extends AsyncClientInterface {
+ private static final String PUBLISHER_NAME = "metricPublisher";
+ private static final String METRIC_COLLECTOR_NAME = "apiCallMetricCollector";
private final IntermediateModel model;
private final PoetExtensions poetExtensions;
private final ClassName className;
@@ -190,9 +197,18 @@ private MethodSpec closeMethod() {
protected MethodSpec.Builder operationBody(MethodSpec.Builder builder, OperationModel opModel) {
builder.addModifiers(Modifier.PUBLIC)
- .addAnnotation(Override.class)
- .beginControlFlow("try")
- .addCode(ClientClassUtils.callApplySignerOverrideMethod(opModel))
+ .addAnnotation(Override.class);
+
+ builder.addStatement("$1T $2N = $1T.create($3S)",
+ MetricCollector.class, METRIC_COLLECTOR_NAME, "ApiCall");
+ builder.beginControlFlow("try");
+
+ builder.addStatement("$N.reportMetric($T.$L, $S)", METRIC_COLLECTOR_NAME, CoreMetric.class, "SERVICE_ID",
+ model.getMetadata().getServiceId());
+ builder.addStatement("$N.reportMetric($T.$L, $S)", METRIC_COLLECTOR_NAME, CoreMetric.class, "OPERATION_NAME",
+ opModel.getOperationName());
+
+ builder.addCode(ClientClassUtils.callApplySignerOverrideMethod(opModel))
.addCode(ClientClassUtils.addEndpointTraitCode(opModel))
.addCode(protocolSpec.responseHandler(model, opModel));
protocolSpec.errorResponseHandler(opModel).ifPresent(builder::addCode);
@@ -224,8 +240,17 @@ protected MethodSpec.Builder operationBody(MethodSpec.Builder builder, Operation
"() -> $N.exceptionOccurred(t))", paramName);
}
- return builder.addStatement("return $T.failedFuture(t)", CompletableFutureUtils.class)
- .endControlFlow();
+ builder.addStatement("$T<$T> $N = $T.resolvePublisher(clientConfiguration, $N.overrideConfiguration().orElse(null))",
+ Optional.class,
+ MetricPublisher.class,
+ PUBLISHER_NAME,
+ MetricUtils.class,
+ opModel.getInput().getVariableName())
+ .addStatement("$N.ifPresent(p -> p.publish($N.collect()))", PUBLISHER_NAME, "apiCallMetricCollector")
+ .addStatement("return $T.failedFuture(t)", CompletableFutureUtils.class)
+ .endControlFlow();
+
+ return builder;
}
@Override
diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java
index 3b36a1e330f2..d9eeabfad3f9 100644
--- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java
+++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java
@@ -47,7 +47,6 @@
import software.amazon.awssdk.core.SdkClient;
import software.amazon.awssdk.core.async.AsyncRequestBody;
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
-import software.amazon.awssdk.metrics.MetricCollector;
import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain;
public class AsyncClientInterface implements ClassSpec {
@@ -285,12 +284,6 @@ private MethodSpec traditionalMethod(OperationModel opModel) {
.addParameter(requestType, opModel.getInput().getVariableName())
.addJavadoc(opModel.getDocs(model, ClientType.ASYNC));
-
- String metricCollectorName = "apiCallMetricCollector";
-
- builder.addStatement("$1T $2N = $1T.create($3S)",
- MetricCollector.class, metricCollectorName, "ApiCall");
-
if (opModel.hasStreamingInput()) {
builder.addParameter(ClassName.get(AsyncRequestBody.class), "requestBody");
} else if (opModel.hasEventStreamInput()) {
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 1dd17e93ea4c..3a68c19482a2 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
@@ -28,6 +28,7 @@
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import javax.lang.model.element.Modifier;
+import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
import software.amazon.awssdk.awscore.eventstream.EventStreamAsyncResponseTransformer;
import software.amazon.awssdk.awscore.eventstream.EventStreamTaggedUnionPojoSupplier;
import software.amazon.awssdk.awscore.eventstream.RestEventStreamAsyncResponseTransformer;
@@ -266,6 +267,8 @@ public CodeBlock asyncExecutionHandler(IntermediateModel intermediateModel, Oper
asyncResponseTransformerVariable(isStreaming, isRestJson, opModel));
String whenComplete = whenCompleteBody(opModel, customerResponseHandler);
if (!whenComplete.isEmpty()) {
+ builder.addStatement("$T requestOverrideConfig = $L.overrideConfiguration().orElse(null)",
+ AwsRequestOverrideConfiguration.class, opModel.getInput().getVariableName());
builder.add("executeFuture$L;", whenComplete);
}
if (opModel.hasEventStreamOutput()) {
@@ -326,7 +329,7 @@ private String whenCompleteBody(OperationModel operationModel, String responseHa
return streamingOutputWhenComplete(responseHandlerName);
} else {
// Non streaming can just return the future as is
- return "";
+ return publishMetricsWhenComplete();
}
}
@@ -336,6 +339,7 @@ private String whenCompleteBody(OperationModel operationModel, String responseHa
* {@link EventStreamAsyncResponseTransformer}. Failure is notified via the normal future (the one returned by the client
* handler).
*
+ *
* @param responseHandlerName Variable name of response handler customer passed in.
* @return whenComplete to append to future.
*/
@@ -347,12 +351,12 @@ private String eventStreamOutputWhenComplete(String responseHandlerName) {
+ " } finally {"
+ " future.completeExceptionally(e);"
+ " }"
- + " }%n"
- + "})", responseHandlerName);
+ + " }"
+ + "%s"
+ + "})", responseHandlerName, publishMetrics());
}
-
@Override
public Optional createErrorResponseHandler() {
ClassName httpResponseHandler = ClassName.get(HttpResponseHandler.class);
diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/ProtocolSpec.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/ProtocolSpec.java
index 38ba7afc1f8f..3cd7191e455e 100644
--- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/ProtocolSpec.java
+++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/ProtocolSpec.java
@@ -155,7 +155,8 @@ default String streamingOutputWhenComplete(String responseHandlerName) {
+ " runAndLogError(log, \"Exception thrown in exceptionOccurred callback, ignoring\", () "
+ "-> %s.exceptionOccurred(e));%n"
+ " }%n"
- + "})", responseHandlerName);
+ + "%s"
+ + "})", responseHandlerName, publishMetrics());
}
@@ -177,4 +178,16 @@ default TypeName executeFutureValueType(OperationModel opModel, PoetExtensions p
default TypeName getPojoResponseType(OperationModel opModel, PoetExtensions poetExtensions) {
return poetExtensions.getModelClass(opModel.getReturnType().getReturnType());
}
+
+ default String publishMetricsWhenComplete() {
+ return String.format(".whenComplete((r, e) -> {%n"
+ + "%s%n"
+ + "})", publishMetrics());
+ }
+
+ default String publishMetrics() {
+ return "Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration, "
+ + "requestOverrideConfig);\n"
+ + "metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));";
+ }
}
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 f5a1763a4d1f..46aa35bcf7a0 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
@@ -24,6 +24,7 @@
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import javax.lang.model.element.Modifier;
+import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
import software.amazon.awssdk.awscore.exception.AwsServiceException;
import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel;
import software.amazon.awssdk.codegen.model.intermediate.OperationModel;
@@ -154,9 +155,12 @@ public CodeBlock asyncExecutionHandler(IntermediateModel intermediateModel, Oper
"errorResponseHandler",
opModel.getInput().getVariableName(),
opModel.hasStreamingOutput() ? ", asyncResponseTransformer" : "");
-
+ builder.addStatement("$T requestOverrideConfig = $L.overrideConfiguration().orElse(null)",
+ AwsRequestOverrideConfiguration.class, opModel.getInput().getVariableName());
if (opModel.hasStreamingOutput()) {
builder.add("executeFuture$L;", streamingOutputWhenComplete("asyncResponseTransformer"));
+ } else {
+ builder.add("executeFuture$L;", publishMetricsWhenComplete());
}
builder.addStatement("return executeFuture");
return builder.build();
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 9eacd267a14c..a543a0fad876 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
@@ -20,6 +20,7 @@
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import java.util.Optional;
+import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel;
import software.amazon.awssdk.codegen.model.intermediate.OperationModel;
import software.amazon.awssdk.codegen.poet.PoetExtensions;
@@ -169,8 +170,12 @@ public CodeBlock asyncExecutionHandler(IntermediateModel intermediateModel, Oper
opModel.getInput().getVariableName(),
opModel.hasStreamingOutput() ? ", asyncResponseTransformer" : "");
+ builder.addStatement("$T requestOverrideConfig = $L.overrideConfiguration().orElse(null)",
+ AwsRequestOverrideConfiguration.class, opModel.getInput().getVariableName());
if (opModel.hasStreamingOutput()) {
builder.add("executeFuture$L;", streamingOutputWhenComplete("asyncResponseTransformer"));
+ } else {
+ builder.add("executeFuture$L;", publishMetricsWhenComplete());
}
builder.addStatement("return executeFuture");
return builder.build();
diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-async-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-async-client-class.java
index 2b0c659a467f..0a0f07dfbffc 100644
--- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-async-client-class.java
+++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-async-client-class.java
@@ -3,6 +3,7 @@
import static software.amazon.awssdk.utils.FunctionalUtils.runAndLogError;
import java.nio.ByteBuffer;
+import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -33,11 +34,14 @@
import software.amazon.awssdk.core.client.handler.AttachHttpMetadataResponseHandler;
import software.amazon.awssdk.core.client.handler.ClientExecutionParams;
import software.amazon.awssdk.core.http.HttpResponseHandler;
+import software.amazon.awssdk.core.internal.util.MetricUtils;
+import software.amazon.awssdk.core.metrics.CoreMetric;
import software.amazon.awssdk.core.protocol.VoidSdkResponse;
import software.amazon.awssdk.core.runtime.transform.AsyncStreamingRequestMarshaller;
import software.amazon.awssdk.core.signer.Signer;
import software.amazon.awssdk.core.util.VersionInfo;
import software.amazon.awssdk.metrics.MetricCollector;
+import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.protocols.core.ExceptionMetadata;
import software.amazon.awssdk.protocols.json.AwsJsonProtocol;
import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory;
@@ -154,6 +158,8 @@ public final String serviceName() {
public CompletableFuture aPostOperation(APostOperationRequest aPostOperationRequest) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperation");
String hostPrefix = "{StringMember}-foo.";
Validate.paramNotBlank(aPostOperationRequest.stringMember(), "StringMember");
String resolvedHostExpression = String.format("%s-foo.", aPostOperationRequest.stringMember());
@@ -172,8 +178,17 @@ public CompletableFuture aPostOperation(APostOperationRe
.withMarshaller(new APostOperationRequestMarshaller(protocolFactory))
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.hostPrefixExpression(resolvedHostExpression).withInput(aPostOperationRequest));
+ AwsRequestOverrideConfiguration requestOverrideConfig = aPostOperationRequest.overrideConfiguration().orElse(null);
+ executeFuture.whenComplete((r, e) -> {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
+ });
return executeFuture;
} catch (Throwable t) {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration, aPostOperationRequest
+ .overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -206,6 +221,8 @@ public CompletableFuture aPostOperationWithOut
APostOperationWithOutputRequest aPostOperationWithOutputRequest) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperationWithOutput");
JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false)
.isPayloadJson(true).build();
@@ -221,8 +238,18 @@ public CompletableFuture aPostOperationWithOut
.withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory))
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.withInput(aPostOperationWithOutputRequest));
+ AwsRequestOverrideConfiguration requestOverrideConfig = aPostOperationWithOutputRequest.overrideConfiguration()
+ .orElse(null);
+ executeFuture.whenComplete((r, e) -> {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
+ });
return executeFuture;
} catch (Throwable t) {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ aPostOperationWithOutputRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -251,6 +278,8 @@ public CompletableFuture eventStreamOperation(EventStreamOperationRequest
Publisher requestStream, EventStreamOperationResponseHandler asyncResponseHandler) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "EventStreamOperation");
eventStreamOperationRequest = applySignerOverride(eventStreamOperationRequest, EventStreamAws4Signer.create());
JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false)
.isPayloadJson(true).build();
@@ -293,6 +322,8 @@ public CompletableFuture eventStreamOperation(EventStreamOperationRequest
.withFullDuplex(true).withResponseHandler(responseHandler)
.withErrorResponseHandler(errorResponseHandler).withInput(eventStreamOperationRequest),
restAsyncResponseTransformer);
+ AwsRequestOverrideConfiguration requestOverrideConfig = eventStreamOperationRequest.overrideConfiguration().orElse(
+ null);
executeFuture.whenComplete((r, e) -> {
if (e != null) {
try {
@@ -301,11 +332,17 @@ public CompletableFuture eventStreamOperation(EventStreamOperationRequest
future.completeExceptionally(e);
}
}
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
});
return CompletableFutureUtils.forwardExceptionTo(future, executeFuture);
} catch (Throwable t) {
runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring",
() -> asyncResponseHandler.exceptionOccurred(t));
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ eventStreamOperationRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -336,6 +373,8 @@ public CompletableFuture eventStreamO
Publisher requestStream) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "EventStreamOperationWithOnlyInput");
eventStreamOperationWithOnlyInputRequest = applySignerOverride(eventStreamOperationWithOnlyInputRequest,
EventStreamAws4Signer.create());
JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false)
@@ -360,8 +399,18 @@ public CompletableFuture eventStreamO
.withAsyncRequestBody(software.amazon.awssdk.core.async.AsyncRequestBody.fromPublisher(adapted))
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.withInput(eventStreamOperationWithOnlyInputRequest));
+ AwsRequestOverrideConfiguration requestOverrideConfig = eventStreamOperationWithOnlyInputRequest
+ .overrideConfiguration().orElse(null);
+ executeFuture.whenComplete((r, e) -> {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
+ });
return executeFuture;
} catch (Throwable t) {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ eventStreamOperationWithOnlyInputRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -392,6 +441,8 @@ public CompletableFuture eventStreamOperationWithOnlyOutput(
EventStreamOperationWithOnlyOutputResponseHandler asyncResponseHandler) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "EventStreamOperationWithOnlyOutput");
JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false)
.isPayloadJson(true).build();
@@ -427,6 +478,8 @@ public CompletableFuture eventStreamOperationWithOnlyOutput(
.withMarshaller(new EventStreamOperationWithOnlyOutputRequestMarshaller(protocolFactory))
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.withInput(eventStreamOperationWithOnlyOutputRequest), restAsyncResponseTransformer);
+ AwsRequestOverrideConfiguration requestOverrideConfig = eventStreamOperationWithOnlyOutputRequest
+ .overrideConfiguration().orElse(null);
executeFuture.whenComplete((r, e) -> {
if (e != null) {
try {
@@ -435,11 +488,17 @@ public CompletableFuture eventStreamOperationWithOnlyOutput(
future.completeExceptionally(e);
}
}
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
});
return CompletableFutureUtils.forwardExceptionTo(future, executeFuture);
} catch (Throwable t) {
runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring",
() -> asyncResponseHandler.exceptionOccurred(t));
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ eventStreamOperationWithOnlyOutputRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -472,6 +531,8 @@ public CompletableFuture getWithoutRequiredMe
GetWithoutRequiredMembersRequest getWithoutRequiredMembersRequest) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "GetWithoutRequiredMembers");
JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false)
.isPayloadJson(true).build();
@@ -487,8 +548,18 @@ public CompletableFuture getWithoutRequiredMe
.withMarshaller(new GetWithoutRequiredMembersRequestMarshaller(protocolFactory))
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.withInput(getWithoutRequiredMembersRequest));
+ AwsRequestOverrideConfiguration requestOverrideConfig = getWithoutRequiredMembersRequest.overrideConfiguration()
+ .orElse(null);
+ executeFuture.whenComplete((r, e) -> {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
+ });
return executeFuture;
} catch (Throwable t) {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ getWithoutRequiredMembersRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -518,6 +589,8 @@ public CompletableFuture paginatedOpera
PaginatedOperationWithResultKeyRequest paginatedOperationWithResultKeyRequest) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "PaginatedOperationWithResultKey");
JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false)
.isPayloadJson(true).build();
@@ -533,8 +606,18 @@ public CompletableFuture paginatedOpera
.withMarshaller(new PaginatedOperationWithResultKeyRequestMarshaller(protocolFactory))
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.withInput(paginatedOperationWithResultKeyRequest));
+ AwsRequestOverrideConfiguration requestOverrideConfig = paginatedOperationWithResultKeyRequest
+ .overrideConfiguration().orElse(null);
+ executeFuture.whenComplete((r, e) -> {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
+ });
return executeFuture;
} catch (Throwable t) {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ paginatedOperationWithResultKeyRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -561,7 +644,7 @@ public CompletableFuture paginatedOpera
* The following are few ways to use the response class:
*
* 1) Using the subscribe helper method
- *
+ *
*
* {@code
* software.amazon.awssdk.services.json.paginators.PaginatedOperationWithResultKeyPublisher publisher = client.paginatedOperationWithResultKeyPaginator(request);
@@ -571,19 +654,19 @@ public CompletableFuture paginatedOpera
*
*
* 2) Using a custom subscriber
- *
+ *
*
* {@code
* software.amazon.awssdk.services.json.paginators.PaginatedOperationWithResultKeyPublisher publisher = client.paginatedOperationWithResultKeyPaginator(request);
* publisher.subscribe(new Subscriber() {
- *
+ *
* public void onSubscribe(org.reactivestreams.Subscriber subscription) { //... };
- *
- *
+ *
+ *
* public void onNext(software.amazon.awssdk.services.json.model.PaginatedOperationWithResultKeyResponse response) { //... };
* });}
*
- *
+ *
* As the response is a publisher, it can work well with third party reactive streams implementations like RxJava2.
*
* Please notice that the configuration of MaxResults won't limit the number of results you get with the
@@ -641,6 +724,8 @@ public CompletableFuture paginatedOp
PaginatedOperationWithoutResultKeyRequest paginatedOperationWithoutResultKeyRequest) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "PaginatedOperationWithoutResultKey");
JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false)
.isPayloadJson(true).build();
@@ -656,8 +741,18 @@ public CompletableFuture paginatedOp
.withMarshaller(new PaginatedOperationWithoutResultKeyRequestMarshaller(protocolFactory))
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.withInput(paginatedOperationWithoutResultKeyRequest));
+ AwsRequestOverrideConfiguration requestOverrideConfig = paginatedOperationWithoutResultKeyRequest
+ .overrideConfiguration().orElse(null);
+ executeFuture.whenComplete((r, e) -> {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
+ });
return executeFuture;
} catch (Throwable t) {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ paginatedOperationWithoutResultKeyRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -684,7 +779,7 @@ public CompletableFuture paginatedOp
* The following are few ways to use the response class:
*
* 1) Using the subscribe helper method
- *
+ *
*
* {@code
* software.amazon.awssdk.services.json.paginators.PaginatedOperationWithoutResultKeyPublisher publisher = client.paginatedOperationWithoutResultKeyPaginator(request);
@@ -694,19 +789,19 @@ public CompletableFuture paginatedOp
*
*
* 2) Using a custom subscriber
- *
+ *
*
* {@code
* software.amazon.awssdk.services.json.paginators.PaginatedOperationWithoutResultKeyPublisher publisher = client.paginatedOperationWithoutResultKeyPaginator(request);
* publisher.subscribe(new Subscriber() {
- *
+ *
* public void onSubscribe(org.reactivestreams.Subscriber subscription) { //... };
- *
- *
+ *
+ *
* public void onNext(software.amazon.awssdk.services.json.model.PaginatedOperationWithoutResultKeyResponse response) { //... };
* });}
*
- *
+ *
* As the response is a publisher, it can work well with third party reactive streams implementations like RxJava2.
*
* Please notice that the configuration of MaxResults won't limit the number of results you get with the
@@ -769,6 +864,8 @@ public CompletableFuture streamingInputOperatio
StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingInputOperation");
JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false)
.isPayloadJson(true).build();
@@ -787,8 +884,18 @@ public CompletableFuture streamingInputOperatio
.asyncRequestBody(requestBody).build()).withResponseHandler(responseHandler)
.withErrorResponseHandler(errorResponseHandler).withAsyncRequestBody(requestBody)
.withInput(streamingInputOperationRequest));
+ AwsRequestOverrideConfiguration requestOverrideConfig = streamingInputOperationRequest.overrideConfiguration()
+ .orElse(null);
+ executeFuture.whenComplete((r, e) -> {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
+ });
return executeFuture;
} catch (Throwable t) {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ streamingInputOperationRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -828,6 +935,8 @@ public CompletableFuture streamingInputOutputOperation(
AsyncResponseTransformer asyncResponseTransformer) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingInputOutputOperation");
streamingInputOutputOperationRequest = applySignerOverride(streamingInputOutputOperationRequest,
Aws4UnsignedPayloadSigner.create());
JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(true)
@@ -851,16 +960,24 @@ public CompletableFuture streamingInputOutputOperation(
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.withAsyncRequestBody(requestBody).withInput(streamingInputOutputOperationRequest),
asyncResponseTransformer);
+ AwsRequestOverrideConfiguration requestOverrideConfig = streamingInputOutputOperationRequest.overrideConfiguration()
+ .orElse(null);
executeFuture.whenComplete((r, e) -> {
if (e != null) {
runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring",
() -> asyncResponseTransformer.exceptionOccurred(e));
}
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
});
return executeFuture;
} catch (Throwable t) {
runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring",
() -> asyncResponseTransformer.exceptionOccurred(t));
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ streamingInputOutputOperationRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -895,6 +1012,8 @@ public CompletableFuture streamingOutputOperation(
AsyncResponseTransformer asyncResponseTransformer) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Json Service");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingOutputOperation");
JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(true)
.isPayloadJson(false).build();
@@ -910,16 +1029,24 @@ public CompletableFuture streamingOutputOperation(
.withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory))
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.withInput(streamingOutputOperationRequest), asyncResponseTransformer);
+ AwsRequestOverrideConfiguration requestOverrideConfig = streamingOutputOperationRequest.overrideConfiguration()
+ .orElse(null);
executeFuture.whenComplete((r, e) -> {
if (e != null) {
runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring",
() -> asyncResponseTransformer.exceptionOccurred(e));
}
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
});
return executeFuture;
} catch (Throwable t) {
runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring",
() -> asyncResponseTransformer.exceptionOccurred(t));
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ streamingOutputOperationRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
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 da4ca5d9f07b..728e1842e8ab 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
@@ -3,11 +3,13 @@
import static software.amazon.awssdk.utils.FunctionalUtils.runAndLogError;
import java.net.URI;
+import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.annotations.Generated;
import software.amazon.awssdk.annotations.SdkInternalApi;
+import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
import software.amazon.awssdk.awscore.client.config.AwsClientOption;
import software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler;
import software.amazon.awssdk.awscore.exception.AwsServiceException;
@@ -18,7 +20,10 @@
import software.amazon.awssdk.core.endpointdiscovery.EndpointDiscoveryRefreshCache;
import software.amazon.awssdk.core.endpointdiscovery.EndpointDiscoveryRequest;
import software.amazon.awssdk.core.http.HttpResponseHandler;
+import software.amazon.awssdk.core.internal.util.MetricUtils;
+import software.amazon.awssdk.core.metrics.CoreMetric;
import software.amazon.awssdk.metrics.MetricCollector;
+import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.protocols.json.AwsJsonProtocol;
import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory;
import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory;
@@ -92,6 +97,8 @@ public final String serviceName() {
public CompletableFuture describeEndpoints(DescribeEndpointsRequest describeEndpointsRequest) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "AwsEndpointDiscoveryTest");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "DescribeEndpoints");
JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false)
.isPayloadJson(true).build();
@@ -107,8 +114,17 @@ public CompletableFuture describeEndpoints(DescribeEn
.withMarshaller(new DescribeEndpointsRequestMarshaller(protocolFactory))
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.withInput(describeEndpointsRequest));
+ AwsRequestOverrideConfiguration requestOverrideConfig = describeEndpointsRequest.overrideConfiguration().orElse(null);
+ executeFuture.whenComplete((r, e) -> {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
+ });
return executeFuture;
} catch (Throwable t) {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ describeEndpointsRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -136,6 +152,8 @@ public CompletableFuture testDiscovery
TestDiscoveryIdentifiersRequiredRequest testDiscoveryIdentifiersRequiredRequest) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "AwsEndpointDiscoveryTest");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "TestDiscoveryIdentifiersRequired");
JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false)
.isPayloadJson(true).build();
@@ -159,8 +177,18 @@ public CompletableFuture testDiscovery
.withMarshaller(new TestDiscoveryIdentifiersRequiredRequestMarshaller(protocolFactory))
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.discoveredEndpoint(cachedEndpoint).withInput(testDiscoveryIdentifiersRequiredRequest));
+ AwsRequestOverrideConfiguration requestOverrideConfig = testDiscoveryIdentifiersRequiredRequest
+ .overrideConfiguration().orElse(null);
+ executeFuture.whenComplete((r, e) -> {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
+ });
return executeFuture;
} catch (Throwable t) {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ testDiscoveryIdentifiersRequiredRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -187,6 +215,8 @@ public CompletableFuture testDiscoveryOptional(
TestDiscoveryOptionalRequest testDiscoveryOptionalRequest) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "AwsEndpointDiscoveryTest");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "TestDiscoveryOptional");
JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false)
.isPayloadJson(true).build();
@@ -210,8 +240,18 @@ public CompletableFuture testDiscoveryOptional(
.withMarshaller(new TestDiscoveryOptionalRequestMarshaller(protocolFactory))
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.discoveredEndpoint(cachedEndpoint).withInput(testDiscoveryOptionalRequest));
+ AwsRequestOverrideConfiguration requestOverrideConfig = testDiscoveryOptionalRequest.overrideConfiguration().orElse(
+ null);
+ executeFuture.whenComplete((r, e) -> {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
+ });
return executeFuture;
} catch (Throwable t) {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ testDiscoveryOptionalRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -238,6 +278,8 @@ public CompletableFuture testDiscoveryRequired(
TestDiscoveryRequiredRequest testDiscoveryRequiredRequest) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "AwsEndpointDiscoveryTest");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "TestDiscoveryRequired");
JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false)
.isPayloadJson(true).build();
@@ -261,8 +303,18 @@ public CompletableFuture testDiscoveryRequired(
.withMarshaller(new TestDiscoveryRequiredRequestMarshaller(protocolFactory))
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.discoveredEndpoint(cachedEndpoint).withInput(testDiscoveryRequiredRequest));
+ AwsRequestOverrideConfiguration requestOverrideConfig = testDiscoveryRequiredRequest.overrideConfiguration().orElse(
+ null);
+ executeFuture.whenComplete((r, e) -> {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
+ });
return executeFuture;
} catch (Throwable t) {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ testDiscoveryRequiredRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java
index 0024827d14a9..e97f69cd5896 100644
--- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java
+++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java
@@ -8,7 +8,6 @@
import software.amazon.awssdk.core.SdkClient;
import software.amazon.awssdk.core.async.AsyncRequestBody;
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
-import software.amazon.awssdk.metrics.MetricCollector;
import software.amazon.awssdk.services.json.model.APostOperationRequest;
import software.amazon.awssdk.services.json.model.APostOperationResponse;
import software.amazon.awssdk.services.json.model.APostOperationWithOutputRequest;
@@ -86,7 +85,6 @@ static JsonAsyncClientBuilder builder() {
* API Documentation
*/
default CompletableFuture aPostOperation(APostOperationRequest aPostOperationRequest) {
- MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
throw new UnsupportedOperationException();
}
@@ -148,7 +146,6 @@ default CompletableFuture aPostOperation(Consumer aPostOperationWithOutput(
APostOperationWithOutputRequest aPostOperationWithOutputRequest) {
- MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
throw new UnsupportedOperationException();
}
@@ -209,7 +206,6 @@ default CompletableFuture aPostOperationWithOu
*/
default CompletableFuture eventStreamOperation(EventStreamOperationRequest eventStreamOperationRequest,
Publisher requestStream, EventStreamOperationResponseHandler asyncResponseHandler) {
- MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
throw new UnsupportedOperationException();
}
@@ -268,7 +264,6 @@ default CompletableFuture eventStreamOperation(
default CompletableFuture eventStreamOperationWithOnlyInput(
EventStreamOperationWithOnlyInputRequest eventStreamOperationWithOnlyInputRequest,
Publisher requestStream) {
- MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
throw new UnsupportedOperationException();
}
@@ -329,7 +324,6 @@ default CompletableFuture eventStream
default CompletableFuture eventStreamOperationWithOnlyOutput(
EventStreamOperationWithOnlyOutputRequest eventStreamOperationWithOnlyOutputRequest,
EventStreamOperationWithOnlyOutputResponseHandler asyncResponseHandler) {
- MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
throw new UnsupportedOperationException();
}
@@ -392,7 +386,6 @@ default CompletableFuture eventStreamOperationWithOnlyOutput(
*/
default CompletableFuture getWithoutRequiredMembers(
GetWithoutRequiredMembersRequest getWithoutRequiredMembersRequest) {
- MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
throw new UnsupportedOperationException();
}
@@ -454,7 +447,6 @@ default CompletableFuture getWithoutRequiredM
*/
default CompletableFuture paginatedOperationWithResultKey(
PaginatedOperationWithResultKeyRequest paginatedOperationWithResultKeyRequest) {
- MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
throw new UnsupportedOperationException();
}
@@ -535,7 +527,7 @@ default CompletableFuture paginatedOper
* The following are few ways to use the response class:
*
* 1) Using the subscribe helper method
- *
+ *
*
* {@code
* software.amazon.awssdk.services.json.paginators.PaginatedOperationWithResultKeyPublisher publisher = client.paginatedOperationWithResultKeyPaginator(request);
@@ -545,19 +537,19 @@ default CompletableFuture paginatedOper
*
*
* 2) Using a custom subscriber
- *
+ *
*
* {@code
* software.amazon.awssdk.services.json.paginators.PaginatedOperationWithResultKeyPublisher publisher = client.paginatedOperationWithResultKeyPaginator(request);
* publisher.subscribe(new Subscriber() {
- *
+ *
* public void onSubscribe(org.reactivestreams.Subscriber subscription) { //... };
- *
- *
+ *
+ *
* public void onNext(software.amazon.awssdk.services.json.model.PaginatedOperationWithResultKeyResponse response) { //... };
* });}
*
- *
+ *
* As the response is a publisher, it can work well with third party reactive streams implementations like RxJava2.
*
* Please notice that the configuration of MaxResults won't limit the number of results you get with the
@@ -610,7 +602,7 @@ default PaginatedOperationWithResultKeyPublisher paginatedOperationWithResultKey
* The following are few ways to use the response class:
*
* 1) Using the subscribe helper method
- *
+ *
*
* {@code
* software.amazon.awssdk.services.json.paginators.PaginatedOperationWithResultKeyPublisher publisher = client.paginatedOperationWithResultKeyPaginator(request);
@@ -620,19 +612,19 @@ default PaginatedOperationWithResultKeyPublisher paginatedOperationWithResultKey
*
*
* 2) Using a custom subscriber
- *
+ *
*
* {@code
* software.amazon.awssdk.services.json.paginators.PaginatedOperationWithResultKeyPublisher publisher = client.paginatedOperationWithResultKeyPaginator(request);
* publisher.subscribe(new Subscriber() {
- *
+ *
* public void onSubscribe(org.reactivestreams.Subscriber subscription) { //... };
- *
- *
+ *
+ *
* public void onNext(software.amazon.awssdk.services.json.model.PaginatedOperationWithResultKeyResponse response) { //... };
* });}
*
- *
+ *
* As the response is a publisher, it can work well with third party reactive streams implementations like RxJava2.
*
* Please notice that the configuration of MaxResults won't limit the number of results you get with the
@@ -687,7 +679,7 @@ default PaginatedOperationWithResultKeyPublisher paginatedOperationWithResultKey
* The following are few ways to use the response class:
*
* 1) Using the subscribe helper method
- *
+ *
*
* {@code
* software.amazon.awssdk.services.json.paginators.PaginatedOperationWithResultKeyPublisher publisher = client.paginatedOperationWithResultKeyPaginator(request);
@@ -697,19 +689,19 @@ default PaginatedOperationWithResultKeyPublisher paginatedOperationWithResultKey
*
*
* 2) Using a custom subscriber
- *
+ *
*
* {@code
* software.amazon.awssdk.services.json.paginators.PaginatedOperationWithResultKeyPublisher publisher = client.paginatedOperationWithResultKeyPaginator(request);
* publisher.subscribe(new Subscriber() {
- *
+ *
* public void onSubscribe(org.reactivestreams.Subscriber subscription) { //... };
- *
- *
+ *
+ *
* public void onNext(software.amazon.awssdk.services.json.model.PaginatedOperationWithResultKeyResponse response) { //... };
* });}
*
- *
+ *
* As the response is a publisher, it can work well with third party reactive streams implementations like RxJava2.
*
* Please notice that the configuration of MaxResults won't limit the number of results you get with the
@@ -771,7 +763,6 @@ default PaginatedOperationWithResultKeyPublisher paginatedOperationWithResultKey
*/
default CompletableFuture paginatedOperationWithoutResultKey(
PaginatedOperationWithoutResultKeyRequest paginatedOperationWithoutResultKeyRequest) {
- MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
throw new UnsupportedOperationException();
}
@@ -829,7 +820,7 @@ default CompletableFuture paginatedO
* The following are few ways to use the response class:
*
* 1) Using the subscribe helper method
- *
+ *
*
* {@code
* software.amazon.awssdk.services.json.paginators.PaginatedOperationWithoutResultKeyPublisher publisher = client.paginatedOperationWithoutResultKeyPaginator(request);
@@ -839,19 +830,19 @@ default CompletableFuture paginatedO
*
*
* 2) Using a custom subscriber
- *
+ *
*
* {@code
* software.amazon.awssdk.services.json.paginators.PaginatedOperationWithoutResultKeyPublisher publisher = client.paginatedOperationWithoutResultKeyPaginator(request);
* publisher.subscribe(new Subscriber() {
- *
+ *
* public void onSubscribe(org.reactivestreams.Subscriber subscription) { //... };
- *
- *
+ *
+ *
* public void onNext(software.amazon.awssdk.services.json.model.PaginatedOperationWithoutResultKeyResponse response) { //... };
* });}
*
- *
+ *
* As the response is a publisher, it can work well with third party reactive streams implementations like RxJava2.
*
* Please notice that the configuration of MaxResults won't limit the number of results you get with the
@@ -906,7 +897,7 @@ default PaginatedOperationWithoutResultKeyPublisher paginatedOperationWithoutRes
* The following are few ways to use the response class:
*
* 1) Using the subscribe helper method
- *
+ *
*
* {@code
* software.amazon.awssdk.services.json.paginators.PaginatedOperationWithoutResultKeyPublisher publisher = client.paginatedOperationWithoutResultKeyPaginator(request);
@@ -916,19 +907,19 @@ default PaginatedOperationWithoutResultKeyPublisher paginatedOperationWithoutRes
*
*
* 2) Using a custom subscriber
- *
+ *
*
* {@code
* software.amazon.awssdk.services.json.paginators.PaginatedOperationWithoutResultKeyPublisher publisher = client.paginatedOperationWithoutResultKeyPaginator(request);
* publisher.subscribe(new Subscriber() {
- *
+ *
* public void onSubscribe(org.reactivestreams.Subscriber subscription) { //... };
- *
- *
+ *
+ *
* public void onNext(software.amazon.awssdk.services.json.model.PaginatedOperationWithoutResultKeyResponse response) { //... };
* });}
*
- *
+ *
* As the response is a publisher, it can work well with third party reactive streams implementations like RxJava2.
*
* Please notice that the configuration of MaxResults won't limit the number of results you get with the
@@ -994,7 +985,6 @@ default PaginatedOperationWithoutResultKeyPublisher paginatedOperationWithoutRes
*/
default CompletableFuture streamingInputOperation(
StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) {
- MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
throw new UnsupportedOperationException();
}
@@ -1131,7 +1121,6 @@ default CompletableFuture streamingInputOperati
default CompletableFuture streamingInputOutputOperation(
StreamingInputOutputOperationRequest streamingInputOutputOperationRequest, AsyncRequestBody requestBody,
AsyncResponseTransformer asyncResponseTransformer) {
- MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
throw new UnsupportedOperationException();
}
@@ -1282,7 +1271,6 @@ default CompletableFuture streamingInputO
default CompletableFuture streamingOutputOperation(
StreamingOutputOperationRequest streamingOutputOperationRequest,
AsyncResponseTransformer asyncResponseTransformer) {
- MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
throw new UnsupportedOperationException();
}
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 e96ac5147355..c8b53faf5172 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
@@ -2,11 +2,13 @@
import static software.amazon.awssdk.utils.FunctionalUtils.runAndLogError;
+import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.annotations.Generated;
import software.amazon.awssdk.annotations.SdkInternalApi;
+import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
import software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler;
import software.amazon.awssdk.awscore.exception.AwsServiceException;
import software.amazon.awssdk.core.async.AsyncRequestBody;
@@ -15,8 +17,11 @@
import software.amazon.awssdk.core.client.handler.AsyncClientHandler;
import software.amazon.awssdk.core.client.handler.ClientExecutionParams;
import software.amazon.awssdk.core.http.HttpResponseHandler;
+import software.amazon.awssdk.core.internal.util.MetricUtils;
+import software.amazon.awssdk.core.metrics.CoreMetric;
import software.amazon.awssdk.core.runtime.transform.AsyncStreamingRequestMarshaller;
import software.amazon.awssdk.metrics.MetricCollector;
+import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.protocols.core.ExceptionMetadata;
import software.amazon.awssdk.protocols.query.AwsQueryProtocolFactory;
import software.amazon.awssdk.services.query.model.APostOperationRequest;
@@ -89,6 +94,8 @@ public final String serviceName() {
public CompletableFuture aPostOperation(APostOperationRequest aPostOperationRequest) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperation");
String hostPrefix = "foo-";
String resolvedHostExpression = "foo-";
@@ -103,8 +110,17 @@ public CompletableFuture aPostOperation(APostOperationRe
.withMarshaller(new APostOperationRequestMarshaller(protocolFactory))
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.hostPrefixExpression(resolvedHostExpression).withInput(aPostOperationRequest));
+ AwsRequestOverrideConfiguration requestOverrideConfig = aPostOperationRequest.overrideConfiguration().orElse(null);
+ executeFuture.whenComplete((r, e) -> {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
+ });
return executeFuture;
} catch (Throwable t) {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration, aPostOperationRequest
+ .overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -137,6 +153,8 @@ public CompletableFuture aPostOperationWithOut
APostOperationWithOutputRequest aPostOperationWithOutputRequest) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "APostOperationWithOutput");
HttpResponseHandler responseHandler = protocolFactory
.createResponseHandler(APostOperationWithOutputResponse::builder);
@@ -149,8 +167,18 @@ public CompletableFuture aPostOperationWithOut
.withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory))
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.withInput(aPostOperationWithOutputRequest));
+ AwsRequestOverrideConfiguration requestOverrideConfig = aPostOperationWithOutputRequest.overrideConfiguration()
+ .orElse(null);
+ executeFuture.whenComplete((r, e) -> {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
+ });
return executeFuture;
} catch (Throwable t) {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ aPostOperationWithOutputRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -184,6 +212,8 @@ public CompletableFuture streamingInputOperatio
StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingInputOperation");
HttpResponseHandler responseHandler = protocolFactory
.createResponseHandler(StreamingInputOperationResponse::builder);
@@ -199,8 +229,18 @@ public CompletableFuture streamingInputOperatio
.asyncRequestBody(requestBody).build()).withResponseHandler(responseHandler)
.withErrorResponseHandler(errorResponseHandler).withAsyncRequestBody(requestBody)
.withInput(streamingInputOperationRequest));
+ AwsRequestOverrideConfiguration requestOverrideConfig = streamingInputOperationRequest.overrideConfiguration()
+ .orElse(null);
+ executeFuture.whenComplete((r, e) -> {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
+ });
return executeFuture;
} catch (Throwable t) {
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ streamingInputOperationRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
@@ -235,6 +275,8 @@ public CompletableFuture streamingOutputOperation(
AsyncResponseTransformer asyncResponseTransformer) {
MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall");
try {
+ apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "Query Service");
+ apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "StreamingOutputOperation");
HttpResponseHandler responseHandler = protocolFactory
.createResponseHandler(StreamingOutputOperationResponse::builder);
@@ -247,16 +289,24 @@ public CompletableFuture streamingOutputOperation(
.withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory))
.withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler)
.withInput(streamingOutputOperationRequest), asyncResponseTransformer);
+ AwsRequestOverrideConfiguration requestOverrideConfig = streamingOutputOperationRequest.overrideConfiguration()
+ .orElse(null);
executeFuture.whenComplete((r, e) -> {
if (e != null) {
runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring",
() -> asyncResponseTransformer.exceptionOccurred(e));
}
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ requestOverrideConfig);
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
});
return executeFuture;
} catch (Throwable t) {
runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring",
() -> asyncResponseTransformer.exceptionOccurred(t));
+ Optional metricPublisher = MetricUtils.resolvePublisher(clientConfiguration,
+ streamingOutputOperationRequest.overrideConfiguration().orElse(null));
+ metricPublisher.ifPresent(p -> p.publish(apiCallMetricCollector.collect()));
return CompletableFutureUtils.failedFuture(t);
}
}
diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/util/MetricUtils.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/util/MetricUtils.java
index dcd0554cdde5..629b57524685 100644
--- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/util/MetricUtils.java
+++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/util/MetricUtils.java
@@ -26,6 +26,7 @@
import software.amazon.awssdk.core.SdkRequest;
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
import software.amazon.awssdk.metrics.MetricPublisher;
+import software.amazon.awssdk.utils.OptionalUtils;
import software.amazon.awssdk.utils.Pair;
/**
@@ -44,6 +45,7 @@ private MetricUtils() {
* @param requestConfig The request override configuration.
* @return The metric publisher to use.
*/
+ //TODO: remove this and use the overload instead
public static Optional resolvePublisher(SdkClientConfiguration clientConfig,
SdkRequest requestConfig) {
Optional requestOverride = requestConfig.overrideConfiguration()
@@ -54,6 +56,22 @@ public static Optional resolvePublisher(SdkClientConfiguration
return Optional.ofNullable(clientConfig.option(METRIC_PUBLISHER));
}
+ /**
+ * Resolve the correct metric publisher to use. The publisher set on the request always takes precedence.
+ *
+ * @param clientConfig The client configuration.
+ * @param requestConfig The request override configuration.
+ * @return The metric publisher to use.
+ */
+ public static Optional resolvePublisher(SdkClientConfiguration clientConfig,
+ RequestOverrideConfiguration requestConfig) {
+ if (requestConfig != null) {
+ return OptionalUtils.firstPresent(requestConfig.metricPublisher(), () -> clientConfig.option(METRIC_PUBLISHER));
+ }
+
+ return Optional.ofNullable(clientConfig.option(METRIC_PUBLISHER));
+ }
+
/**
* Measure the duration of the given callable.
*
diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/metrics/CoreMetric.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/metrics/CoreMetric.java
index 857a607b6de1..e0aa69d59a0e 100644
--- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/metrics/CoreMetric.java
+++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/metrics/CoreMetric.java
@@ -76,7 +76,7 @@ public final class CoreMetric {
/**
* The exception thrown during request execution. Note this may be a service
- * error that has been unmarshalled, or a clientside exception.
+ * error that has been unmarshalled, or a client side exception.
*/
public static final SdkMetric EXCEPTION = metric("Exception", Throwable.class);
diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/AsyncCoreMetricsTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/AsyncCoreMetricsTest.java
new file mode 100644
index 000000000000..73d52ba22b38
--- /dev/null
+++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/AsyncCoreMetricsTest.java
@@ -0,0 +1,158 @@
+/*
+ * 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.metrics;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import java.io.IOException;
+import java.net.URI;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.core.metrics.CoreMetric;
+import software.amazon.awssdk.metrics.MetricCollection;
+import software.amazon.awssdk.metrics.MetricPublisher;
+import software.amazon.awssdk.services.protocolrestjson.ProtocolRestJsonAsyncClient;
+import software.amazon.awssdk.services.protocolrestjson.model.ProtocolRestJsonException;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AsyncCoreMetricsTest {
+ private static final String SERVICE_ID = "AmazonProtocolRestJson";
+ private static final String REQUEST_ID = "req-id";
+ private static final String EXTENDED_REQUEST_ID = "extended-id";
+
+ private static ProtocolRestJsonAsyncClient client;
+
+ @Rule
+ public WireMockRule wireMock = new WireMockRule(0);
+
+ @Mock
+ private AwsCredentialsProvider mockCredentialsProvider;
+
+ @Mock
+ private MetricPublisher mockPublisher;
+
+ @Before
+ public void setup() throws IOException {
+ client = ProtocolRestJsonAsyncClient.builder()
+ .credentialsProvider(mockCredentialsProvider)
+ .endpointOverride(URI.create("http://localhost:" + wireMock.port()))
+ .overrideConfiguration(c -> c.metricPublisher(mockPublisher))
+ .build();
+
+ when(mockCredentialsProvider.resolveCredentials()).thenAnswer(invocation -> {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ie) {
+ ie.printStackTrace();
+ }
+ return AwsBasicCredentials.create("foo", "bar");
+ });
+ }
+
+ @After
+ public void teardown() {
+ if (client != null) {
+ client.close();
+ }
+ client = null;
+ }
+
+ @Test
+ public void apiCall_noConfiguredPublisher_succeeds() {
+ stubSuccessfulResponse();
+ ProtocolRestJsonAsyncClient noPublisher = ProtocolRestJsonAsyncClient.builder()
+ .endpointOverride(URI.create("http://localhost:" + wireMock.port()))
+ .build();
+
+ noPublisher.allTypes().join();
+ }
+
+ @Test
+ public void apiCall_publisherOverriddenOnRequest_requestPublisherTakesPrecedence() {
+ stubSuccessfulResponse();
+ MetricPublisher requestMetricPublisher = mock(MetricPublisher.class);
+
+ client.allTypes(r -> r.overrideConfiguration(o -> o.metricPublisher(requestMetricPublisher))).join();
+
+ verify(requestMetricPublisher).publish(any(MetricCollection.class));
+ verifyZeroInteractions(mockPublisher);
+ }
+
+ @Test
+ public void apiCall_operationSuccessful_addsMetrics() {
+ stubSuccessfulResponse();
+ client.allTypes().join();
+
+ ArgumentCaptor collectionCaptor = ArgumentCaptor.forClass(MetricCollection.class);
+ verify(mockPublisher).publish(collectionCaptor.capture());
+
+ MetricCollection capturedCollection = collectionCaptor.getValue();
+
+ assertThat(capturedCollection.name()).isEqualTo("ApiCall");
+ assertThat(capturedCollection.metricValues(CoreMetric.SERVICE_ID))
+ .containsExactly(SERVICE_ID);
+ assertThat(capturedCollection.metricValues(CoreMetric.OPERATION_NAME))
+ .containsExactly("AllTypes");
+ }
+
+ @Test
+ public void apiCall_operationFailed_addsMetrics() {
+ stubErrorResponse();
+ assertThatThrownBy(() -> client.allTypes().join()).hasCauseInstanceOf(ProtocolRestJsonException.class);
+
+ ArgumentCaptor collectionCaptor = ArgumentCaptor.forClass(MetricCollection.class);
+ verify(mockPublisher).publish(collectionCaptor.capture());
+
+ MetricCollection capturedCollection = collectionCaptor.getValue();
+
+ assertThat(capturedCollection.name()).isEqualTo("ApiCall");
+ assertThat(capturedCollection.metricValues(CoreMetric.SERVICE_ID))
+ .containsExactly(SERVICE_ID);
+ assertThat(capturedCollection.metricValues(CoreMetric.OPERATION_NAME))
+ .containsExactly("AllTypes");
+ }
+
+ private void stubSuccessfulResponse() {
+ stubFor(post(anyUrl())
+ .willReturn(aResponse().withStatus(200)
+ .withBody("{}")));
+ }
+
+ private void stubErrorResponse() {
+ stubFor(post(anyUrl())
+ .willReturn(aResponse().withStatus(500)
+ .withBody("{}")));
+ }
+}
diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/protocolrestjson/CoreMetricsTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java
similarity index 98%
rename from test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/protocolrestjson/CoreMetricsTest.java
rename to test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java
index 4192ac63aa48..0937b423ade6 100644
--- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/protocolrestjson/CoreMetricsTest.java
+++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java
@@ -13,7 +13,7 @@
* permissions and limitations under the License.
*/
-package software.amazon.awssdk.services.protocolrestjson;
+package software.amazon.awssdk.services.metrics;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
@@ -44,6 +44,7 @@
import software.amazon.awssdk.http.SdkHttpFullResponse;
import software.amazon.awssdk.metrics.MetricCollection;
import software.amazon.awssdk.metrics.MetricPublisher;
+import software.amazon.awssdk.services.protocolrestjson.ProtocolRestJsonClient;
import software.amazon.awssdk.services.protocolrestjson.model.EmptyModeledException;
@RunWith(MockitoJUnitRunner.class)