diff --git a/codegen/pom.xml b/codegen/pom.xml
index e6fe0beb0c07..40713ee7c698 100644
--- a/codegen/pom.xml
+++ b/codegen/pom.xml
@@ -57,6 +57,11 @@
* {@code * software.amazon.awssdk.services.json.paginators.PaginatedOperationWithResultKeyPublisher publisher = client.paginatedOperationWithResultKeyPaginator(request); @@ -565,19 +571,19 @@ public CompletableFuture* * 2) Using a custom subscriber - * + * *paginatedOpera *
* {@code * software.amazon.awssdk.services.json.paginators.PaginatedOperationWithResultKeyPublisher publisher = client.paginatedOperationWithResultKeyPaginator(request); * publisher.subscribe(new Subscriber- * + * * As the response is a publisher, it can work well with third party reactive streams implementations like RxJava2. *() { - * + * * public void onSubscribe(org.reactivestreams.Subscriber subscription) { //... }; - * - * + * + * * public void onNext(software.amazon.awssdk.services.json.model.PaginatedOperationWithResultKeyResponse response) { //... }; * });} *
* Please notice that the configuration of MaxResults won't limit the number of results you get with the
@@ -633,6 +639,7 @@ public PaginatedOperationWithResultKeyPublisher paginatedOperationWithResultKeyP
@Override
public CompletableFuture
* {@code * software.amazon.awssdk.services.json.paginators.PaginatedOperationWithoutResultKeyPublisher publisher = client.paginatedOperationWithoutResultKeyPaginator(request); @@ -687,19 +694,19 @@ public CompletableFuture* * 2) Using a custom subscriber - * + * *paginatedOp *
* {@code * software.amazon.awssdk.services.json.paginators.PaginatedOperationWithoutResultKeyPublisher publisher = client.paginatedOperationWithoutResultKeyPaginator(request); * publisher.subscribe(new Subscriber- * + * * As the response is a publisher, it can work well with third party reactive streams implementations like RxJava2. *() { - * + * * public void onSubscribe(org.reactivestreams.Subscriber subscription) { //... }; - * - * + * + * * public void onNext(software.amazon.awssdk.services.json.model.PaginatedOperationWithoutResultKeyResponse response) { //... }; * });} *
* Please notice that the configuration of MaxResults won't limit the number of results you get with the
@@ -760,6 +767,7 @@ public PaginatedOperationWithoutResultKeyPublisher paginatedOperationWithoutResu
@Override
public CompletableFuture
* {@code * software.amazon.awssdk.services.json.paginators.PaginatedOperationWithResultKeyPublisher publisher = client.paginatedOperationWithResultKeyPaginator(request); @@ -537,19 +545,19 @@ default CompletableFuture* * 2) Using a custom subscriber - * + * *paginatedOper *
* {@code * software.amazon.awssdk.services.json.paginators.PaginatedOperationWithResultKeyPublisher publisher = client.paginatedOperationWithResultKeyPaginator(request); * publisher.subscribe(new Subscriber- * + * * As the response is a publisher, it can work well with third party reactive streams implementations like RxJava2. *() { - * + * * public void onSubscribe(org.reactivestreams.Subscriber subscription) { //... }; - * - * + * + * * public void onNext(software.amazon.awssdk.services.json.model.PaginatedOperationWithResultKeyResponse response) { //... }; * });} *
* Please notice that the configuration of MaxResults won't limit the number of results you get with the @@ -602,7 +610,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); @@ -612,19 +620,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- * + * * As the response is a publisher, it can work well with third party reactive streams implementations like RxJava2. *() { - * + * * public void onSubscribe(org.reactivestreams.Subscriber subscription) { //... }; - * - * + * + * * public void onNext(software.amazon.awssdk.services.json.model.PaginatedOperationWithResultKeyResponse response) { //... }; * });} *
* Please notice that the configuration of MaxResults won't limit the number of results you get with the @@ -679,7 +687,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); @@ -689,19 +697,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- * + * * As the response is a publisher, it can work well with third party reactive streams implementations like RxJava2. *() { - * + * * public void onSubscribe(org.reactivestreams.Subscriber subscription) { //... }; - * - * + * + * * public void onNext(software.amazon.awssdk.services.json.model.PaginatedOperationWithResultKeyResponse response) { //... }; * });} *
* Please notice that the configuration of MaxResults won't limit the number of results you get with the
@@ -738,7 +746,7 @@ default PaginatedOperationWithResultKeyPublisher paginatedOperationWithResultKey
default PaginatedOperationWithResultKeyPublisher paginatedOperationWithResultKeyPaginator(
Consumer
* {@code * software.amazon.awssdk.services.json.paginators.PaginatedOperationWithoutResultKeyPublisher publisher = client.paginatedOperationWithoutResultKeyPaginator(request); @@ -830,19 +839,19 @@ default CompletableFuture* * 2) Using a custom subscriber - * + * *paginatedO *
* {@code * software.amazon.awssdk.services.json.paginators.PaginatedOperationWithoutResultKeyPublisher publisher = client.paginatedOperationWithoutResultKeyPaginator(request); * publisher.subscribe(new Subscriber- * + * * As the response is a publisher, it can work well with third party reactive streams implementations like RxJava2. *() { - * + * * public void onSubscribe(org.reactivestreams.Subscriber subscription) { //... }; - * - * + * + * * public void onNext(software.amazon.awssdk.services.json.model.PaginatedOperationWithoutResultKeyResponse response) { //... }; * });} *
* Please notice that the configuration of MaxResults won't limit the number of results you get with the @@ -897,7 +906,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); @@ -907,19 +916,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- * + * * As the response is a publisher, it can work well with third party reactive streams implementations like RxJava2. *() { - * + * * public void onSubscribe(org.reactivestreams.Subscriber subscription) { //... }; - * - * + * + * * public void onNext(software.amazon.awssdk.services.json.model.PaginatedOperationWithoutResultKeyResponse response) { //... }; * });} *
* Please notice that the configuration of MaxResults won't limit the number of results you get with the
@@ -956,7 +965,7 @@ default PaginatedOperationWithoutResultKeyPublisher paginatedOperationWithoutRes
default PaginatedOperationWithoutResultKeyPublisher paginatedOperationWithoutResultKeyPaginator(
Consumer
* {@code * software.amazon.awssdk.services.json.paginators.PaginatedOperationWithResultKeyIterable responses = client.paginatedOperationWithResultKeyPaginator(request); @@ -268,7 +312,7 @@ public PaginatedOperationWithResultKeyResponse paginatedOperationWithResultKey( ** * 2) Using For loop - * + * *
* { * @code @@ -281,7 +325,7 @@ public PaginatedOperationWithResultKeyResponse paginatedOperationWithResultKey( ** * 3) Use iterator directly - * + * *
* {@code * software.amazon.awssdk.services.json.paginators.PaginatedOperationWithResultKeyIterable responses = client.paginatedOperationWithResultKeyPaginator(request); @@ -313,8 +357,8 @@ public PaginatedOperationWithResultKeyResponse paginatedOperationWithResultKey( */ @Override public PaginatedOperationWithResultKeyIterable paginatedOperationWithResultKeyPaginator( - PaginatedOperationWithResultKeyRequest paginatedOperationWithResultKeyRequest) throws AwsServiceException, - SdkClientException, JsonException { + PaginatedOperationWithResultKeyRequest paginatedOperationWithResultKeyRequest) throws AwsServiceException, + SdkClientException, JsonException { return new PaginatedOperationWithResultKeyIterable(this, applyPaginatorUserAgent(paginatedOperationWithResultKeyRequest)); } @@ -336,23 +380,33 @@ public PaginatedOperationWithResultKeyIterable paginatedOperationWithResultKeyPa */ @Override public PaginatedOperationWithoutResultKeyResponse paginatedOperationWithoutResultKey( - PaginatedOperationWithoutResultKeyRequest paginatedOperationWithoutResultKeyRequest) throws AwsServiceException, - SdkClientException, JsonException { + PaginatedOperationWithoutResultKeyRequest paginatedOperationWithoutResultKeyRequest) throws AwsServiceException, + SdkClientException, JsonException { JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandlerresponseHandler = protocolFactory.createResponseHandler( - operationMetadata, PaginatedOperationWithoutResultKeyResponse::builder); + operationMetadata, PaginatedOperationWithoutResultKeyResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); - - return clientHandler - .execute(new ClientExecutionParams () - .withOperationName("PaginatedOperationWithoutResultKey") - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withInput(paginatedOperationWithoutResultKeyRequest) - .withMarshaller(new PaginatedOperationWithoutResultKeyRequestMarshaller(protocolFactory))); + operationMetadata); + MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.SERVICE_ID, "Json Service"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.OPERATION_NAME, "PaginatedOperationWithoutResultKey"); + try { + + return clientHandler + .execute(new ClientExecutionParams () + .withOperationName("PaginatedOperationWithoutResultKey").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withInput(paginatedOperationWithoutResultKeyRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new PaginatedOperationWithoutResultKeyRequestMarshaller(protocolFactory))); + } finally { + MetricPublisher metricPublisher = clientConfiguration.option(SdkClientOption.METRIC_PUBLISHER); + if (metricPublisher != null) { + metricPublisher.publish(apiCallMetricCollector.collect()); + } + } } /** @@ -374,7 +428,7 @@ public PaginatedOperationWithoutResultKeyResponse paginatedOperationWithoutResul * The following are few ways to iterate through the response pages: * * 1) Using a Stream - * + * * * {@code * software.amazon.awssdk.services.json.paginators.PaginatedOperationWithoutResultKeyIterable responses = client.paginatedOperationWithoutResultKeyPaginator(request); @@ -383,7 +437,7 @@ public PaginatedOperationWithoutResultKeyResponse paginatedOperationWithoutResul ** * 2) Using For loop - * + * ** { * @code @@ -396,7 +450,7 @@ public PaginatedOperationWithoutResultKeyResponse paginatedOperationWithoutResul ** * 3) Use iterator directly - * + * ** {@code * software.amazon.awssdk.services.json.paginators.PaginatedOperationWithoutResultKeyIterable responses = client.paginatedOperationWithoutResultKeyPaginator(request); @@ -428,10 +482,10 @@ public PaginatedOperationWithoutResultKeyResponse paginatedOperationWithoutResul */ @Override public PaginatedOperationWithoutResultKeyIterable paginatedOperationWithoutResultKeyPaginator( - PaginatedOperationWithoutResultKeyRequest paginatedOperationWithoutResultKeyRequest) throws AwsServiceException, - SdkClientException, JsonException { + PaginatedOperationWithoutResultKeyRequest paginatedOperationWithoutResultKeyRequest) throws AwsServiceException, + SdkClientException, JsonException { return new PaginatedOperationWithoutResultKeyIterable(this, - applyPaginatorUserAgent(paginatedOperationWithoutResultKeyRequest)); + applyPaginatorUserAgent(paginatedOperationWithoutResultKeyRequest)); } /** @@ -442,11 +496,11 @@ public PaginatedOperationWithoutResultKeyIterable paginatedOperationWithoutResul * 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. @@ -463,26 +517,38 @@ public PaginatedOperationWithoutResultKeyIterable paginatedOperationWithoutResul */ @Override public StreamingInputOperationResponse streamingInputOperation(StreamingInputOperationRequest streamingInputOperationRequest, - RequestBody requestBody) throws AwsServiceException, SdkClientException, JsonException { + RequestBody requestBody) throws AwsServiceException, SdkClientException, JsonException { JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) - .isPayloadJson(true).build(); + .isPayloadJson(true).build(); HttpResponseHandlerresponseHandler = protocolFactory.createResponseHandler( - operationMetadata, StreamingInputOperationResponse::builder); + operationMetadata, StreamingInputOperationResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); - - return clientHandler.execute(new ClientExecutionParams () - .withOperationName("StreamingInputOperation") - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withInput(streamingInputOperationRequest) - .withRequestBody(requestBody) - .withMarshaller( - StreamingRequestMarshaller.builder() - .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) - .requestBody(requestBody).build())); + operationMetadata); + MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.SERVICE_ID, "Json Service"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.OPERATION_NAME, "StreamingInputOperation"); + try { + + 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())); + } finally { + MetricPublisher metricPublisher = clientConfiguration.option(SdkClientOption.METRIC_PUBLISHER); + if (metricPublisher != null) { + metricPublisher.publish(apiCallMetricCollector.collect()); + } + } } /** @@ -493,20 +559,20 @@ public StreamingInputOperationResponse streamingInputOperation(StreamingInputOpe * 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' * @param responseTransformer * Functional interface for processing the streamed response content. The unmarshalled - * StreamingInputOutputOperationResponse and an InputStream to the response content are provided as parameters - * to the callback. The callback may return a transformed type which will be the return value of this method. - * See {@link software.amazon.awssdk.core.sync.ResponseTransformer} for details on implementing this - * interface and for links to pre-canned implementations for common scenarios like downloading to a file. The - * service documentation for the response content is as follows 'This be a stream'. + * StreamingInputOutputOperationResponse and an InputStream to the response content are provided as + * parameters to the callback. The callback may return a transformed type which will be the return value of + * this method. See {@link software.amazon.awssdk.core.sync.ResponseTransformer} for details on implementing + * this interface and for links to pre-canned implementations for common scenarios like downloading to a + * file. The service documentation for the response content is as follows 'This be a stream'. * @return The transformed result of the ResponseTransformer. * @throws SdkException * Base class for all exceptions that can be thrown by the SDK (both service and client). Can be used for @@ -521,31 +587,44 @@ public StreamingInputOperationResponse streamingInputOperation(StreamingInputOpe */ @Override publicReturnT streamingInputOutputOperation( - StreamingInputOutputOperationRequest streamingInputOutputOperationRequest, RequestBody requestBody, - ResponseTransformer responseTransformer) throws AwsServiceException, - SdkClientException, JsonException { + StreamingInputOutputOperationRequest streamingInputOutputOperationRequest, RequestBody requestBody, + ResponseTransformer responseTransformer) throws AwsServiceException, + SdkClientException, JsonException { streamingInputOutputOperationRequest = applySignerOverride(streamingInputOutputOperationRequest, - Aws4UnsignedPayloadSigner.create()); + Aws4UnsignedPayloadSigner.create()); JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(true) - .isPayloadJson(false).build(); + .isPayloadJson(false).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - operationMetadata, StreamingInputOutputOperationResponse::builder); + operationMetadata, StreamingInputOutputOperationResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); - - return clientHandler.execute( - new ClientExecutionParams () - .withOperationName("StreamingInputOutputOperation") - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withInput(streamingInputOutputOperationRequest) - .withRequestBody(requestBody) - .withMarshaller( - StreamingRequestMarshaller.builder() - .delegateMarshaller(new StreamingInputOutputOperationRequestMarshaller(protocolFactory)) - .requestBody(requestBody).transferEncoding(true).build()), responseTransformer); + operationMetadata); + MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.SERVICE_ID, "Json Service"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.OPERATION_NAME, "StreamingInputOutputOperation"); + try { + + return clientHandler.execute( + new ClientExecutionParams () + .withOperationName("StreamingInputOutputOperation") + .withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler) + .withInput(streamingInputOutputOperationRequest) + .withMetricCollector(apiCallMetricCollector) + .withRequestBody(requestBody) + .withMarshaller( + StreamingRequestMarshaller + .builder() + .delegateMarshaller( + new StreamingInputOutputOperationRequestMarshaller(protocolFactory)) + .requestBody(requestBody).transferEncoding(true).build()), responseTransformer); + } finally { + MetricPublisher metricPublisher = clientConfiguration.option(SdkClientOption.METRIC_PUBLISHER); + if (metricPublisher != null) { + metricPublisher.publish(apiCallMetricCollector.collect()); + } + } } /** @@ -554,8 +633,8 @@ public ReturnT streamingInputOutputOperation( * @param streamingOutputOperationRequest * @param responseTransformer * Functional interface for processing the streamed response content. The unmarshalled - * StreamingOutputOperationResponse and an InputStream to the response content are provided as parameters - * to the callback. The callback may return a transformed type which will be the return value of this method. + * StreamingOutputOperationResponse and an InputStream to the response content are provided as parameters to + * the callback. The callback may return a transformed type which will be the return value of this method. * See {@link software.amazon.awssdk.core.sync.ResponseTransformer} for details on implementing this * interface and for links to pre-canned implementations for common scenarios like downloading to a file. The * service documentation for the response content is as follows 'This be a stream'. @@ -573,39 +652,49 @@ public ReturnT streamingInputOutputOperation( */ @Override public ReturnT streamingOutputOperation(StreamingOutputOperationRequest streamingOutputOperationRequest, - ResponseTransformer responseTransformer) throws AwsServiceException, - SdkClientException, JsonException { + ResponseTransformer responseTransformer) throws AwsServiceException, + SdkClientException, JsonException { JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(true) - .isPayloadJson(false).build(); + .isPayloadJson(false).build(); HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( - operationMetadata, StreamingOutputOperationResponse::builder); + operationMetadata, StreamingOutputOperationResponse::builder); HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, - operationMetadata); - - return clientHandler.execute( - new ClientExecutionParams () - .withOperationName("StreamingOutputOperation") - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .withInput(streamingOutputOperationRequest) - .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)), responseTransformer); + operationMetadata); + MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.SERVICE_ID, "Json Service"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.OPERATION_NAME, "StreamingOutputOperation"); + try { + + return clientHandler.execute( + new ClientExecutionParams () + .withOperationName("StreamingOutputOperation").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withInput(streamingOutputOperationRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)), responseTransformer); + } finally { + MetricPublisher metricPublisher = clientConfiguration.option(SdkClientOption.METRIC_PUBLISHER); + if (metricPublisher != null) { + metricPublisher.publish(apiCallMetricCollector.collect()); + } + } } private HttpResponseHandler createErrorResponseHandler(BaseAwsJsonProtocolFactory protocolFactory, - JsonOperationMetadata operationMetadata) { + JsonOperationMetadata operationMetadata) { return protocolFactory.createErrorResponseHandler(operationMetadata); } private > T init(T builder) { return builder - .clientConfiguration(clientConfiguration) - .defaultServiceExceptionSupplier(JsonException::builder) - .protocol(AwsJsonProtocol.REST_JSON) - .protocolVersion("1.1") - .registerModeledException( - ExceptionMetadata.builder().errorCode("InvalidInput") - .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()); + .clientConfiguration(clientConfiguration) + .defaultServiceExceptionSupplier(JsonException::builder) + .protocol(AwsJsonProtocol.REST_JSON) + .protocolVersion("1.1") + .registerModeledException( + ExceptionMetadata.builder().errorCode("InvalidInput") + .exceptionBuilderSupplier(InvalidInputException::builder).httpStatusCode(400).build()); } @Override @@ -615,10 +704,10 @@ public void close() { private T applyPaginatorUserAgent(T request) { Consumer userAgentApplier = b -> b.addApiName(ApiName.builder() - .version(VersionInfo.SDK_VERSION).name("PAGINATED").build()); + .version(VersionInfo.SDK_VERSION).name("PAGINATED").build()); AwsRequestOverrideConfiguration overrideConfiguration = request.overrideConfiguration() - .map(c -> c.toBuilder().applyMutation(userAgentApplier).build()) - .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(userAgentApplier).build())); + .map(c -> c.toBuilder().applyMutation(userAgentApplier).build()) + .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(userAgentApplier).build())); return (T) request.toBuilder().overrideConfiguration(overrideConfiguration).build(); } @@ -628,8 +717,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 e6ddff92b7f4..e96ac5147355 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 @@ -16,6 +16,7 @@ import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.http.HttpResponseHandler; import software.amazon.awssdk.core.runtime.transform.AsyncStreamingRequestMarshaller; +import software.amazon.awssdk.metrics.MetricCollector; import software.amazon.awssdk.protocols.core.ExceptionMetadata; import software.amazon.awssdk.protocols.query.AwsQueryProtocolFactory; import software.amazon.awssdk.services.query.model.APostOperationRequest; @@ -86,21 +87,22 @@ public final String serviceName() { */ @Override public CompletableFuture aPostOperation(APostOperationRequest aPostOperationRequest) { + MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall"); try { String hostPrefix = "foo-"; String resolvedHostExpression = "foo-"; HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(APostOperationResponse::builder); + .createResponseHandler(APostOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); CompletableFuture executeFuture = clientHandler - .execute(new ClientExecutionParams () - .withOperationName("APostOperation") - .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) - .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) - .hostPrefixExpression(resolvedHostExpression).withInput(aPostOperationRequest)); + .execute(new ClientExecutionParams () + .withOperationName("APostOperation") + .withMarshaller(new APostOperationRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .hostPrefixExpression(resolvedHostExpression).withInput(aPostOperationRequest)); return executeFuture; } catch (Throwable t) { return CompletableFutureUtils.failedFuture(t); @@ -132,20 +134,21 @@ public CompletableFuture aPostOperation(APostOperationRe */ @Override public CompletableFuture aPostOperationWithOutput( - APostOperationWithOutputRequest aPostOperationWithOutputRequest) { + APostOperationWithOutputRequest aPostOperationWithOutputRequest) { + MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall"); try { 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) - .withInput(aPostOperationWithOutputRequest)); + .execute(new ClientExecutionParams () + .withOperationName("APostOperationWithOutput") + .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withInput(aPostOperationWithOutputRequest)); return executeFuture; } catch (Throwable t) { return CompletableFutureUtils.failedFuture(t); @@ -178,23 +181,24 @@ public CompletableFuture aPostOperationWithOut */ @Override public CompletableFuture streamingInputOperation( - StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) { + StreamingInputOperationRequest streamingInputOperationRequest, AsyncRequestBody requestBody) { + MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall"); try { 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).withAsyncRequestBody(requestBody) - .withInput(streamingInputOperationRequest)); + .execute(new ClientExecutionParams () + .withOperationName("StreamingInputOperation") + .withMarshaller( + AsyncStreamingRequestMarshaller.builder() + .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) + .asyncRequestBody(requestBody).build()).withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withAsyncRequestBody(requestBody) + .withInput(streamingInputOperationRequest)); return executeFuture; } catch (Throwable t) { return CompletableFutureUtils.failedFuture(t); @@ -227,31 +231,32 @@ public CompletableFuture streamingInputOperatio */ @Override public CompletableFuture streamingOutputOperation( - StreamingOutputOperationRequest streamingOutputOperationRequest, - AsyncResponseTransformer asyncResponseTransformer) { + StreamingOutputOperationRequest streamingOutputOperationRequest, + AsyncResponseTransformer asyncResponseTransformer) { + MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall"); try { 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) - .withInput(streamingOutputOperationRequest), asyncResponseTransformer); + new ClientExecutionParams () + .withOperationName("StreamingOutputOperation") + .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withInput(streamingOutputOperationRequest), asyncResponseTransformer); executeFuture.whenComplete((r, e) -> { if (e != null) { runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> asyncResponseTransformer.exceptionOccurred(e)); + () -> asyncResponseTransformer.exceptionOccurred(e)); } }); return executeFuture; } catch (Throwable t) { runAndLogError(log, "Exception thrown in exceptionOccurred callback, ignoring", - () -> asyncResponseTransformer.exceptionOccurred(t)); + () -> asyncResponseTransformer.exceptionOccurred(t)); return CompletableFutureUtils.failedFuture(t); } } @@ -263,10 +268,10 @@ public void close() { 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(); } } 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 c99dfe5cf930..c4c82282dd3c 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 @@ -4,7 +4,9 @@ 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.awscore.metrics.AwsCoreMetric; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; +import software.amazon.awssdk.core.client.config.SdkClientOption; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.client.handler.SyncClientHandler; import software.amazon.awssdk.core.exception.SdkClientException; @@ -12,6 +14,8 @@ import software.amazon.awssdk.core.runtime.transform.StreamingRequestMarshaller; import software.amazon.awssdk.core.sync.RequestBody; import software.amazon.awssdk.core.sync.ResponseTransformer; +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; @@ -76,19 +80,30 @@ public final String serviceName() { */ @Override public APostOperationResponse aPostOperation(APostOperationRequest aPostOperationRequest) throws InvalidInputException, - AwsServiceException, SdkClientException, QueryException { + AwsServiceException, SdkClientException, QueryException { String hostPrefix = "foo-"; String resolvedHostExpression = "foo-"; HttpResponseHandler responseHandler = protocolFactory - .createResponseHandler(APostOperationResponse::builder); + .createResponseHandler(APostOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.SERVICE_ID, "Query Service"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.OPERATION_NAME, "APostOperation"); + try { - return clientHandler.execute(new ClientExecutionParams () - .withOperationName("APostOperation").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).hostPrefixExpression(resolvedHostExpression) - .withInput(aPostOperationRequest).withMarshaller(new APostOperationRequestMarshaller(protocolFactory))); + return clientHandler.execute(new ClientExecutionParams () + .withOperationName("APostOperation").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).hostPrefixExpression(resolvedHostExpression) + .withInput(aPostOperationRequest).withMetricCollector(apiCallMetricCollector) + .withMarshaller(new APostOperationRequestMarshaller(protocolFactory))); + } finally { + MetricPublisher metricPublisher = clientConfiguration.option(SdkClientOption.METRIC_PUBLISHER); + if (metricPublisher != null) { + metricPublisher.publish(apiCallMetricCollector.collect()); + } + } } /** @@ -113,19 +128,30 @@ 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(); + MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.SERVICE_ID, "Query Service"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.OPERATION_NAME, "APostOperationWithOutput"); + try { - return clientHandler - .execute(new ClientExecutionParams () - .withOperationName("APostOperationWithOutput").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(aPostOperationWithOutputRequest) - .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory))); + return clientHandler + .execute(new ClientExecutionParams () + .withOperationName("APostOperationWithOutput").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withInput(aPostOperationWithOutputRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new APostOperationWithOutputRequestMarshaller(protocolFactory))); + } finally { + MetricPublisher metricPublisher = clientConfiguration.option(SdkClientOption.METRIC_PUBLISHER); + if (metricPublisher != null) { + metricPublisher.publish(apiCallMetricCollector.collect()); + } + } } /** @@ -136,11 +162,11 @@ public APostOperationWithOutputResponse aPostOperationWithOutput( * 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. @@ -157,23 +183,35 @@ public APostOperationWithOutputResponse aPostOperationWithOutput( */ @Override public StreamingInputOperationResponse streamingInputOperation(StreamingInputOperationRequest streamingInputOperationRequest, - RequestBody requestBody) throws AwsServiceException, SdkClientException, QueryException { + RequestBody requestBody) throws AwsServiceException, SdkClientException, QueryException { HttpResponseHandlerresponseHandler = protocolFactory - .createResponseHandler(StreamingInputOperationResponse::builder); + .createResponseHandler(StreamingInputOperationResponse::builder); HttpResponseHandler errorResponseHandler = protocolFactory.createErrorResponseHandler(); + MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.SERVICE_ID, "Query Service"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.OPERATION_NAME, "StreamingInputOperation"); + try { - return clientHandler.execute(new ClientExecutionParams () - .withOperationName("StreamingInputOperation") - .withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler) - .withInput(streamingInputOperationRequest) - .withRequestBody(requestBody) - .withMarshaller( - StreamingRequestMarshaller.builder() - .delegateMarshaller(new StreamingInputOperationRequestMarshaller(protocolFactory)) - .requestBody(requestBody).build())); + 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())); + } finally { + MetricPublisher metricPublisher = clientConfiguration.option(SdkClientOption.METRIC_PUBLISHER); + if (metricPublisher != null) { + metricPublisher.publish(apiCallMetricCollector.collect()); + } + } } /** @@ -201,28 +239,39 @@ 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(); + MetricCollector apiCallMetricCollector = MetricCollector.create("ApiCall"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.SERVICE_ID, "Query Service"); + apiCallMetricCollector.reportMetric(AwsCoreMetric.OPERATION_NAME, "StreamingOutputOperation"); + try { - return clientHandler.execute( - new ClientExecutionParams () - .withOperationName("StreamingOutputOperation").withResponseHandler(responseHandler) - .withErrorResponseHandler(errorResponseHandler).withInput(streamingOutputOperationRequest) - .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)), responseTransformer); + return clientHandler.execute( + new ClientExecutionParams () + .withOperationName("StreamingOutputOperation").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withInput(streamingOutputOperationRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new StreamingOutputOperationRequestMarshaller(protocolFactory)), responseTransformer); + } finally { + MetricPublisher metricPublisher = clientConfiguration.option(SdkClientOption.METRIC_PUBLISHER); + if (metricPublisher != null) { + metricPublisher.publish(apiCallMetricCollector.collect()); + } + } } 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/core/aws-core/pom.xml b/core/aws-core/pom.xml index 45a68fe355c5..0f289fa045ad 100644 --- a/core/aws-core/pom.xml +++ b/core/aws-core/pom.xml @@ -63,6 +63,11 @@ http-client-spi ${awsjavasdk.version} ++ software.amazon.awssdk +metrics-spi +${awsjavasdk.version} ++ software.amazon.awssdk utils diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/metrics/AwsCoreMetric.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/metrics/AwsCoreMetric.java new file mode 100644 index 000000000000..5e387fdead5b --- /dev/null +++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/metrics/AwsCoreMetric.java @@ -0,0 +1,45 @@ +/* + * 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.awscore.metrics; + +import software.amazon.awssdk.annotations.SdkPublicApi; +import software.amazon.awssdk.metrics.MetricCategory; +import software.amazon.awssdk.metrics.SdkMetric; + +/** + * The set of metrics collected for all SDK clients. + */ +@SdkPublicApi +public final class AwsCoreMetric { + + /** + * The unique ID for the service. This is present for all API call metrics. + */ + public static final SdkMetricSERVICE_ID = metric("ServiceName", String.class); + + /** + * The name of the service operation being invoked. This is present for all + * API call metrics. + */ + public static final SdkMetric OPERATION_NAME = metric("OperationName", String.class); + + private AwsCoreMetric() { + } + + private static SdkMetric metric(String name, Class clzz) { + return SdkMetric.create(name, clzz, MetricCategory.DEFAULT); + } +} diff --git a/core/sdk-core/pom.xml b/core/sdk-core/pom.xml index ac66e61d21d3..81334cd13e05 100644 --- a/core/sdk-core/pom.xml +++ b/core/sdk-core/pom.xml @@ -41,6 +41,11 @@ http-client-spi ${awsjavasdk.version} + software.amazon.awssdk +metrics-spi +${awsjavasdk.version} ++ software.amazon.awssdk utils 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 1be24c8bac0c..c4194399f976 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 @@ -28,6 +28,7 @@ import static software.amazon.awssdk.core.client.config.SdkClientOption.ASYNC_HTTP_CLIENT; import static software.amazon.awssdk.core.client.config.SdkClientOption.CRC32_FROM_COMPRESSED_DATA_ENABLED; import static software.amazon.awssdk.core.client.config.SdkClientOption.EXECUTION_INTERCEPTORS; +import static software.amazon.awssdk.core.client.config.SdkClientOption.METRIC_PUBLISHER; import static software.amazon.awssdk.core.client.config.SdkClientOption.PROFILE_FILE; import static software.amazon.awssdk.core.client.config.SdkClientOption.PROFILE_NAME; import static software.amazon.awssdk.core.client.config.SdkClientOption.RETRY_POLICY; @@ -66,6 +67,7 @@ import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.async.AsyncExecuteRequest; import software.amazon.awssdk.http.async.SdkAsyncHttpClient; +import software.amazon.awssdk.metrics.MetricPublisher; import software.amazon.awssdk.profiles.ProfileFile; import software.amazon.awssdk.profiles.ProfileFileSystemSetting; import software.amazon.awssdk.utils.AttributeMap; @@ -391,6 +393,11 @@ public final B httpClientBuilder(SdkAsyncHttpClient.Builder httpClientBuilder) { return thisBuilder(); } + public final B metricPublisher(MetricPublisher metricPublisher) { + clientConfiguration.option(METRIC_PUBLISHER, metricPublisher); + return thisBuilder(); + } + /** * Return "this" for method chaining. */ diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/config/SdkClientOption.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/config/SdkClientOption.java index 11c26163287d..98669b52dc2c 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/config/SdkClientOption.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/config/SdkClientOption.java @@ -27,6 +27,7 @@ import software.amazon.awssdk.core.retry.RetryPolicy; import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.async.SdkAsyncHttpClient; +import software.amazon.awssdk.metrics.MetricPublisher; import software.amazon.awssdk.profiles.ProfileFile; /** @@ -129,6 +130,8 @@ public final class SdkClientOptionextends ClientOption { */ public static final SdkClientOption PROFILE_NAME = new SdkClientOption<>(String.class); + public static final SdkClientOption METRIC_PUBLISHER = new SdkClientOption<>(MetricPublisher.class); + private SdkClientOption(Class valueClass) { super(valueClass); } 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 3d4b03dda61f..1b5320886fd2 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 @@ -25,6 +25,7 @@ import software.amazon.awssdk.core.http.HttpResponseHandler; import software.amazon.awssdk.core.runtime.transform.Marshaller; import software.amazon.awssdk.core.sync.RequestBody; +import software.amazon.awssdk.metrics.MetricCollector; /** * Encapsulates parameters needed for a particular API call. Captures input and output pojo types. @@ -47,6 +48,7 @@ public final class ClientExecutionParams { private String hostPrefixExpression; private String operationName; private URI discoveredEndpoint; + private MetricCollector metricCollector; public Marshaller getMarshaller() { return marshaller; @@ -166,4 +168,13 @@ public ClientExecutionParams discoveredEndpoint(URI discoveredE this.discoveredEndpoint = discoveredEndpoint; return this; } + + public ClientExecutionParams withMetricCollector(MetricCollector metricCollector) { + this.metricCollector = metricCollector; + return this; + } + + public MetricCollector getMetricCollector() { + return metricCollector; + } } diff --git a/services/pom.xml b/services/pom.xml index d3d5d1432b8c..c8d8b5e9e2d0 100644 --- a/services/pom.xml +++ b/services/pom.xml @@ -292,6 +292,11 @@ software.amazon.awssdk ${awsjavasdk.version} + software.amazon.awssdk +metrics-spi +${awsjavasdk.version} ++ apache-client software.amazon.awssdk diff --git a/test/codegen-generated-classes-test/pom.xml b/test/codegen-generated-classes-test/pom.xml index 279a70810e29..9a8aa2e595a8 100644 --- a/test/codegen-generated-classes-test/pom.xml +++ b/test/codegen-generated-classes-test/pom.xml @@ -75,6 +75,11 @@http-client-spi ${awsjavasdk.version} + software.amazon.awssdk +metrics-spi +${awsjavasdk.version} ++ software.amazon.awssdk sdk-core diff --git a/test/protocol-tests/pom.xml b/test/protocol-tests/pom.xml index ec28701980e1..6d58efef7945 100644 --- a/test/protocol-tests/pom.xml +++ b/test/protocol-tests/pom.xml @@ -83,6 +83,11 @@http-client-spi ${awsjavasdk.version} + software.amazon.awssdk +metrics-spi +${awsjavasdk.version} +software.amazon.awssdk sdk-core