Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public static SmithyIntermediateModelPostprocessor create(CustomizationConfig co
processors.add(new UseLegacyEventGenerationSchemeProcessor());
processors.add(new EventStreamSharedEventProcessor(config.getDuplicateAndRenameSharedEvents()));
processors.add(new LongPollingOperationProcessor());
processors.add(new DefaultReadWriteTimeoutExemptionProcessor());
return new SmithyIntermediateModelPostprocessor(processors);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@
import java.io.IOException;
import software.amazon.awssdk.codegen.internal.Jackson;
import software.amazon.awssdk.codegen.model.rules.endpoints.EndpointTestSuiteModel;
import software.amazon.awssdk.codegen.model.service.EndpointBddModel;
import software.amazon.awssdk.codegen.model.service.EndpointRuleSetModel;
import software.amazon.smithy.model.node.Node;
import software.amazon.smithy.model.shapes.ServiceShape;
import software.amazon.smithy.rulesengine.traits.EndpointBddTrait;
import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait;
import software.amazon.smithy.rulesengine.traits.EndpointTestsTrait;

/**
* Reads the endpoint rule-set and endpoint tests from the service's Smithy traits, where C2J reads
* them from the {@code endpoint-rule-set.json} and {@code endpoint-tests.json} sidecar files.
* Reads the endpoint rule-set, endpoint BDD and endpoint tests from the service's Smithy traits, where C2J reads
* them from the {@code endpoint-rule-set.json}, {@code endpoint-bdd-1.json} and {@code endpoint-tests.json} sidecar
* files.
*
* <p>The trait content already uses the schema these POJOs expect, so this is a parse rather than a
* translation. It goes through the same {@link Jackson} mapper the sidecar path uses, so the two
* sources produce the same concrete types and tolerate unknown keys the same way.
*
* <p>The {@code endpointBdd} trait encodes the same rules as a binary decision diagram. Every
* service also carries {@code endpointRuleSet} in tree form, so it is ignored.
*/
final class AddSmithyEndpoints {

Expand All @@ -50,6 +50,16 @@ static EndpointRuleSetModel endpointRuleSet(ServiceShape service) {
.orElse(null);
}

/**
* Returns null when the service has no BDD trait; otherwise codegen generates the BDD endpoint provider, as C2J does
* from {@code endpoint-bdd-1.json}.
*/
static EndpointBddModel endpointBdd(ServiceShape service) {
return service.getTrait(EndpointBddTrait.class)
.map(trait -> parse(EndpointBddModel.class, trait.toNode(), service))
.orElse(null);
}

/**
* Returns null when the service has no endpoint-tests trait. {@code IntermediateModel} then
* substitutes an empty test suite. Uses {@code toNode()} rather than {@code getTestCases()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import software.amazon.awssdk.codegen.model.rules.endpoints.EndpointTestSuiteModel;
import software.amazon.awssdk.codegen.model.service.AuthType;
import software.amazon.awssdk.codegen.model.service.ClientContextParam;
import software.amazon.awssdk.codegen.model.service.EndpointBddModel;
import software.amazon.awssdk.codegen.model.service.EndpointRuleSetModel;
import software.amazon.awssdk.codegen.model.service.PaginatorDefinition;
import software.amazon.awssdk.codegen.naming.DefaultSmithyNamingStrategy;
Expand Down Expand Up @@ -81,6 +82,7 @@ public final class SmithyIntermediateModelBuilder {
private final ServiceIndex serviceIndex;
private final String protocol;
private final EndpointRuleSetModel endpointRuleSet;
private final EndpointBddModel endpointBdd;
private final EndpointTestSuiteModel endpointTestSuiteModel;
private final List<IntermediateModelShapeProcessor> shapeProcessors;

Expand All @@ -94,6 +96,7 @@ public SmithyIntermediateModelBuilder(SmithyModels models) {
this.serviceIndex = ServiceIndex.of(model);
this.protocol = ProtocolUtils.resolveProtocol(serviceIndex, service, customConfig);
this.endpointRuleSet = AddSmithyEndpoints.endpointRuleSet(service);
this.endpointBdd = AddSmithyEndpoints.endpointBdd(service);
this.endpointTestSuiteModel = AddSmithyEndpoints.endpointTests(service);
this.shapeProcessors = createShapeProcessors();
}
Expand Down Expand Up @@ -183,7 +186,7 @@ public IntermediateModel build() {
AddSmithyMetadata.constructMetadata(model, service, serviceIndex, namingStrategy, customConfig, protocol),
operations, shapes, customConfig, endpointOperation,
paginators, namingStrategy, Collections.emptyMap(),
endpointRuleSet, endpointTestSuiteModel, null, clientContextParams);
endpointRuleSet, endpointTestSuiteModel, endpointBdd, clientContextParams);

SmithyIntermediateModelPostprocessor.create(customConfig).postprocess(fullModel);

Expand All @@ -202,7 +205,7 @@ public IntermediateModel build() {
fullModel.getWaiters(),
endpointRuleSet,
endpointTestSuiteModel,
null,
endpointBdd,
clientContextParams);

linkMembersToShapes(trimmedModel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,32 @@ class SmithyIntermediateModelBuilderTest {
+ " ]\n"
+ "})\n";

/**
* The rule set above as Smithy compiles it to a BDD ({@code EndpointBddTrait.from(Cfg.from(ruleSet))}), with its
* own URL.
*/
private static final String BDD =
"@smithy.rules#clientContextParams(\n"
+ " Region: { type: \"string\", documentation: \"The region\" }\n"
+ ")\n"
+ "@smithy.rules#endpointBdd({\n"
+ " version: \"1.1\"\n"
+ " parameters: {\n"
+ " Region: { required: false, type: \"string\" }\n"
+ " }\n"
+ " conditions: []\n"
+ " results: [\n"
+ " {\n"
+ " conditions: []\n"
+ " endpoint: { url: \"https://bdd.example.amazonaws.com\", properties: {}, headers: {} }\n"
+ " type: \"endpoint\"\n"
+ " }\n"
+ " ]\n"
+ " root: 100000001\n"
+ " nodeCount: 1\n"
+ " nodes: \"/////wAAAAH/////\"\n"
+ "})\n";

private static final String TESTS =
"@smithy.rules#endpointTests({\n"
+ " version: \"1.0\"\n"
Expand Down Expand Up @@ -100,6 +126,23 @@ void endpointTraitsPresent_reachTheIntermediateModel() {
assertThat(model.getEndpointParameters()).containsOnlyKeys("Region");
assertThat(model.getEndpointRules()).hasSize(1);
assertThat(model.getEndpointTestSuiteModel().getTestCases()).hasSize(1);
assertThat(model.getEndpointBddModel()).isNull();
}

/**
* Without a rule set the parameters can only come from the BDD: the default rules declare more than
* {@code Region}.
*/
@Test
void endpointBddTraitPresent_reachesTheIntermediateModel() {
IntermediateModel model = build(BDD);

assertThat(model.getEndpointBddModel()).isNotNull();
assertThat(model.getEndpointBddModel().getRoot()).isEqualTo(100000001);
assertThat(model.getEndpointBddModel().getNodeCount()).isEqualTo(1);
assertThat(model.getEndpointBddModel().getNodes()).isEqualTo("/////wAAAAH/////");
assertThat(model.getEndpointBddModel().getResults()).hasSize(1);
assertThat(model.getEndpointParameters()).containsOnlyKeys("Region");
}

/**
Expand All @@ -115,6 +158,7 @@ void endpointTraitsAbsent_fallBackToTheDefaultRules() {
assertThat(model.getEndpointRules()).usingRecursiveComparison().isEqualTo(defaultRules.getRules());
assertThat(model.getEndpointParameters()).usingRecursiveComparison().isEqualTo(defaultRules.getParameters());
assertThat(model.getEndpointTestSuiteModel().getTestCases()).isEmpty();
assertThat(model.getEndpointBddModel()).isNull();
}

private static IntermediateModel buildPaginated(CustomizationConfig config) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ void longPollingOperation_isMarked() {
assertThat(model.getOperation("ReceiveMessage").isLongPolling()).isTrue();
}

@Test
void readWriteTimeoutExemptService_getsItsTimeout() {
IntermediateModel model = build(serviceWithSdkId("Neptune Graph"), CustomizationConfig.create());

assertThat(model.getMetadata().getDefaultReadWriteTimeoutMillis()).isEqualTo(900_000L);
}

@Test
void legacyEventGenerationScheme_twoMembersSharingAShape_fails() {
CustomizationConfig config = legacyEventConfig("EventOne", "EventTwo");
Expand Down Expand Up @@ -151,6 +158,21 @@ private static String sqsReceiveMessageService() {
+ "structure OpResponse {}\n";
}

private static String serviceWithSdkId(String sdkId) {
return "$version: \"2.0\"\nnamespace demo\n\n"
+ "use aws.api#service\n"
+ "use aws.auth#sigv4\n"
+ "use aws.protocols#restJson1\n"
+ "@service(sdkId: \"" + sdkId + "\", arnNamespace: \"demo\")\n"
+ "@sigv4(name: \"demo\")\n"
+ "@restJson1\n"
+ "service DemoService { version: \"2024-01-01\", operations: [Op] }\n"
+ "@http(method: \"POST\", uri: \"/op\")\n"
+ "operation Op { input: OpRequest, output: OpResponse }\n"
+ "structure OpRequest {}\n"
+ "structure OpResponse {}\n";
}

private static String eventStreamService() {
return REST_JSON_SERVICE
+ "service DemoService { version: \"2024-01-01\", operations: [Subscribe] }\n"
Expand Down
Loading