Skip to content

Commit fb7c89c

Browse files
Steven Yuankuhe
authored andcommitted
feat(codegen): refactor builtin plugins
1 parent e5b8295 commit fb7c89c

File tree

4 files changed

+170
-85
lines changed

4 files changed

+170
-85
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,47 @@
11
/*
2-
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License").
5-
* You may not use this file except in compliance with the License.
6-
* A copy of the License is located at
7-
*
8-
* http://aws.amazon.com/apache2.0
9-
*
10-
* or in the "license" file accompanying this file. This file is distributed
11-
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12-
* express or implied. See the License for the specific language governing
13-
* permissions and limitations under the License.
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
144
*/
155

166
package software.amazon.smithy.aws.typescript.codegen;
177

188
import static software.amazon.smithy.aws.typescript.codegen.AwsTraitsUtils.isAwsService;
19-
import static software.amazon.smithy.aws.typescript.codegen.AwsTraitsUtils.isEndpointsV2Service;
209
import static software.amazon.smithy.aws.typescript.codegen.AwsTraitsUtils.isSigV4Service;
2110
import static software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin.Convention.HAS_CONFIG;
2211
import static software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin.Convention.HAS_MIDDLEWARE;
2312

2413
import java.util.List;
25-
import java.util.Set;
26-
import software.amazon.smithy.aws.traits.ServiceTrait;
27-
import software.amazon.smithy.model.Model;
28-
import software.amazon.smithy.model.knowledge.OperationIndex;
29-
import software.amazon.smithy.model.shapes.OperationShape;
30-
import software.amazon.smithy.model.shapes.Shape;
3114
import software.amazon.smithy.typescript.codegen.TypeScriptDependency;
3215
import software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin;
3316
import software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration;
34-
import software.amazon.smithy.utils.ListUtils;
35-
import software.amazon.smithy.utils.SetUtils;
3617
import software.amazon.smithy.utils.SmithyInternalApi;
3718

