Skip to content

Commit ca3e85b

Browse files
committed
Correctly support endpoint expressions with multiple chained assigns
1 parent 7cb55e8 commit ca3e85b

8 files changed

Lines changed: 77 additions & 35 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "bugfix",
3+
"category": "AWS SDK for Java v2",
4+
"contributor": "",
5+
"description": "Correctly support endpoint expressions with multiple chained assigns."
6+
}

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,16 +117,21 @@ public RuleExpression visitBooleanAndExpression(BooleanAndExpression e) {
117117

118118
@Override
119119
public RuleExpression visitLetExpression(LetExpression e) {
120-
LetExpression expr = (LetExpression) super.visitLetExpression(e);
121-
expr.bindings().forEach((k, v) -> {
122-
RuleType type = v.type();
120+
// Process bindings sequentially so that each binding's type is registered before subsequent bindings are
121+
// visited. This allows later bindings to reference variables assigned by earlier bindings within the same
122+
// let expression (e.g., `isoArn = aws.parseArn(...)` followed by `isoArnType = getAttr(isoArn, ...)`).
123+
LetExpression.Builder builder = LetExpression.builder();
124+
e.bindings().forEach((k, v) -> {
125+
RuleExpression visited = v.accept(this);
126+
RuleType type = visited.type();
123127
if (type == null) {
124-
addError("Cannot find type for variable `%s`, expression: `%s`", k, v);
128+
addError("Cannot find type for variable `%s`, expression: `%s`", k, visited);
125129
} else {
126130
putLocal(k, type);
127131
}
132+
builder.putBinding(k, visited);
128133
});
129-
return expr;
134+
return builder.build();
130135
}
131136

132137
@Override

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/query/endpoint-rule-set.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,10 +416,20 @@
416416
}
417417
],
418418
"assign": "ParsedArn"
419+
},
420+
{
421+
"fn": "getAttr",
422+
"argv": [
423+
{
424+
"ref": "ParsedArn"
425+
},
426+
"resourceId[0]"
427+
],
428+
"assign": "ArnResourceId"
419429
}
420430
],
421431
"endpoint": {
422-
"url": "https://{endpointId}.query.{partitionResult#dualStackDnsSuffix}",
432+
"url": "https://{ArnResourceId}.{endpointId}.query.{partitionResult#dualStackDnsSuffix}",
423433
"properties": {
424434
"authSchemes": [
425435
{

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/rules/endpoint-provider-class.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,10 +374,16 @@ private static Rule endpointRule_11() {
374374
.builder()
375375
.fn(FnNode.builder().fn("aws.parseArn").argv(Arrays.asList(Expr.ref(Identifier.of("FirstArn"))))
376376
.build().validate()).result("ParsedArn").build())
377+
.addCondition(
378+
Condition
379+
.builder()
380+
.fn(FnNode.builder().fn("getAttr")
381+
.argv(Arrays.asList(Expr.ref(Identifier.of("ParsedArn")), Expr.of("resourceId[0]")))
382+
.build().validate()).result("ArnResourceId").build())
377383
.endpoint(
378384
EndpointResult
379385
.builder()
380-
.url(Expr.of("https://{endpointId}.query.{partitionResult#dualStackDnsSuffix}"))
386+
.url(Expr.of("https://{ArnResourceId}.{endpointId}.query.{partitionResult#dualStackDnsSuffix}"))
381387
.addProperty(
382388
Identifier.of("authSchemes"),
383389
Literal.fromTuple(Arrays.asList(Literal.fromRecord(MapUtils.of(Identifier.of("name"),

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/rules/endpoint-provider-know-prop-override-class.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,10 +369,16 @@ private static Rule endpointRule_11() {
369369
.builder()
370370
.fn(FnNode.builder().fn("aws.parseArn").argv(Arrays.asList(Expr.ref(Identifier.of("FirstArn"))))
371371
.build().validate()).result("ParsedArn").build())
372+
.addCondition(
373+
Condition
374+
.builder()
375+
.fn(FnNode.builder().fn("getAttr")
376+
.argv(Arrays.asList(Expr.ref(Identifier.of("ParsedArn")), Expr.of("resourceId[0]")))
377+
.build().validate()).result("ArnResourceId").build())
372378
.endpoint(
373379
EndpointResult
374380
.builder()
375-
.url(Expr.of("https://{endpointId}.query.{partitionResult#dualStackDnsSuffix}"))
381+
.url(Expr.of("https://{ArnResourceId}.{endpointId}.query.{partitionResult#dualStackDnsSuffix}"))
376382
.addProperty(
377383
Identifier.of("authSchemes"),
378384
Literal.fromTuple(Arrays.asList(Literal.fromRecord(MapUtils.of(Identifier.of("name"),

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/rules2/endpoint-provider-class.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,18 @@ private static RuleResult endpointRule1(QueryEndpointParams params, String regio
6464
if (firstArn != null) {
6565
RuleArn parsedArn = RulesFunctions.awsParseArn(firstArn);
6666
if (parsedArn != null) {
67-
return RuleResult.endpoint(Endpoint
68-
.builder()
69-
.endpointUrl(
70-
EndpointUrl.fromComponents("https",
71-
params.endpointId() + ".query." + partitionResult.dualStackDnsSuffix(), -1, ""))
72-
.putAttribute(
73-
AwsEndpointAttribute.AUTH_SCHEMES,
74-
Arrays.asList(SigV4aAuthScheme.builder().signingName("query")
75-
.signingRegionSet(Arrays.asList("*")).build())).build());
67+
String arnResourceId = RulesFunctions.listAccess(parsedArn.resourceId(), 0);
68+
if (arnResourceId != null) {
69+
return RuleResult.endpoint(Endpoint
70+
.builder()
71+
.endpointUrl(
72+
EndpointUrl.fromComponents("https", arnResourceId + "." + params.endpointId()
73+
+ ".query." + partitionResult.dualStackDnsSuffix(), -1, ""))
74+
.putAttribute(
75+
AwsEndpointAttribute.AUTH_SCHEMES,
76+
Arrays.asList(SigV4aAuthScheme.builder().signingName("query")
77+
.signingRegionSet(Arrays.asList("*")).build())).build());
78+
}
7679
}
7780
}
7881
}

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/rules2/endpoint-provider-know-prop-override-class.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,18 @@ private static RuleResult endpointRule1(QueryEndpointParams params, String regio
6464
if (firstArn != null) {
6565
RuleArn parsedArn = RulesFunctions.awsParseArn(firstArn);
6666
if (parsedArn != null) {
67-
return RuleResult.endpoint(Endpoint
68-
.builder()
69-
.endpointUrl(
70-
EndpointUrl.fromComponents("https",
71-
params.endpointId() + ".query." + partitionResult.dualStackDnsSuffix(), -1, ""))
72-
.putAttribute(
73-
AwsEndpointAttribute.AUTH_SCHEMES,
74-
Arrays.asList(SigV4aAuthScheme.builder().signingName("query")
75-
.signingRegionSet(Arrays.asList("*")).build())).build());
67+
String arnResourceId = RulesFunctions.listAccess(parsedArn.resourceId(), 0);
68+
if (arnResourceId != null) {
69+
return RuleResult.endpoint(Endpoint
70+
.builder()
71+
.endpointUrl(
72+
EndpointUrl.fromComponents("https", arnResourceId + "." + params.endpointId()
73+
+ ".query." + partitionResult.dualStackDnsSuffix(), -1, ""))
74+
.putAttribute(
75+
AwsEndpointAttribute.AUTH_SCHEMES,
76+
Arrays.asList(SigV4aAuthScheme.builder().signingName("query")
77+
.signingRegionSet(Arrays.asList("*")).build())).build());
78+
}
7679
}
7780
}
7881
}

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/rules2/endpoint-provider-uri-cache-class.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,18 @@ private static RuleResult endpointRule1(QueryEndpointParams params, String regio
6464
if (firstArn != null) {
6565
RuleArn parsedArn = RulesFunctions.awsParseArn(firstArn);
6666
if (parsedArn != null) {
67-
return RuleResult.endpoint(Endpoint
68-
.builder()
69-
.endpointUrl(
70-
EndpointUrl.fromComponents("https",
71-
params.endpointId() + ".query." + partitionResult.dualStackDnsSuffix(), -1, ""))
72-
.putAttribute(
73-
AwsEndpointAttribute.AUTH_SCHEMES,
74-
Arrays.asList(SigV4aAuthScheme.builder().signingName("query")
75-
.signingRegionSet(Arrays.asList("*")).build())).build());
67+
String arnResourceId = RulesFunctions.listAccess(parsedArn.resourceId(), 0);
68+
if (arnResourceId != null) {
69+
return RuleResult.endpoint(Endpoint
70+
.builder()
71+
.endpointUrl(
72+
EndpointUrl.fromComponents("https", arnResourceId + "." + params.endpointId()
73+
+ ".query." + partitionResult.dualStackDnsSuffix(), -1, ""))
74+
.putAttribute(
75+
AwsEndpointAttribute.AUTH_SCHEMES,
76+
Arrays.asList(SigV4aAuthScheme.builder().signingName("query")
77+
.signingRegionSet(Arrays.asList("*")).build())).build());
78+
}
7679
}
7780
}
7881
}

0 commit comments

Comments
 (0)