From cdeec3aba59a38495d9b79a9497dec9f64a08b52 Mon Sep 17 00:00:00 2001 From: David Negrete Date: Fri, 17 Feb 2023 16:23:09 -0700 Subject: [PATCH 1/8] Implement SERVICE_ENDPOINT core metric --- .changes/next-release/bugfix-AWSSDKforJavav2-0a552ee.json | 6 ++++++ .../stages/AsyncApiCallAttemptMetricCollectionStage.java | 3 +++ .../amazon/awssdk/core/internal/util/MetricUtils.java | 7 +++++++ .../software/amazon/awssdk/core/metrics/CoreMetric.java | 7 +++++++ .../amazon/awssdk/services/metrics/CoreMetricsTest.java | 2 ++ .../services/metrics/async/BaseAsyncCoreMetricsTest.java | 2 ++ 6 files changed, 27 insertions(+) create mode 100644 .changes/next-release/bugfix-AWSSDKforJavav2-0a552ee.json diff --git a/.changes/next-release/bugfix-AWSSDKforJavav2-0a552ee.json b/.changes/next-release/bugfix-AWSSDKforJavav2-0a552ee.json new file mode 100644 index 000000000000..7ff6d8584379 --- /dev/null +++ b/.changes/next-release/bugfix-AWSSDKforJavav2-0a552ee.json @@ -0,0 +1,6 @@ +{ + "category": "AWS SDK for Java v2", + "contributor": "", + "type": "bugfix", + "description": "Implement SERVICE_ENDPOINT core metric" +} diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncApiCallAttemptMetricCollectionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncApiCallAttemptMetricCollectionStage.java index d4777674452c..b9b2636d2c21 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncApiCallAttemptMetricCollectionStage.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncApiCallAttemptMetricCollectionStage.java @@ -16,6 +16,7 @@ package software.amazon.awssdk.core.internal.http.pipeline.stages; import static software.amazon.awssdk.core.internal.util.MetricUtils.collectHttpMetrics; +import static software.amazon.awssdk.core.internal.util.MetricUtils.collectHttpRequestMetrics; import static software.amazon.awssdk.core.internal.util.MetricUtils.createAttemptMetricsCollector; import java.time.Duration; @@ -53,6 +54,8 @@ public CompletableFuture> execute(SdkHttpFullRequest input, context.attemptMetricCollector(apiCallAttemptMetrics); reportBackoffDelay(context); + collectHttpRequestMetrics(apiCallAttemptMetrics, input); + CompletableFuture> executeFuture = wrapped.execute(input, context); CompletableFuture> metricsCollectedFuture = executeFuture.whenComplete((r, t) -> { if (t == null) { 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 8805653dd636..0c0d33d67369 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 @@ -25,6 +25,7 @@ import software.amazon.awssdk.core.internal.http.RequestExecutionContext; import software.amazon.awssdk.core.metrics.CoreMetric; import software.amazon.awssdk.http.HttpMetric; +import software.amazon.awssdk.http.SdkHttpFullRequest; import software.amazon.awssdk.http.SdkHttpFullResponse; import software.amazon.awssdk.metrics.MetricCollector; import software.amazon.awssdk.metrics.NoOpMetricCollector; @@ -65,6 +66,12 @@ public static Pair measureDurationUnsafe(Callable c) throws return Pair.of(result, d); } + public static void collectHttpRequestMetrics(MetricCollector metricCollector, SdkHttpFullRequest httpRequest) { + if (metricCollector != null && !(metricCollector instanceof NoOpMetricCollector) && httpRequest != null) { + metricCollector.reportMetric(CoreMetric.SERVICE_ENDPOINT, httpRequest.getUri()); + } + } + public static void collectHttpMetrics(MetricCollector metricCollector, SdkHttpFullResponse httpResponse) { if (metricCollector != null && !(metricCollector instanceof NoOpMetricCollector) && httpResponse != null) { metricCollector.reportMetric(HttpMetric.HTTP_STATUS_CODE, httpResponse.statusCode()); 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 f4529d32c1a0..df71deacc274 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 @@ -15,6 +15,7 @@ package software.amazon.awssdk.core.metrics; +import java.net.URI; import java.time.Duration; import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.core.retry.RetryPolicy; @@ -50,6 +51,12 @@ public final class CoreMetric { public static final SdkMetric RETRY_COUNT = metric("RetryCount", Integer.class, MetricLevel.ERROR); + /** + * The endpoint for the service. + */ + public static final SdkMetric SERVICE_ENDPOINT = + metric("ServiceEndpoint", URI.class, MetricLevel.ERROR); + /** * The duration of the API call. This includes all call attempts made. * diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java index c2b701217cf1..a75bbe9ffb1c 100644 --- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java +++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java @@ -183,6 +183,8 @@ public void testApiCall_operationSuccessful_addsMetrics() { assertThat(capturedCollection.metricValues(CoreMetric.MARSHALLING_DURATION).get(0)) .isGreaterThanOrEqualTo(Duration.ZERO); assertThat(capturedCollection.metricValues(CoreMetric.RETRY_COUNT)).containsExactly(0); + assertThat(capturedCollection.metricValues(CoreMetric.SERVICE_ENDPOINT).get(0)).isEqualTo(URI.create( + "https://customresponsemetadata.us-west-2.amazonaws.com")); assertThat(capturedCollection.children()).hasSize(1); MetricCollection attemptCollection = capturedCollection.children().get(0); diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/BaseAsyncCoreMetricsTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/BaseAsyncCoreMetricsTest.java index 4ed2df722d6b..0bfc93a83146 100644 --- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/BaseAsyncCoreMetricsTest.java +++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/BaseAsyncCoreMetricsTest.java @@ -203,6 +203,8 @@ private void verifyApiCallCollection(MetricCollection capturedCollection) { .isGreaterThanOrEqualTo(Duration.ZERO); assertThat(capturedCollection.metricValues(CoreMetric.API_CALL_DURATION).get(0)) .isGreaterThan(FIXED_DELAY); + assertThat(capturedCollection.metricValues(CoreMetric.SERVICE_ENDPOINT).get(0)) + .isEqualTo(URI.create("http://localhost")); } void stubSuccessfulResponse() { From 439e9654dd827e7952579bfdb6d2dfd6ed4786dd Mon Sep 17 00:00:00 2001 From: David Negrete Date: Thu, 9 Mar 2023 17:02:15 -0700 Subject: [PATCH 2/8] Create CollectionStages for SERVICE_ENDPOINT --- .../internal/http/AmazonAsyncHttpClient.java | 4 +- .../internal/http/AmazonSyncHttpClient.java | 5 ++ ...ncApiCallAttemptMetricCollectionStage.java | 3 - ...cServiceEndpointMetricCollectionStage.java | 59 +++++++++++++++++++ ...eEndpointAttemptMetricCollectionStage.java | 53 +++++++++++++++++ .../ServiceEndpointMetricCollectionStage.java | 45 ++++++++++++++ .../core/internal/util/MetricUtils.java | 2 +- .../services/metrics/CoreMetricsTest.java | 1 + .../async/BaseAsyncCoreMetricsTest.java | 4 +- 9 files changed, 169 insertions(+), 7 deletions(-) create mode 100644 core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncServiceEndpointMetricCollectionStage.java create mode 100644 core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointAttemptMetricCollectionStage.java create mode 100644 core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointMetricCollectionStage.java diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonAsyncHttpClient.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonAsyncHttpClient.java index 766b998fa710..fcf80d14fbfa 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonAsyncHttpClient.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonAsyncHttpClient.java @@ -37,6 +37,7 @@ import software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncBeforeTransmissionExecutionInterceptorsStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncExecutionFailureExceptionReportingStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncRetryableStage; +import software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncServiceEndpointMetricCollectionStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncSigningStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.HttpChecksumStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.MakeAsyncHttpRequestStage; @@ -183,7 +184,8 @@ public CompletableFuture execute( .then(async(() -> new AfterExecutionInterceptorsStage<>())) .wrappedWith(AsyncExecutionFailureExceptionReportingStage::new) .wrappedWith(AsyncApiCallTimeoutTrackingStage::new) - .wrappedWith(AsyncApiCallMetricCollectionStage::new)::build)::build) + .wrappedWith(AsyncApiCallMetricCollectionStage::new) + .wrappedWith(AsyncServiceEndpointMetricCollectionStage::new)::build)::build) .build(httpClientDependencies) .execute(request, createRequestExecutionDependencies()); } catch (RuntimeException e) { diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonSyncHttpClient.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonSyncHttpClient.java index 75cab29c6f51..136e2f5dfd41 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonSyncHttpClient.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonSyncHttpClient.java @@ -45,6 +45,8 @@ import software.amazon.awssdk.core.internal.http.pipeline.stages.MergeCustomHeadersStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.MergeCustomQueryParamsStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage; +import software.amazon.awssdk.core.internal.http.pipeline.stages.ServiceEndpointAttemptMetricCollectionStage; +import software.amazon.awssdk.core.internal.http.pipeline.stages.ServiceEndpointMetricCollectionStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.SigningStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.TimeoutExceptionHandlingStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.UnwrapResponseContainer; @@ -185,10 +187,13 @@ public OutputT execute(HttpResponseHandler> response .wrappedWith(ApiCallAttemptTimeoutTrackingStage::new) .wrappedWith(TimeoutExceptionHandlingStage::new) .wrappedWith((deps, wrapped) -> new ApiCallAttemptMetricCollectionStage<>(wrapped)) + .wrappedWith((deps, wrapped) -> + new ServiceEndpointAttemptMetricCollectionStage<>(wrapped)) .wrappedWith(RetryableStage::new)::build) .wrappedWith(StreamManagingStage::new) .wrappedWith(ApiCallTimeoutTrackingStage::new)::build) .wrappedWith((deps, wrapped) -> new ApiCallMetricCollectionStage<>(wrapped)) + .wrappedWith((deps, wrapped) -> new ServiceEndpointMetricCollectionStage<>(wrapped)) .then(() -> new UnwrapResponseContainer<>()) .then(() -> new AfterExecutionInterceptorsStage<>()) .wrappedWith(ExecutionFailureExceptionReportingStage::new) diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncApiCallAttemptMetricCollectionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncApiCallAttemptMetricCollectionStage.java index b9b2636d2c21..d4777674452c 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncApiCallAttemptMetricCollectionStage.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncApiCallAttemptMetricCollectionStage.java @@ -16,7 +16,6 @@ package software.amazon.awssdk.core.internal.http.pipeline.stages; import static software.amazon.awssdk.core.internal.util.MetricUtils.collectHttpMetrics; -import static software.amazon.awssdk.core.internal.util.MetricUtils.collectHttpRequestMetrics; import static software.amazon.awssdk.core.internal.util.MetricUtils.createAttemptMetricsCollector; import java.time.Duration; @@ -54,8 +53,6 @@ public CompletableFuture> execute(SdkHttpFullRequest input, context.attemptMetricCollector(apiCallAttemptMetrics); reportBackoffDelay(context); - collectHttpRequestMetrics(apiCallAttemptMetrics, input); - CompletableFuture> executeFuture = wrapped.execute(input, context); CompletableFuture> metricsCollectedFuture = executeFuture.whenComplete((r, t) -> { if (t == null) { diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncServiceEndpointMetricCollectionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncServiceEndpointMetricCollectionStage.java new file mode 100644 index 000000000000..168186cb86db --- /dev/null +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncServiceEndpointMetricCollectionStage.java @@ -0,0 +1,59 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.awssdk.core.internal.http.pipeline.stages; + +import java.util.concurrent.CompletableFuture; +import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.core.internal.http.RequestExecutionContext; +import software.amazon.awssdk.core.internal.http.pipeline.RequestPipeline; +import software.amazon.awssdk.core.metrics.CoreMetric; +import software.amazon.awssdk.http.SdkHttpFullRequest; +import software.amazon.awssdk.metrics.MetricCollector; +import software.amazon.awssdk.utils.CompletableFutureUtils; + +/** + * Wrapper pipeline that tracks the {@link CoreMetric#SERVICE_ENDPOINT} metric. + */ +@SdkInternalApi +public final class AsyncServiceEndpointMetricCollectionStage implements RequestPipeline> { + private final RequestPipeline> wrapped; + + public AsyncServiceEndpointMetricCollectionStage(RequestPipeline> wrapped) { + this.wrapped = wrapped; + } + + @Override + public CompletableFuture execute(SdkHttpFullRequest input, RequestExecutionContext context) throws Exception { + MetricCollector metricCollector = context.executionContext().metricCollector(); + + CompletableFuture future = new CompletableFuture<>(); + + CompletableFuture executeFuture = wrapped.execute(input, context); + + executeFuture.whenComplete((r, t) -> { + metricCollector.reportMetric(CoreMetric.SERVICE_ENDPOINT, input.getUri()); + + if (t != null) { + future.completeExceptionally(t); + } else { + future.complete(r); + } + }); + + return CompletableFutureUtils.forwardExceptionTo(future, executeFuture); + } +} diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointAttemptMetricCollectionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointAttemptMetricCollectionStage.java new file mode 100644 index 000000000000..8e6fcaff5131 --- /dev/null +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointAttemptMetricCollectionStage.java @@ -0,0 +1,53 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.awssdk.core.internal.http.pipeline.stages; + +import static software.amazon.awssdk.core.internal.util.MetricUtils.collectServiceEndpointMetrics; +import static software.amazon.awssdk.core.internal.util.MetricUtils.createAttemptMetricsCollector; + +import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.core.Response; +import software.amazon.awssdk.core.internal.http.RequestExecutionContext; +import software.amazon.awssdk.core.internal.http.pipeline.RequestPipeline; +import software.amazon.awssdk.core.internal.http.pipeline.RequestToResponsePipeline; +import software.amazon.awssdk.http.SdkHttpFullRequest; +import software.amazon.awssdk.metrics.MetricCollector; + +/** + * Wrapper pipeline that initializes and tracks the API call attempt metric collection. This wrapper and any wrapped + * stages will track API call attempt metrics. + */ +@SdkInternalApi +public final class ServiceEndpointAttemptMetricCollectionStage implements RequestToResponsePipeline { + private final RequestPipeline> wrapped; + + public ServiceEndpointAttemptMetricCollectionStage(RequestPipeline> wrapped) { + this.wrapped = wrapped; + } + + @Override + public Response execute(SdkHttpFullRequest input, RequestExecutionContext context) throws Exception { + MetricCollector apiCallAttemptMetrics = createAttemptMetricsCollector(context); + context.attemptMetricCollector(apiCallAttemptMetrics); + + Response response = wrapped.execute(input, context); + + collectServiceEndpointMetrics(apiCallAttemptMetrics, input); + + return response; + } + +} diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointMetricCollectionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointMetricCollectionStage.java new file mode 100644 index 000000000000..cb5f0db7eb4e --- /dev/null +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointMetricCollectionStage.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.core.internal.http.pipeline.stages; + +import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.core.Response; +import software.amazon.awssdk.core.internal.http.RequestExecutionContext; +import software.amazon.awssdk.core.internal.http.pipeline.RequestPipeline; +import software.amazon.awssdk.core.internal.http.pipeline.RequestToResponsePipeline; +import software.amazon.awssdk.core.metrics.CoreMetric; +import software.amazon.awssdk.http.SdkHttpFullRequest; +import software.amazon.awssdk.metrics.MetricCollector; + +/** + * Wrapper pipeline that tracks the {@link CoreMetric#SERVICE_ENDPOINT} metric. + */ +@SdkInternalApi +public class ServiceEndpointMetricCollectionStage implements RequestToResponsePipeline { + private final RequestPipeline> wrapped; + + public ServiceEndpointMetricCollectionStage(RequestPipeline> wrapped) { + this.wrapped = wrapped; + } + + @Override + public Response execute(SdkHttpFullRequest input, RequestExecutionContext context) throws Exception { + MetricCollector metricCollector = context.executionContext().metricCollector(); + metricCollector.reportMetric(CoreMetric.SERVICE_ENDPOINT, input.getUri()); + + return wrapped.execute(input, context); + } +} 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 0c0d33d67369..1b1e918c2749 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 @@ -66,7 +66,7 @@ public static Pair measureDurationUnsafe(Callable c) throws return Pair.of(result, d); } - public static void collectHttpRequestMetrics(MetricCollector metricCollector, SdkHttpFullRequest httpRequest) { + public static void collectServiceEndpointMetrics(MetricCollector metricCollector, SdkHttpFullRequest httpRequest) { if (metricCollector != null && !(metricCollector instanceof NoOpMetricCollector) && httpRequest != null) { metricCollector.reportMetric(CoreMetric.SERVICE_ENDPOINT, httpRequest.getUri()); } diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java index a75bbe9ffb1c..28c945201b6c 100644 --- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java +++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java @@ -24,6 +24,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; +import java.net.URI; import java.time.Duration; import java.util.List; import java.util.stream.Collectors; diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/BaseAsyncCoreMetricsTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/BaseAsyncCoreMetricsTest.java index 0bfc93a83146..2054a7ea5d36 100644 --- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/BaseAsyncCoreMetricsTest.java +++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/async/BaseAsyncCoreMetricsTest.java @@ -203,8 +203,8 @@ private void verifyApiCallCollection(MetricCollection capturedCollection) { .isGreaterThanOrEqualTo(Duration.ZERO); assertThat(capturedCollection.metricValues(CoreMetric.API_CALL_DURATION).get(0)) .isGreaterThan(FIXED_DELAY); - assertThat(capturedCollection.metricValues(CoreMetric.SERVICE_ENDPOINT).get(0)) - .isEqualTo(URI.create("http://localhost")); + assertThat(capturedCollection.metricValues(CoreMetric.SERVICE_ENDPOINT).get(0)).toString() + .startsWith("http://localhost"); } void stubSuccessfulResponse() { From 8164d60d28464a98c0bee6088cef223c9e4b7102 Mon Sep 17 00:00:00 2001 From: Dongie Agnir Date: Tue, 15 Aug 2023 12:56:41 -0700 Subject: [PATCH 3/8] Remove erviceEndpointMetricCollectionStages since they're unnecessary --- .../internal/http/AmazonAsyncHttpClient.java | 4 +- .../internal/http/AmazonSyncHttpClient.java | 5 -- ...cServiceEndpointMetricCollectionStage.java | 59 ------------------- .../ServiceEndpointMetricCollectionStage.java | 45 -------------- 4 files changed, 1 insertion(+), 112 deletions(-) delete mode 100644 core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncServiceEndpointMetricCollectionStage.java delete mode 100644 core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointMetricCollectionStage.java diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonAsyncHttpClient.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonAsyncHttpClient.java index fcf80d14fbfa..766b998fa710 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonAsyncHttpClient.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonAsyncHttpClient.java @@ -37,7 +37,6 @@ import software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncBeforeTransmissionExecutionInterceptorsStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncExecutionFailureExceptionReportingStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncRetryableStage; -import software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncServiceEndpointMetricCollectionStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncSigningStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.HttpChecksumStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.MakeAsyncHttpRequestStage; @@ -184,8 +183,7 @@ public CompletableFuture execute( .then(async(() -> new AfterExecutionInterceptorsStage<>())) .wrappedWith(AsyncExecutionFailureExceptionReportingStage::new) .wrappedWith(AsyncApiCallTimeoutTrackingStage::new) - .wrappedWith(AsyncApiCallMetricCollectionStage::new) - .wrappedWith(AsyncServiceEndpointMetricCollectionStage::new)::build)::build) + .wrappedWith(AsyncApiCallMetricCollectionStage::new)::build)::build) .build(httpClientDependencies) .execute(request, createRequestExecutionDependencies()); } catch (RuntimeException e) { diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonSyncHttpClient.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonSyncHttpClient.java index 136e2f5dfd41..75cab29c6f51 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonSyncHttpClient.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/AmazonSyncHttpClient.java @@ -45,8 +45,6 @@ import software.amazon.awssdk.core.internal.http.pipeline.stages.MergeCustomHeadersStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.MergeCustomQueryParamsStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage; -import software.amazon.awssdk.core.internal.http.pipeline.stages.ServiceEndpointAttemptMetricCollectionStage; -import software.amazon.awssdk.core.internal.http.pipeline.stages.ServiceEndpointMetricCollectionStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.SigningStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.TimeoutExceptionHandlingStage; import software.amazon.awssdk.core.internal.http.pipeline.stages.UnwrapResponseContainer; @@ -187,13 +185,10 @@ public OutputT execute(HttpResponseHandler> response .wrappedWith(ApiCallAttemptTimeoutTrackingStage::new) .wrappedWith(TimeoutExceptionHandlingStage::new) .wrappedWith((deps, wrapped) -> new ApiCallAttemptMetricCollectionStage<>(wrapped)) - .wrappedWith((deps, wrapped) -> - new ServiceEndpointAttemptMetricCollectionStage<>(wrapped)) .wrappedWith(RetryableStage::new)::build) .wrappedWith(StreamManagingStage::new) .wrappedWith(ApiCallTimeoutTrackingStage::new)::build) .wrappedWith((deps, wrapped) -> new ApiCallMetricCollectionStage<>(wrapped)) - .wrappedWith((deps, wrapped) -> new ServiceEndpointMetricCollectionStage<>(wrapped)) .then(() -> new UnwrapResponseContainer<>()) .then(() -> new AfterExecutionInterceptorsStage<>()) .wrappedWith(ExecutionFailureExceptionReportingStage::new) diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncServiceEndpointMetricCollectionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncServiceEndpointMetricCollectionStage.java deleted file mode 100644 index 168186cb86db..000000000000 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncServiceEndpointMetricCollectionStage.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package software.amazon.awssdk.core.internal.http.pipeline.stages; - -import java.util.concurrent.CompletableFuture; -import software.amazon.awssdk.annotations.SdkInternalApi; -import software.amazon.awssdk.core.internal.http.RequestExecutionContext; -import software.amazon.awssdk.core.internal.http.pipeline.RequestPipeline; -import software.amazon.awssdk.core.metrics.CoreMetric; -import software.amazon.awssdk.http.SdkHttpFullRequest; -import software.amazon.awssdk.metrics.MetricCollector; -import software.amazon.awssdk.utils.CompletableFutureUtils; - -/** - * Wrapper pipeline that tracks the {@link CoreMetric#SERVICE_ENDPOINT} metric. - */ -@SdkInternalApi -public final class AsyncServiceEndpointMetricCollectionStage implements RequestPipeline> { - private final RequestPipeline> wrapped; - - public AsyncServiceEndpointMetricCollectionStage(RequestPipeline> wrapped) { - this.wrapped = wrapped; - } - - @Override - public CompletableFuture execute(SdkHttpFullRequest input, RequestExecutionContext context) throws Exception { - MetricCollector metricCollector = context.executionContext().metricCollector(); - - CompletableFuture future = new CompletableFuture<>(); - - CompletableFuture executeFuture = wrapped.execute(input, context); - - executeFuture.whenComplete((r, t) -> { - metricCollector.reportMetric(CoreMetric.SERVICE_ENDPOINT, input.getUri()); - - if (t != null) { - future.completeExceptionally(t); - } else { - future.complete(r); - } - }); - - return CompletableFutureUtils.forwardExceptionTo(future, executeFuture); - } -} diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointMetricCollectionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointMetricCollectionStage.java deleted file mode 100644 index cb5f0db7eb4e..000000000000 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointMetricCollectionStage.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package software.amazon.awssdk.core.internal.http.pipeline.stages; - -import software.amazon.awssdk.annotations.SdkInternalApi; -import software.amazon.awssdk.core.Response; -import software.amazon.awssdk.core.internal.http.RequestExecutionContext; -import software.amazon.awssdk.core.internal.http.pipeline.RequestPipeline; -import software.amazon.awssdk.core.internal.http.pipeline.RequestToResponsePipeline; -import software.amazon.awssdk.core.metrics.CoreMetric; -import software.amazon.awssdk.http.SdkHttpFullRequest; -import software.amazon.awssdk.metrics.MetricCollector; - -/** - * Wrapper pipeline that tracks the {@link CoreMetric#SERVICE_ENDPOINT} metric. - */ -@SdkInternalApi -public class ServiceEndpointMetricCollectionStage implements RequestToResponsePipeline { - private final RequestPipeline> wrapped; - - public ServiceEndpointMetricCollectionStage(RequestPipeline> wrapped) { - this.wrapped = wrapped; - } - - @Override - public Response execute(SdkHttpFullRequest input, RequestExecutionContext context) throws Exception { - MetricCollector metricCollector = context.executionContext().metricCollector(); - metricCollector.reportMetric(CoreMetric.SERVICE_ENDPOINT, input.getUri()); - - return wrapped.execute(input, context); - } -} From faa8de0a45a1f426ec2c3d74aa6d4a249acc03ed Mon Sep 17 00:00:00 2001 From: Dongie Agnir Date: Tue, 15 Aug 2023 13:30:01 -0700 Subject: [PATCH 4/8] Move collection of SERVICE_ENDPOINT metric Simplify by collecting in the API Call metric collection stages where other request metrics are already being collected. --- .../stages/ApiCallMetricCollectionStage.java | 2 ++ .../AsyncApiCallMetricCollectionStage.java | 2 ++ .../core/internal/util/MetricUtils.java | 16 +++++++++- .../core/internal/util/MetricUtilsTest.java | 1 + .../services/metrics/CoreMetricsTest.java | 31 +++++++++++++++++++ 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallMetricCollectionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallMetricCollectionStage.java index a54fd9678376..3b78dedaf2ad 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallMetricCollectionStage.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallMetricCollectionStage.java @@ -21,6 +21,7 @@ import software.amazon.awssdk.core.internal.http.RequestExecutionContext; import software.amazon.awssdk.core.internal.http.pipeline.RequestPipeline; import software.amazon.awssdk.core.internal.http.pipeline.RequestToResponsePipeline; +import software.amazon.awssdk.core.internal.util.MetricUtils; import software.amazon.awssdk.core.metrics.CoreMetric; import software.amazon.awssdk.http.SdkHttpFullRequest; import software.amazon.awssdk.metrics.MetricCollector; @@ -39,6 +40,7 @@ public ApiCallMetricCollectionStage(RequestPipeline execute(SdkHttpFullRequest input, RequestExecutionContext context) throws Exception { MetricCollector metricCollector = context.executionContext().metricCollector(); + MetricUtils.collectServiceEndpointMetrics(metricCollector, input); // Note: at this point, any exception, even a service exception, will // be thrown from the wrapped pipeline so we can't use diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncApiCallMetricCollectionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncApiCallMetricCollectionStage.java index 3d57cedea52d..09016026be1c 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncApiCallMetricCollectionStage.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AsyncApiCallMetricCollectionStage.java @@ -20,6 +20,7 @@ import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.core.internal.http.RequestExecutionContext; import software.amazon.awssdk.core.internal.http.pipeline.RequestPipeline; +import software.amazon.awssdk.core.internal.util.MetricUtils; import software.amazon.awssdk.core.metrics.CoreMetric; import software.amazon.awssdk.http.SdkHttpFullRequest; import software.amazon.awssdk.metrics.MetricCollector; @@ -40,6 +41,7 @@ public AsyncApiCallMetricCollectionStage(RequestPipeline execute(SdkHttpFullRequest input, RequestExecutionContext context) throws Exception { MetricCollector metricCollector = context.executionContext().metricCollector(); + MetricUtils.collectServiceEndpointMetrics(metricCollector, input); CompletableFuture future = new CompletableFuture<>(); 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 1b1e918c2749..bee59eae51ff 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 @@ -18,10 +18,13 @@ import static software.amazon.awssdk.core.http.HttpResponseHandler.X_AMZN_REQUEST_ID_HEADERS; import static software.amazon.awssdk.core.http.HttpResponseHandler.X_AMZ_ID_2_HEADER; +import java.net.URI; +import java.net.URISyntaxException; import java.time.Duration; import java.util.concurrent.Callable; import java.util.function.Supplier; import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.core.exception.SdkClientException; import software.amazon.awssdk.core.internal.http.RequestExecutionContext; import software.amazon.awssdk.core.metrics.CoreMetric; import software.amazon.awssdk.http.HttpMetric; @@ -66,9 +69,20 @@ public static Pair measureDurationUnsafe(Callable c) throws return Pair.of(result, d); } + /** + * Collect the SERVICE_ENDPOINT metric for this request. + */ public static void collectServiceEndpointMetrics(MetricCollector metricCollector, SdkHttpFullRequest httpRequest) { if (metricCollector != null && !(metricCollector instanceof NoOpMetricCollector) && httpRequest != null) { - metricCollector.reportMetric(CoreMetric.SERVICE_ENDPOINT, httpRequest.getUri()); + // Only interested in the service endpoint so don't include any path, query, or fragment component + URI requestUri = httpRequest.getUri(); + try { + URI serviceEndpoint = new URI(requestUri.getScheme(), requestUri.getAuthority(), null, null, null); + metricCollector.reportMetric(CoreMetric.SERVICE_ENDPOINT, serviceEndpoint); + } catch (URISyntaxException e) { + // This should not happen since getUri() should return a valid URI + throw SdkClientException.create("Unable to collect SERVICE_ENDPOINT metric", e); + } } } diff --git a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/util/MetricUtilsTest.java b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/util/MetricUtilsTest.java index b32a543a7404..cd5a74a0c190 100644 --- a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/util/MetricUtilsTest.java +++ b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/util/MetricUtilsTest.java @@ -24,6 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.mockito.Mockito; import software.amazon.awssdk.core.http.HttpResponseHandler; import software.amazon.awssdk.core.metrics.CoreMetric; import software.amazon.awssdk.http.HttpMetric; diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java index 28c945201b6c..1f335dde578d 100644 --- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java +++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java @@ -27,6 +27,7 @@ import java.net.URI; import java.time.Duration; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import org.junit.After; import org.junit.Before; @@ -42,6 +43,7 @@ import software.amazon.awssdk.core.exception.SdkException; import software.amazon.awssdk.core.metrics.CoreMetric; import software.amazon.awssdk.core.internal.metrics.SdkErrorType; +import software.amazon.awssdk.endpoints.Endpoint; import software.amazon.awssdk.http.AbortableInputStream; import software.amazon.awssdk.http.ExecutableHttpRequest; import software.amazon.awssdk.http.HttpExecuteRequest; @@ -53,6 +55,8 @@ import software.amazon.awssdk.metrics.MetricPublisher; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.protocolrestjson.ProtocolRestJsonClient; +import software.amazon.awssdk.services.protocolrestjson.endpoints.ProtocolRestJsonEndpointParams; +import software.amazon.awssdk.services.protocolrestjson.endpoints.ProtocolRestJsonEndpointProvider; import software.amazon.awssdk.services.protocolrestjson.model.EmptyModeledException; import software.amazon.awssdk.services.protocolrestjson.model.SimpleStruct; import software.amazon.awssdk.services.protocolrestjson.paginators.PaginatedOperationWithResultKeyIterable; @@ -78,6 +82,9 @@ public class CoreMetricsTest { @Mock private MetricPublisher mockPublisher; + @Mock + private ProtocolRestJsonEndpointProvider mockEndpointProvider; + @Before public void setup() throws IOException { client = ProtocolRestJsonClient.builder() @@ -85,6 +92,7 @@ public void setup() throws IOException { .region(Region.US_WEST_2) .credentialsProvider(mockCredentialsProvider) .overrideConfiguration(c -> c.addMetricPublisher(mockPublisher).retryPolicy(b -> b.numRetries(MAX_RETRIES))) + .endpointProvider(mockEndpointProvider) .build(); AbortableInputStream content = contentStream("{}"); SdkHttpFullResponse httpResponse = SdkHttpFullResponse.builder() @@ -117,6 +125,11 @@ public void setup() throws IOException { } return AwsBasicCredentials.create("foo", "bar"); }); + + when(mockEndpointProvider.resolveEndpoint(any(ProtocolRestJsonEndpointParams.class))).thenReturn( + CompletableFuture.completedFuture(Endpoint.builder() + .url(URI.create("https://protocolrestjson.amazonaws.com")) + .build())); } @After @@ -283,6 +296,24 @@ public void testApiCall_httpClientThrowsNetworkError_errorTypeIncludedInMetrics( } } + @Test + public void testApiCall_endpointProviderAddsPathQueryFragment_notReportedInServiceEndpointMetric() { + when(mockEndpointProvider.resolveEndpoint(any(ProtocolRestJsonEndpointParams.class))) + .thenReturn(CompletableFuture.completedFuture(Endpoint.builder() + .url(URI.create("https://protocolrestjson.amazonaws.com:8080/foo?bar#baz")) + .build())); + + client.allTypes(); + + ArgumentCaptor collectionCaptor = ArgumentCaptor.forClass(MetricCollection.class); + verify(mockPublisher).publish(collectionCaptor.capture()); + + MetricCollection capturedCollection = collectionCaptor.getValue(); + + URI expectedServiceEndpoint = URI.create("https://protocolrestjson.amazonaws.com:8080"); + assertThat(capturedCollection.metricValues(CoreMetric.SERVICE_ENDPOINT)).containsExactly(expectedServiceEndpoint); + } + private static HttpExecuteResponse mockExecuteResponse(SdkHttpFullResponse httpResponse) { HttpExecuteResponse mockResponse = mock(HttpExecuteResponse.class); From bcee6c847c8067c918049c98002ec505bf52b8df Mon Sep 17 00:00:00 2001 From: Dongie Agnir Date: Tue, 15 Aug 2023 13:32:40 -0700 Subject: [PATCH 5/8] Remove unused import --- .../amazon/awssdk/core/internal/util/MetricUtilsTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/util/MetricUtilsTest.java b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/util/MetricUtilsTest.java index cd5a74a0c190..b32a543a7404 100644 --- a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/util/MetricUtilsTest.java +++ b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/util/MetricUtilsTest.java @@ -24,7 +24,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.mockito.Mockito; import software.amazon.awssdk.core.http.HttpResponseHandler; import software.amazon.awssdk.core.metrics.CoreMetric; import software.amazon.awssdk.http.HttpMetric; From 9335736af8aec082034d4dda26df96115abf9b86 Mon Sep 17 00:00:00 2001 From: Dongie Agnir Date: Tue, 15 Aug 2023 13:32:47 -0700 Subject: [PATCH 6/8] Update changelog entry --- .changes/next-release/bugfix-AWSSDKforJavav2-0a552ee.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changes/next-release/bugfix-AWSSDKforJavav2-0a552ee.json b/.changes/next-release/bugfix-AWSSDKforJavav2-0a552ee.json index 7ff6d8584379..4521e9e47d8e 100644 --- a/.changes/next-release/bugfix-AWSSDKforJavav2-0a552ee.json +++ b/.changes/next-release/bugfix-AWSSDKforJavav2-0a552ee.json @@ -2,5 +2,5 @@ "category": "AWS SDK for Java v2", "contributor": "", "type": "bugfix", - "description": "Implement SERVICE_ENDPOINT core metric" + "description": "Add support for the `SERVICE_ENDPOINT` metric. This metric represents the endpoint (scheme and authority) that the request was sent to." } From ba89f477aa0e3570a9c86b312c86ea243407d489 Mon Sep 17 00:00:00 2001 From: Dongie Agnir Date: Tue, 15 Aug 2023 14:47:56 -0700 Subject: [PATCH 7/8] Fix test --- .../amazon/awssdk/services/metrics/CoreMetricsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java index 1f335dde578d..583f1ae1a30c 100644 --- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java +++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/metrics/CoreMetricsTest.java @@ -198,7 +198,7 @@ public void testApiCall_operationSuccessful_addsMetrics() { .isGreaterThanOrEqualTo(Duration.ZERO); assertThat(capturedCollection.metricValues(CoreMetric.RETRY_COUNT)).containsExactly(0); assertThat(capturedCollection.metricValues(CoreMetric.SERVICE_ENDPOINT).get(0)).isEqualTo(URI.create( - "https://customresponsemetadata.us-west-2.amazonaws.com")); + "https://protocolrestjson.amazonaws.com")); assertThat(capturedCollection.children()).hasSize(1); MetricCollection attemptCollection = capturedCollection.children().get(0); From 7eaa5d68cfd5d6dca2b9babda2b1898180775d8c Mon Sep 17 00:00:00 2001 From: Dongie Agnir Date: Tue, 15 Aug 2023 14:55:10 -0700 Subject: [PATCH 8/8] Remove unused class --- ...eEndpointAttemptMetricCollectionStage.java | 53 ------------------- 1 file changed, 53 deletions(-) delete mode 100644 core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointAttemptMetricCollectionStage.java diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointAttemptMetricCollectionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointAttemptMetricCollectionStage.java deleted file mode 100644 index 8e6fcaff5131..000000000000 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ServiceEndpointAttemptMetricCollectionStage.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package software.amazon.awssdk.core.internal.http.pipeline.stages; - -import static software.amazon.awssdk.core.internal.util.MetricUtils.collectServiceEndpointMetrics; -import static software.amazon.awssdk.core.internal.util.MetricUtils.createAttemptMetricsCollector; - -import software.amazon.awssdk.annotations.SdkInternalApi; -import software.amazon.awssdk.core.Response; -import software.amazon.awssdk.core.internal.http.RequestExecutionContext; -import software.amazon.awssdk.core.internal.http.pipeline.RequestPipeline; -import software.amazon.awssdk.core.internal.http.pipeline.RequestToResponsePipeline; -import software.amazon.awssdk.http.SdkHttpFullRequest; -import software.amazon.awssdk.metrics.MetricCollector; - -/** - * Wrapper pipeline that initializes and tracks the API call attempt metric collection. This wrapper and any wrapped - * stages will track API call attempt metrics. - */ -@SdkInternalApi -public final class ServiceEndpointAttemptMetricCollectionStage implements RequestToResponsePipeline { - private final RequestPipeline> wrapped; - - public ServiceEndpointAttemptMetricCollectionStage(RequestPipeline> wrapped) { - this.wrapped = wrapped; - } - - @Override - public Response execute(SdkHttpFullRequest input, RequestExecutionContext context) throws Exception { - MetricCollector apiCallAttemptMetrics = createAttemptMetricsCollector(context); - context.attemptMetricCollector(apiCallAttemptMetrics); - - Response response = wrapped.execute(input, context); - - collectServiceEndpointMetrics(apiCallAttemptMetrics, input); - - return response; - } - -}