Skip to content

Commit ed69ac0

Browse files
committed
Move sigv4a business metric logic to auth interceptor to record at auth scheme selection
1 parent 025cb48 commit ed69ac0

File tree

5 files changed

+64
-42
lines changed

5 files changed

+64
-42
lines changed

codegen/src/main/java/software/amazon/awssdk/codegen/poet/auth/scheme/AuthSchemeInterceptorSpec.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import software.amazon.awssdk.core.metrics.CoreMetric;
5252
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
5353
import software.amazon.awssdk.endpoints.EndpointProvider;
54+
import software.amazon.awssdk.http.auth.aws.scheme.AwsV4aAuthScheme;
5455
import software.amazon.awssdk.http.auth.aws.signer.RegionSet;
5556
import software.amazon.awssdk.http.auth.scheme.BearerAuthScheme;
5657
import software.amazon.awssdk.http.auth.spi.scheme.AuthScheme;
@@ -158,6 +159,22 @@ private MethodSpec generateBeforeExecution() {
158159
builder.addStatement("recordEnvironmentTokenBusinessMetric(selectedAuthScheme, "
159160
+ "executionAttributes)");
160161
}
162+
163+
if (authSchemeSpecUtils.hasSigV4aSupport()) {
164+
builder.beginControlFlow("if (selectedAuthScheme != null && "
165+
+ "selectedAuthScheme.authSchemeOption().schemeId().equals($T.SCHEME_ID) && "
166+
+ "!$T.isSignerOverridden(context.request(), executionAttributes))",
167+
AwsV4aAuthScheme.class,
168+
ClassName.get("software.amazon.awssdk.awscore.util", "SignerOverrideUtils"))
169+
.addStatement("$T businessMetrics = executionAttributes.getAttribute($T.BUSINESS_METRICS)",
170+
ClassName.get("software.amazon.awssdk.core.useragent", "BusinessMetricCollection"),
171+
SdkInternalExecutionAttribute.class)
172+
.beginControlFlow("if (businessMetrics != null)")
173+
.addStatement("businessMetrics.addMetric($T.SIGV4A_SIGNING.value())",
174+
BusinessMetricFeatureId.class)
175+
.endControlFlow()
176+
.endControlFlow();
177+
}
161178
return builder.build();
162179
}
163180

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/auth/scheme/ops-auth-sigv4a-value-auth-scheme-interceptor.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import software.amazon.awssdk.annotations.Generated;
1111
import software.amazon.awssdk.annotations.SdkInternalApi;
1212
import software.amazon.awssdk.awscore.AwsExecutionAttribute;
13+
import software.amazon.awssdk.awscore.util.SignerOverrideUtils;
1314
import software.amazon.awssdk.core.SdkRequest;
1415
import software.amazon.awssdk.core.SelectedAuthScheme;
1516
import software.amazon.awssdk.core.exception.SdkException;
@@ -20,6 +21,9 @@
2021
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
2122
import software.amazon.awssdk.core.internal.util.MetricUtils;
2223
import software.amazon.awssdk.core.metrics.CoreMetric;
24+
import software.amazon.awssdk.core.useragent.BusinessMetricCollection;
25+
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
26+
import software.amazon.awssdk.http.auth.aws.scheme.AwsV4aAuthScheme;
2327
import software.amazon.awssdk.http.auth.aws.signer.RegionSet;
2428
import software.amazon.awssdk.http.auth.spi.scheme.AuthScheme;
2529
import software.amazon.awssdk.http.auth.spi.scheme.AuthSchemeOption;
@@ -49,6 +53,14 @@ public void beforeExecution(Context.BeforeExecution context, ExecutionAttributes
4953
List<AuthSchemeOption> authOptions = resolveAuthOptions(context, executionAttributes);
5054
SelectedAuthScheme<? extends Identity> selectedAuthScheme = selectAuthScheme(authOptions, executionAttributes);
5155
putSelectedAuthScheme(executionAttributes, selectedAuthScheme);
56+
if (selectedAuthScheme != null && selectedAuthScheme.authSchemeOption().schemeId().equals(AwsV4aAuthScheme.SCHEME_ID)
57+
&& !SignerOverrideUtils.isSignerOverridden(context.request(), executionAttributes)) {
58+
BusinessMetricCollection businessMetrics = executionAttributes
59+
.getAttribute(SdkInternalExecutionAttribute.BUSINESS_METRICS);
60+
if (businessMetrics != null) {
61+
businessMetrics.addMetric(BusinessMetricFeatureId.SIGV4A_SIGNING.value());
62+
}
63+
}
5264
}
5365

