Skip to content

Commit dea1fee

Browse files
committed
Add support for tracking business metrics from resolved endpoints
1 parent e520f06 commit dea1fee

16 files changed

+913
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "feature",
3+
"category": "AWS SDK for Java V2",
4+
"contributor": "",
5+
"description": "Add support for tracking business metrics from resolved endpoints."
6+
}

codegen/src/main/java/software/amazon/awssdk/codegen/poet/rules/EndpointResolverInterceptorSpec.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
import software.amazon.awssdk.core.metrics.CoreMetric;
7676
import software.amazon.awssdk.core.signer.Signer;
7777
import software.amazon.awssdk.endpoints.Endpoint;
78+
import software.amazon.awssdk.endpoints.EndpointAttributeKey;
7879
import software.amazon.awssdk.http.SdkHttpRequest;
7980
import software.amazon.awssdk.http.auth.aws.scheme.AwsV4AuthScheme;
8081
import software.amazon.awssdk.http.auth.aws.scheme.AwsV4aAuthScheme;
@@ -160,6 +161,8 @@ public TypeSpec poetSpec() {
160161
}
161162

162163
endpointParamsKnowledgeIndex.addAccountIdMethodsIfPresent(b);
164+
165+
b.addMethod(setMetricValuesMethod());
163166
return b.build();
164167
}
165168

@@ -255,6 +258,7 @@ private MethodSpec modifyRequestMethod(String endpointAuthSchemeStrategyFieldNam
255258
}
256259

257260
b.addStatement("executionAttributes.putAttribute(SdkInternalExecutionAttribute.RESOLVED_ENDPOINT, endpoint)");
261+
b.addStatement("setMetricValues(endpoint, executionAttributes)");
258262
b.addStatement("return result");
259263
b.endControlFlow();
260264
b.beginControlFlow("catch ($T e)", CompletionException.class);
@@ -905,4 +909,19 @@ private MethodSpec constructorMethodSpec(String endpointAuthSchemeFieldName) {
905909
b.addStatement("this.$N = $N.endpointAuthSchemeStrategy()", endpointAuthSchemeFieldName, factoryLocalVarName);
906910
return b.build();
907911
}
912+
913+
private MethodSpec setMetricValuesMethod() {
914+
MethodSpec.Builder b = MethodSpec.methodBuilder("setMetricValues")
915+
.addModifiers(Modifier.PRIVATE)
916+
.addParameter(Endpoint.class, "endpoint")
917+
.addParameter(ExecutionAttributes.class, "executionAttributes")
918+
.returns(void.class);
919+
920+
b.beginControlFlow("if (endpoint.attribute($T.METRIC_VALUES) != null)", AwsEndpointAttribute.class);
921+
b.addStatement("executionAttributes.getOptionalAttribute($T.BUSINESS_METRICS).ifPresent("
922+
+ "metrics -> endpoint.attribute($T.METRIC_VALUES).forEach(v -> metrics.addMetric(v))))",
923+
SdkInternalExecutionAttribute.class, AwsEndpointAttribute.class);
924+
b.endControlFlow();
925+
return b.build();
926+
}
908927
}