3819
/**
3920
* Adds all built-in runtime client plugins to clients.
21+
*
22+
* Note that order is significant because configurations might rely on previously resolved values.
4023
*/
4124
@SmithyInternalApi
4225
public class AddBuiltinPlugins implements TypeScriptIntegration {
43-
private static final Set<String> ROUTE_53_ID_MEMBERS = SetUtils.of("DelegationSetId", "HostedZoneId", "Id");
26+
@Override
27+
public List<String> runAfter() {
28+
return List.of(
29+
software.amazon.smithy.typescript.codegen.integration.AddBuiltinPlugins.class.getCanonicalName());
30+
}
4431

4532
@Override
4633
public List<RuntimeClientPlugin> getClientPlugins() {
47-
// Note that order is significant because configurations might
48-
// rely on previously resolved values.
49-
return ListUtils.of(
34+
return List.of(
35+
// AWS or SigV4
5036
RuntimeClientPlugin.builder()
5137
.withConventions(TypeScriptDependency.CONFIG_RESOLVER.dependency, "Region", HAS_CONFIG)
5238
.servicePredicate((m, s) -> isAwsService(s) || isSigV4Service(s))
5339
.build(),
54-
// Only one of Endpoints or CustomEndpoints (provided by Smithy-TypeScript) should be used
55-
RuntimeClientPlugin.builder()
56-
.withConventions(
57-
TypeScriptDependency.CONFIG_RESOLVER.dependency, "Endpoints", HAS_CONFIG)
58-
.servicePredicate((m, s) -> isAwsService(s) && !isEndpointsV2Service(s))
59-
.build(),
60-
RuntimeClientPlugin.builder()
61-
.withConventions(
62-
TypeScriptDependency.MIDDLEWARE_ENDPOINTS_V2.dependency, "Endpoint", HAS_CONFIG)
63-
.servicePredicate((m, s) -> isAwsService(s) && isEndpointsV2Service(s))
64-
.build(),
65-
RuntimeClientPlugin.builder()
66-
.withConventions(AwsDependency.ACCEPT_HEADER.dependency, "AcceptHeader",
67-
HAS_MIDDLEWARE)
68-
.servicePredicate((m, s) -> testServiceId(s, "API Gateway"))
69-
.build(),
70-
RuntimeClientPlugin.builder()
71-
.withConventions(AwsDependency.GLACIER_MIDDLEWARE.dependency,
72-
"Glacier", HAS_MIDDLEWARE)
73-
.servicePredicate((m, s) -> testServiceId(s, "Glacier"))
74-
.build(),
75-
RuntimeClientPlugin.builder()
76-
.withConventions(AwsDependency.EC2_MIDDLEWARE.dependency,
77-
"CopySnapshotPresignedUrl", HAS_MIDDLEWARE)
78-
.operationPredicate((m, s, o) -> o.getId().getName(s).equals("CopySnapshot")
79-
&& testServiceId(s, "EC2"))
80-
.build(),
81-
RuntimeClientPlugin.builder()
82-
.withConventions(AwsDependency.MACHINELEARNING_MIDDLEWARE.dependency, "PredictEndpoint",
83-
HAS_MIDDLEWARE)
84-
.operationPredicate((m, s, o) -> o.getId().getName(s).equals("Predict")
85-
&& testServiceId(s, "Machine Learning"))
86-
.build(),
87-
RuntimeClientPlugin.builder()
88-
.withConventions(AwsDependency.ROUTE53_MIDDLEWARE.dependency,
89-
"ChangeResourceRecordSets", HAS_MIDDLEWARE)
90-
.operationPredicate((m, s, o) -> o.getId().getName(s).equals("ChangeResourceRecordSets")
91-
&& testServiceId(s, "Route 53"))
92-
.build(),
93-
RuntimeClientPlugin.builder()
94-
.withConventions(AwsDependency.ROUTE53_MIDDLEWARE.dependency, "IdNormalizer",
95-
HAS_MIDDLEWARE)
96-
.operationPredicate((m, s, o) -> testInputContainsMember(m, o, ROUTE_53_ID_MEMBERS)
97-
&& testServiceId(s, "Route 53"))
98-
.build(),
40+
// Can be in smithy-typescript, but the NPM package is in @aws-sdk
9941
RuntimeClientPlugin.builder()
10042
.withConventions(AwsDependency.MIDDLEWARE_HOST_HEADER.dependency, "HostHeader")
10143
.build(),
44+
// Should be in smithy-typescript, but the NPM package is in @aws-sdk
10245
RuntimeClientPlugin.builder()
10346
.withConventions(AwsDependency.MIDDLEWARE_LOGGER.dependency, "Logger", HAS_MIDDLEWARE)
10447
.build(),
@@ -108,19 +51,4 @@ && testServiceId(s, "Route 53"))
10851
.build()
10952
);
11053
}
111-
112-
private static boolean testInputContainsMember(
113-
Model model,
114-
OperationShape operationShape,
115-
Set<String> expectedMemberNames
116-
) {
117-
OperationIndex operationIndex = OperationIndex.of(model);
118-
return operationIndex.getInput(operationShape)
119-
.filter(input -> input.getMemberNames().stream().anyMatch(expectedMemberNames::contains))
120-
.isPresent();
121-
}
122-
123-
private static boolean testServiceId(Shape serviceShape, String expectedId) {
124-
return serviceShape.getTrait(ServiceTrait.class).map(ServiceTrait::getSdkId).orElse("").equals(expectedId);
125-
}
12654
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package software.amazon.smithy.aws.typescript.codegen;
7+
8+
import static software.amazon.smithy.aws.typescript.codegen.AwsTraitsUtils.isAwsService;
9+
import static software.amazon.smithy.aws.typescript.codegen.AwsTraitsUtils.isEndpointsV2Service;
10+
import static software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin.Convention.HAS_CONFIG;
11+
12+
import java.util.List;
13+
import software.amazon.smithy.typescript.codegen.TypeScriptDependency;
14+
import software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin;
15+
import software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration;
16+
import software.amazon.smithy.utils.SmithyInternalApi;
17+
18+
/**
19+
* Adds all built-in runtime client plugins to clients.
20+
*/
21+
@SmithyInternalApi
22+
public class AddEndpointsPlugin implements TypeScriptIntegration {
23+
@Override
24+
public List<String> runAfter() {
25+
return List.of(AddBuiltinPlugins.class.getCanonicalName());
26+
}
27+
28+
@Override
29+
public List<RuntimeClientPlugin> getClientPlugins() {
30+
return List.of(
31+
// AWS but not EP 2.0
32+
RuntimeClientPlugin.builder()
33+
.withConventions(
34+
TypeScriptDependency.CONFIG_RESOLVER.dependency, "Endpoints", HAS_CONFIG)
35+
.servicePredicate((m, s) -> isAwsService(s) && !isEndpointsV2Service(s))
36+
.build(),
37+
// AWS and EP 2.0
38+
RuntimeClientPlugin.builder()
39+
.withConventions(
40+
TypeScriptDependency.MIDDLEWARE_ENDPOINTS_V2.dependency, "Endpoint", HAS_CONFIG)
41+
.servicePredicate((m, s) -> isAwsService(s) && isEndpointsV2Service(s))
42+
.build()
43+
);
44+
}
45+
46+
@Override
47+
public void mutateClientPlugins(List<RuntimeClientPlugin> plugins) {
48+
// TODO
49+
RuntimeClientPlugin genericCustomEndpoints = plugins.stream()
50+
.filter(p -> p.getResolveFunction()
51+
.map(r -> r.getAlias().equals("resolveCustomEndpointsConfig"))
52+
.orElse(false))
53+
.findAny()
54+
.orElseThrow(() -> new IllegalStateException("Expected generic CustomEndpoints config"));
55+
int index = plugins.indexOf(genericCustomEndpoints);
56+
RuntimeClientPlugin modifiedCustomEndpoints = genericCustomEndpoints.toBuilder()
57+
.servicePredicate((m, s) -> !isAwsService(s) && !isEndpointsV2Service(s))
58+
.build();
59+
plugins.set(index, modifiedCustomEndpoints);
60+
}
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package software.amazon.smithy.aws.typescript.codegen;
7+
8+
import static software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin.Convention.HAS_MIDDLEWARE;
9+
10+
import java.util.List;
11+
import java.util.Set;
12+
import software.amazon.smithy.aws.traits.ServiceTrait;
13+
import software.amazon.smithy.model.Model;
14+
import software.amazon.smithy.model.knowledge.OperationIndex;
15+
import software.amazon.smithy.model.shapes.OperationShape;
16+
import software.amazon.smithy.model.shapes.Shape;
17+
import software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin;
18+
import software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration;
19+
import software.amazon.smithy.utils.SmithyInternalApi;
20+
21+
/**
22+
* Adds service customization runtime client plugins.
23+
*/
24+
@SmithyInternalApi
25+
public class AddServiceCustomizationPlugins implements TypeScriptIntegration {
26+
private static final Set<String> ROUTE_53_ID_MEMBERS = Set.of("DelegationSetId", "HostedZoneId", "Id");
27+
28+
@Override
29+
public List<String> runAfter() {
30+
return List.of(
31+
AddBuiltinPlugins.class.getCanonicalName(),
32+
AddEndpointsPlugin.class.getCanonicalName());
33+
}
34+
35+
@Override
36+
public List<RuntimeClientPlugin> getClientPlugins() {
37+
return List.of(
38+
// API Gateway
39+
RuntimeClientPlugin.builder()
40+
.withConventions(AwsDependency.ACCEPT_HEADER.dependency, "AcceptHeader",
41+
HAS_MIDDLEWARE)
42+
.servicePredicate((m, s) -> testServiceId(s, "API Gateway"))
43+
.build(),
44+
// Glacier
45+
RuntimeClientPlugin.builder()
46+
.withConventions(AwsDependency.GLACIER_MIDDLEWARE.dependency,
47+
"Glacier", HAS_MIDDLEWARE)
48+
.servicePredicate((m, s) -> testServiceId(s, "Glacier"))
49+
.build(),
50+
// EC2
51+
RuntimeClientPlugin.builder()
52+
.withConventions(AwsDependency.EC2_MIDDLEWARE.dependency,
53+
"CopySnapshotPresignedUrl", HAS_MIDDLEWARE)
54+
.operationPredicate((m, s, o) -> o.getId().getName(s).equals("CopySnapshot")
55+
&& testServiceId(s, "EC2"))
56+
.build(),
57+
// Machine Learning
58+
RuntimeClientPlugin.builder()
59+
.withConventions(AwsDependency.MACHINELEARNING_MIDDLEWARE.dependency, "PredictEndpoint",
60+
HAS_MIDDLEWARE)
61+
.operationPredicate((m, s, o) -> o.getId().getName(s).equals("Predict")
62+
&& testServiceId(s, "Machine Learning"))
63+
.build(),
64+
// Route 53
65+
RuntimeClientPlugin.builder()
66+
.withConventions(AwsDependency.ROUTE53_MIDDLEWARE.dependency,
67+
"ChangeResourceRecordSets", HAS_MIDDLEWARE)
68+
.operationPredicate((m, s, o) -> o.getId().getName(s).equals("ChangeResourceRecordSets")
69+
&& testServiceId(s, "Route 53"))
70+
.build(),
71+
RuntimeClientPlugin.builder()
72+
.withConventions(AwsDependency.ROUTE53_MIDDLEWARE.dependency, "IdNormalizer",
73+
HAS_MIDDLEWARE)
74+
.operationPredicate((m, s, o) -> testInputContainsMember(m, o, ROUTE_53_ID_MEMBERS)
75+
&& testServiceId(s, "Route 53"))
76+
.build()
77+
);
78+
}
79+
80+
private static boolean testInputContainsMember(
81+
Model model,
82+
OperationShape operationShape,
83+
Set<String> expectedMemberNames
84+
) {
85+
OperationIndex operationIndex = OperationIndex.of(model);
86+
return operationIndex.getInput(operationShape)
87+
.filter(input -> input.getMemberNames().stream().anyMatch(expectedMemberNames::contains))
88+
.isPresent();
89+
}
90+
91+
private static boolean testServiceId(Shape serviceShape, String expectedId) {
92+
return serviceShape.getTrait(ServiceTrait.class).map(ServiceTrait::getSdkId).orElse("").equals(expectedId);
93+
}
94+
}

codegen/smithy-aws-typescript-codegen/src/main/resources/META-INF/services/software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ software.amazon.smithy.aws.typescript.codegen.AddEndpointsV2ParameterNameMap
22
software.amazon.smithy.aws.typescript.codegen.AddAwsRuntimeConfig
33
software.amazon.smithy.aws.typescript.codegen.AddAccountIdEndpointModeRuntimeConfig
44
software.amazon.smithy.aws.typescript.codegen.AddBuiltinPlugins
5+
software.amazon.smithy.aws.typescript.codegen.AddEndpointsPlugin
6+
software.amazon.smithy.aws.typescript.codegen.AddServiceCustomizationPlugins
57
software.amazon.smithy.aws.typescript.codegen.AddAwsAuthPlugin
68
software.amazon.smithy.aws.typescript.codegen.AddTokenAuthPlugin
79
software.amazon.smithy.aws.typescript.codegen.AddProtocols

0 commit comments

Comments
 (0)