5466
private List<AuthSchemeOption> resolveAuthOptions(Context.BeforeExecution context, ExecutionAttributes executionAttributes) {

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/auth/scheme/query-endpoint-auth-params-with-allowlist-auth-scheme-interceptor.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import software.amazon.awssdk.annotations.Generated;
1111
import software.amazon.awssdk.annotations.SdkInternalApi;
1212
import software.amazon.awssdk.awscore.AwsExecutionAttribute;
13+
import software.amazon.awssdk.awscore.util.SignerOverrideUtils;
1314
import software.amazon.awssdk.core.SdkRequest;
1415
import software.amazon.awssdk.core.SelectedAuthScheme;
1516
import software.amazon.awssdk.core.exception.SdkException;
@@ -20,7 +21,10 @@
2021
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
2122
import software.amazon.awssdk.core.internal.util.MetricUtils;
2223
import software.amazon.awssdk.core.metrics.CoreMetric;
24+
import software.amazon.awssdk.core.useragent.BusinessMetricCollection;
25+
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
2326
import software.amazon.awssdk.endpoints.EndpointProvider;
27+
import software.amazon.awssdk.http.auth.aws.scheme.AwsV4aAuthScheme;
2428
import software.amazon.awssdk.http.auth.aws.signer.RegionSet;
2529
import software.amazon.awssdk.http.auth.spi.scheme.AuthScheme;
2630
import software.amazon.awssdk.http.auth.spi.scheme.AuthSchemeOption;
@@ -52,6 +56,14 @@ public void beforeExecution(Context.BeforeExecution context, ExecutionAttributes
5256
List<AuthSchemeOption> authOptions = resolveAuthOptions(context, executionAttributes);
5357
SelectedAuthScheme<? extends Identity> selectedAuthScheme = selectAuthScheme(authOptions, executionAttributes);
5458
putSelectedAuthScheme(executionAttributes, selectedAuthScheme);
59+
if (selectedAuthScheme != null && selectedAuthScheme.authSchemeOption().schemeId().equals(AwsV4aAuthScheme.SCHEME_ID)
60+
&& !SignerOverrideUtils.isSignerOverridden(context.request(), executionAttributes)) {
61+
BusinessMetricCollection businessMetrics = executionAttributes
62+
.getAttribute(SdkInternalExecutionAttribute.BUSINESS_METRICS);
63+
if (businessMetrics != null) {
64+
businessMetrics.addMetric(BusinessMetricFeatureId.SIGV4A_SIGNING.value());
65+
}
66+
}
5567
}
5668

5769
private List<AuthSchemeOption> resolveAuthOptions(Context.BeforeExecution context, ExecutionAttributes executionAttributes) {
@@ -102,7 +114,6 @@ private QueryAuthSchemeParams authSchemeParams(SdkRequest request, ExecutionAttr
102114
executionAttributes.getOptionalAttribute(AwsExecutionAttribute.AWS_SIGV4A_SIGNING_REGION_SET)
103115
.filter(regionSet -> !CollectionUtils.isNullOrEmpty(regionSet))
104116
.ifPresent(nonEmptyRegionSet -> builder.regionSet(RegionSet.create(nonEmptyRegionSet)));
105-
106117
if (builder instanceof QueryEndpointResolverAware.Builder) {
107118
EndpointProvider endpointProvider = executionAttributes.getAttribute(SdkInternalExecutionAttribute.ENDPOINT_PROVIDER);
108119
if (endpointProvider instanceof QueryEndpointProvider) {

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/auth/scheme/query-endpoint-auth-params-without-allowlist-auth-scheme-interceptor.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import software.amazon.awssdk.annotations.Generated;
1111
import software.amazon.awssdk.annotations.SdkInternalApi;
1212
import software.amazon.awssdk.awscore.AwsExecutionAttribute;
13+
import software.amazon.awssdk.awscore.util.SignerOverrideUtils;
1314
import software.amazon.awssdk.core.SdkRequest;
1415
import software.amazon.awssdk.core.SelectedAuthScheme;
1516
import software.amazon.awssdk.core.exception.SdkException;
@@ -20,7 +21,10 @@
2021
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
2122
import software.amazon.awssdk.core.internal.util.MetricUtils;
2223
import software.amazon.awssdk.core.metrics.CoreMetric;
24+
import software.amazon.awssdk.core.useragent.BusinessMetricCollection;
25+
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
2326
import software.amazon.awssdk.endpoints.EndpointProvider;
27+
import software.amazon.awssdk.http.auth.aws.scheme.AwsV4aAuthScheme;
2428
import software.amazon.awssdk.http.auth.aws.signer.RegionSet;
2529
import software.amazon.awssdk.http.auth.spi.scheme.AuthScheme;
2630
import software.amazon.awssdk.http.auth.spi.scheme.AuthSchemeOption;
@@ -52,6 +56,14 @@ public void beforeExecution(Context.BeforeExecution context, ExecutionAttributes
5256
List<AuthSchemeOption> authOptions = resolveAuthOptions(context, executionAttributes);
5357
SelectedAuthScheme<? extends Identity> selectedAuthScheme = selectAuthScheme(authOptions, executionAttributes);
5458
putSelectedAuthScheme(executionAttributes, selectedAuthScheme);
59+
if (selectedAuthScheme != null && selectedAuthScheme.authSchemeOption().schemeId().equals(AwsV4aAuthScheme.SCHEME_ID)
60+
&& !SignerOverrideUtils.isSignerOverridden(context.request(), executionAttributes)) {
61+
BusinessMetricCollection businessMetrics = executionAttributes
62+
.getAttribute(SdkInternalExecutionAttribute.BUSINESS_METRICS);
63+
if (businessMetrics != null) {
64+
businessMetrics.addMetric(BusinessMetricFeatureId.SIGV4A_SIGNING.value());
65+
}
66+
}
5567
}
5668

5769
private List<AuthSchemeOption> resolveAuthOptions(Context.BeforeExecution context, ExecutionAttributes executionAttributes) {

core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/ApplyUserAgentStage.java

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,17 @@
2828
import java.util.Optional;
2929
import software.amazon.awssdk.annotations.SdkInternalApi;
3030
import software.amazon.awssdk.core.ApiName;
31-
import software.amazon.awssdk.core.RequestOverrideConfiguration;
32-
import software.amazon.awssdk.core.SelectedAuthScheme;
3331
import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption;
3432
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
3533
import software.amazon.awssdk.core.client.config.SdkClientOption;
3634
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
37-
import software.amazon.awssdk.core.interceptor.SdkExecutionAttribute;
3835
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
3936
import software.amazon.awssdk.core.internal.http.HttpClientDependencies;
4037
import software.amazon.awssdk.core.internal.http.RequestExecutionContext;
4138
import software.amazon.awssdk.core.internal.http.pipeline.MutableRequestToRequestPipeline;
42-
import software.amazon.awssdk.core.signer.Signer;
4339
import software.amazon.awssdk.core.useragent.AdditionalMetadata;
4440
import software.amazon.awssdk.core.useragent.BusinessMetricCollection;
45-
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
4641
import software.amazon.awssdk.http.SdkHttpFullRequest;
47-
import software.amazon.awssdk.http.auth.aws.scheme.AwsV4aAuthScheme;
4842
import software.amazon.awssdk.identity.spi.Identity;
4943
import software.amazon.awssdk.utils.CompletableFutureUtils;
5044
import software.amazon.awssdk.utils.Logger;
@@ -53,7 +47,7 @@
5347

5448
/**
5549
* A stage for adding the user agent header to the request, after retrieving the current string
56-
* from execution attributes and adding any additional information.
50+
* from execution attributes and adding any additional information.
5751
*/
5852
@SdkInternalApi
5953
public class ApplyUserAgentStage implements MutableRequestToRequestPipeline {
@@ -118,8 +112,7 @@ private String finalizeUserAgent(RequestExecutionContext context) {
118112
userAgentMetadata.forEach(s -> javaUserAgent.append(SPACE).append(s));
119113
}
120114

121-
Optional<String> businessMetrics = getBusinessMetricsString(context.executionAttributes(),
122-
groupedApiNames.right(), context);
115+
Optional<String> businessMetrics = getBusinessMetricsString(context.executionAttributes(), groupedApiNames.right());
123116
businessMetrics.ifPresent(
124117
metrics -> appendSpaceAndField(javaUserAgent, BUSINESS_METADATA, metrics)
125118
);
@@ -150,32 +143,29 @@ private static Pair<List<ApiName>, Collection<String>> groupApiNames(List<ApiNam
150143
}
151144

152145
private static Optional<String> getBusinessMetricsString(ExecutionAttributes executionAttributes,
153-
Collection<String> metricsFromApiNames,
154-
RequestExecutionContext context) {
146+
Collection<String> metricsFromApiNames) {
155147
BusinessMetricCollection businessMetrics =
156148
executionAttributes.getAttribute(SdkInternalExecutionAttribute.BUSINESS_METRICS);
157149
if (businessMetrics == null) {
158150
businessMetrics = new BusinessMetricCollection();
159151
}
160152
businessMetrics.merge(metricsFromApiNames);
161153

162-
SelectedAuthScheme<?> selectedAuthScheme =
163-
executionAttributes.getAttribute(SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME);
154+
credentialProviderBusinessMetrics(executionAttributes).ifPresent(businessMetrics::merge);
164155

165-
credentialProviderBusinessMetrics(selectedAuthScheme).ifPresent(businessMetrics::merge);
166-
addSigV4aBusinessMetrics(selectedAuthScheme, businessMetrics, context, executionAttributes);
167-
168156
if (businessMetrics.recordedMetrics().isEmpty()) {
169157
return Optional.empty();
170158
}
171-
159+
172160
return Optional.of(businessMetrics.asBoundedString());
173161
}
174162

175163
private static Optional<Collection<String>> credentialProviderBusinessMetrics(
176-
SelectedAuthScheme<?> selectedAuthScheme) {
177-
return Optional.ofNullable(selectedAuthScheme)
178-
.map(scheme -> CompletableFutureUtils.joinLikeSync(scheme.identity()))
164+
ExecutionAttributes executionAttributes) {
165+
return Optional.ofNullable(
166+
executionAttributes.getAttribute(SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME))
167+
.map(selectedAuthScheme ->
168+
CompletableFutureUtils.joinLikeSync(selectedAuthScheme.identity()))
179169
.flatMap(Identity::providerName)
180170
.map(providerName -> {
181171
if (StringUtils.isBlank(providerName)) {
@@ -185,26 +175,6 @@ private static Optional<Collection<String>> credentialProviderBusinessMetrics(
185175
});
186176
}
187177

188-
private static boolean isSignerOverridden(RequestExecutionContext context, ExecutionAttributes executionAttributes) {
189-
boolean isClientSignerOverridden =
190-
Boolean.TRUE.equals(executionAttributes.getAttribute(SdkExecutionAttribute.SIGNER_OVERRIDDEN));
191-
Optional<Signer> requestSigner = context.originalRequest().overrideConfiguration()
192-
.flatMap(RequestOverrideConfiguration::signer);
193-
return isClientSignerOverridden || requestSigner.isPresent();
194-
}
195-
196-
private static void addSigV4aBusinessMetrics(SelectedAuthScheme<?> selectedAuthScheme,
197-
BusinessMetricCollection businessMetrics,
198-
RequestExecutionContext context,
199-
ExecutionAttributes executionAttributes) {
200-
if (selectedAuthScheme != null &&
201-
selectedAuthScheme.authSchemeOption().schemeId().equals(AwsV4aAuthScheme.SCHEME_ID) &&
202-
!isSignerOverridden(context, executionAttributes)) {
203-
204-
businessMetrics.addMetric(BusinessMetricFeatureId.SIGV4A_SIGNING.value());
205-
}
206-
}
207-
208178
/**
209179
* This structure is used for external users as well as for internal tracking of features.
210180
* It's not governed by a specification.
@@ -225,4 +195,4 @@ private Optional<String> requestApiNames(List<ApiName> requestApiNames) {
225195
.append(apiName.version()));
226196
return Optional.of(concatenatedNames.toString());
227197
}
228-
}
198+
}

0 commit comments

Comments
 (0)