codegen/src/main/java/software/amazon/awssdk/codegen/poet/rules/TestGeneratorUtils.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ private static void addEndpointAttributeBlock(CodeBlock.Builder builder, String
115115
Map<String, KeyTypePair> knownEndpointAttributes) {
116116
if ("authSchemes".equals(attrName)) {
117117
addAuthSchemesBlock(builder, attrValue);
118+
} else if ("metricValues".equals(attrName)) {
119+
addMetricValuesBlock(builder, attrValue);
118120
} else if (knownEndpointAttributes.containsKey(attrName)) {
119121
addAttributeBlock(builder, attrValue, knownEndpointAttributes.get(attrName));
120122
} else {
@@ -124,6 +126,29 @@ private static void addEndpointAttributeBlock(CodeBlock.Builder builder, String
124126
}
125127
}
126128

129+
private static void addMetricValuesBlock(CodeBlock.Builder builder, TreeNode attrValue) {
130+
CodeBlock keyExpr = CodeBlock.builder()
131+
.add("$T.METRIC_VALUES", AwsEndpointAttribute.class)
132+
.build();
133+
134+
CodeBlock.Builder schemesListExpr = CodeBlock.builder()
135+
.add("$T.asList(", Arrays.class);
136+
137+
JrsArray schemesArray = (JrsArray) attrValue;
138+
139+
Iterator<JrsValue> elementsIter = schemesArray.elements();
140+
while (elementsIter.hasNext()) {
141+
schemesListExpr.add("$S", elementsIter.next().asText());
142+
143+
if (elementsIter.hasNext()) {
144+
schemesListExpr.add(",");
145+
}
146+
}
147+
schemesListExpr.add(")");
148+
149+
builder.add(".putAttribute($L, $L)", keyExpr, schemesListExpr.build());
150+
}
151+
127152
private static void addAttributeBlock(CodeBlock.Builder builder, TreeNode attrValue, KeyTypePair keyType) {
128153
CodeBlock keyExpr = CodeBlock.builder()
129154
.add("$L", keyType.getKey())

codegen/src/main/java/software/amazon/awssdk/codegen/poet/rules2/CodeGeneratorVisitor.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,8 @@ public Void visitPropertiesExpression(PropertiesExpression e) {
353353
properties.forEach((k, v) -> {
354354
if ("authSchemes".equals(k)) {
355355
addAuthSchemesBlock(v);
356+
} else if ("metricValues".equals(k)) {
357+
addMetricValuesBlock(v);
356358
} else if (knownEndpointAttributes.containsKey(k)) {
357359
addAttributeBlock(k, v);
358360
} else {
@@ -436,6 +438,12 @@ private ClassName authSchemeClass(String name) {
436438
}
437439
}
438440

441+
private void addMetricValuesBlock(RuleExpression v) {
442+
builder.add(".putAttribute($T.METRIC_VALUES, ", AwsEndpointAttribute.class);
443+
v.accept(this);
444+
builder.add(")");
445+
}
446+
439447
private void addAttributeBlock(String k, RuleExpression v) {
440448
KeyTypePair keyType = knownEndpointAttributes.get(k);
441449
ClassConstant classConstant = parseClassConstant(keyType.getKey());

codegen/src/test/java/software/amazon/awssdk/codegen/poet/ClientTestModels.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,26 @@ public static IntermediateModel queryServiceModelsWithUnknownEndpointProperties(
206206
return new IntermediateModelBuilder(models).build();
207207
}
208208

209+
public static IntermediateModel queryServiceModelsWithUnknownEndpointMetricValues() {
210+
File serviceModel = new File(ClientTestModels.class.getResource("client/c2j/query/service-2.json").getFile());
211+
File waitersModel = new File(ClientTestModels.class.getResource("client/c2j/query/waiters-2.json").getFile());
212+
File endpointRuleSetModel =
213+
new File(ClientTestModels.class.getResource("client/c2j/query/endpoint-rule-set-metric-values.json").getFile());
214+
File endpointTestsModel =
215+
new File(ClientTestModels.class.getResource("client/c2j/query/endpoint-tests-metric-values.json").getFile());
216+
217+
C2jModels models = C2jModels
218+
.builder()
219+
.serviceModel(getServiceModel(serviceModel))
220+
.waitersModel(getWaiters(waitersModel))
221+
.customizationConfig(CustomizationConfig.create())
222+
.endpointRuleSetModel(getEndpointRuleSet(endpointRuleSetModel))
223+
.endpointTestSuiteModel(getEndpointTestSuite(endpointTestsModel))
224+
.build();
225+
226+
return new IntermediateModelBuilder(models).build();
227+
}
228+
209229
public static IntermediateModel queryServiceModelsWithUriCache() {
210230
File serviceModel = new File(ClientTestModels.class.getResource("client/c2j/query/service-2.json").getFile());
211231
File customizationModel =

codegen/src/test/java/software/amazon/awssdk/codegen/poet/rules/EndpointProviderCompiledRulesClassSpecTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,11 @@ void endpointProviderClassWithUriCache() {
5151
new EndpointProviderSpec2(ClientTestModels.queryServiceModelsWithUriCache());
5252
assertThat(endpointProviderSpec, generatesTo("endpoint-provider-uri-cache-class.java"));
5353
}
54+
55+
@Test
56+
void endpointProviderClassWithMetricValues() {
57+
ClassSpec endpointProviderSpec =
58+
new EndpointProviderSpec2(ClientTestModels.queryServiceModelsWithUnknownEndpointMetricValues());
59+
assertThat(endpointProviderSpec, generatesTo("endpoint-provider-metric-values-class.java"));
60+
}
5461
}

codegen/src/test/java/software/amazon/awssdk/codegen/poet/rules/EndpointRulesClientTestSpecTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,10 @@ public void endpointProviderTestClassWithUnknownProperties() {
4040
ClassSpec endpointProviderSpec = new EndpointProviderTestSpec(ClientTestModels.queryServiceModelsWithUnknownEndpointProperties());
4141
assertThat(endpointProviderSpec, generatesTo("endpoint-rules-unknownproperty-test-class.java"));
4242
}
43+
44+
@Test
45+
public void endpointProviderTestClassWithMetricValues() {
46+
ClassSpec endpointProviderSpec = new EndpointProviderTestSpec(ClientTestModels.queryServiceModelsWithUnknownEndpointMetricValues());
47+
assertThat(endpointProviderSpec, generatesTo("endpoint-rules-metric-values-test-class.java"));
48+
}
4349
}

0 commit comments

Comments
 (0)