Skip to content

Commit db355d3

Browse files
authored
Add support for compiling endpoint rules (#4771)
* Add support for compiling endpoint rules * Address PR comments * Address more PR comments
1 parent 0a28ad2 commit db355d3

File tree

54 files changed

+7395
-444
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+7395
-444
lines changed

codegen/src/main/java/software/amazon/awssdk/codegen/emitters/tasks/EndpointProviderTasks.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import software.amazon.awssdk.codegen.poet.rules.EndpointResolverInterceptorSpec;
3535
import software.amazon.awssdk.codegen.poet.rules.EndpointRulesClientTestSpec;
3636
import software.amazon.awssdk.codegen.poet.rules.RequestEndpointInterceptorSpec;
37+
import software.amazon.awssdk.codegen.poet.rules2.EndpointProviderSpec2;
3738

3839
public final class EndpointProviderTasks extends BaseGeneratorTasks {
3940
private final GeneratorTaskParams generatorTaskParams;
@@ -48,7 +49,14 @@ protected List<GeneratorTask> createTasks() throws Exception {
4849
List<GeneratorTask> tasks = new ArrayList<>();
4950
tasks.add(generateInterface());
5051
tasks.add(generateParams());
51-
tasks.add(generateDefaultProvider());
52+
if (shouldGenerateCompiledEndpointRules()) {
53+
tasks.add(generateDefaultProvider2());
54+
tasks.add(new RulesEngineRuntimeGeneratorTask(generatorTaskParams));
55+
tasks.add(new RulesEngineRuntimeGeneratorTask2(generatorTaskParams));
56+
} else {
57+
tasks.add(generateDefaultProvider());
58+
tasks.add(new RulesEngineRuntimeGeneratorTask(generatorTaskParams));
59+
}
5260
tasks.addAll(generateInterceptors());
5361
if (shouldGenerateEndpointTests()) {
5462
tasks.add(generateProviderTests());
@@ -59,7 +67,6 @@ protected List<GeneratorTask> createTasks() throws Exception {
5967
if (hasClientContextParams()) {
6068
tasks.add(generateClientContextParams());
6169
}
62-
tasks.add(new RulesEngineRuntimeGeneratorTask(generatorTaskParams));
6370
tasks.add(generateDefaultPartitionsProvider());
6471
return tasks;
6572
}
@@ -76,11 +83,20 @@ private GeneratorTask generateDefaultProvider() {
7683
return new PoetGeneratorTask(endpointRulesInternalDir(), model.getFileHeader(), new EndpointProviderSpec(model));
7784
}
7885

86+
private GeneratorTask generateDefaultProvider2() {
87+
return new PoetGeneratorTask(endpointRulesInternalDir(), model.getFileHeader(), new EndpointProviderSpec2(model));
88+
}
89+
7990
private GeneratorTask generateDefaultPartitionsProvider() {
8091
return new PoetGeneratorTask(endpointRulesInternalDir(), model.getFileHeader(),
8192
new DefaultPartitionDataProviderSpec(model));
8293
}
8394

95+
private boolean shouldGenerateCompiledEndpointRules() {
96+
CustomizationConfig customizationConfig = generatorTaskParams.getModel().getCustomizationConfig();
97+
return customizationConfig.isEnableGenerateCompiledEndpointRules();
98+
}
99+
84100
private Collection<GeneratorTask> generateInterceptors() {
85101
return Arrays.asList(
86102
new PoetGeneratorTask(endpointRulesInternalDir(), model.getFileHeader(), new EndpointResolverInterceptorSpec(model)),
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+
*
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.
14+
*/
15+
16+
package software.amazon.awssdk.codegen.emitters.tasks;
17+
18+
import java.io.IOException;
19+
import java.io.InputStream;
20+
import java.io.UncheckedIOException;
21+
import java.util.ArrayList;
22+
import java.util.Collection;
23+
import java.util.List;
24+
import java.util.stream.Collectors;
25+
import software.amazon.awssdk.codegen.emitters.GeneratorTask;
26+
import software.amazon.awssdk.codegen.emitters.GeneratorTaskParams;
27+
import software.amazon.awssdk.codegen.emitters.SimpleGeneratorTask;
28+
import software.amazon.awssdk.codegen.poet.rules.EndpointRulesSpecUtils;
29+
import software.amazon.awssdk.utils.IoUtils;
30+
import software.amazon.awssdk.utils.StringUtils;
31+
import software.amazon.awssdk.utils.Validate;
32+
33+
public final class RulesEngineRuntimeGeneratorTask2 extends BaseGeneratorTasks {
34+
private final String engineInternalClassDir;
35+
private final String engineInternalResourcesDir;
36+
private final String engineInternalPackageName;
37+
private final String fileHeader;
38+
private final EndpointRulesSpecUtils endpointRulesSpecUtils;
39+
40+
public RulesEngineRuntimeGeneratorTask2(GeneratorTaskParams generatorTaskParams) {
41+
super(generatorTaskParams);
42+
this.engineInternalClassDir = generatorTaskParams.getPathProvider().getEndpointRulesInternalDirectory();
43+
this.engineInternalResourcesDir = generatorTaskParams.getPathProvider().getEndpointRulesInternalResourcesDirectory();
44+
this.engineInternalPackageName = generatorTaskParams.getModel().getMetadata().getFullInternalEndpointRulesPackageName();
45+
this.fileHeader = generatorTaskParams.getModel().getFileHeader();
46+
this.endpointRulesSpecUtils = new EndpointRulesSpecUtils(generatorTaskParams.getModel());
47+
}
48+
49+
@Override
50+
protected List<GeneratorTask> createTasks() throws Exception {
51+
List<GeneratorTask> copyTasks = new ArrayList<>();
52+
List<String> rulesEngineFiles = endpointRulesSpecUtils.rulesEngineResourceFiles2();
53+
for (String path : rulesEngineJavaFilePaths(rulesEngineFiles)) {
54+
String newFileName = computeNewName(path);
55+
copyTasks.add(new SimpleGeneratorTask(engineInternalClassDir,
56+
newFileName,
57+
fileHeader,
58+
() -> rulesEngineFileContent("/" + path)));
59+
}
60+
61+
return copyTasks;
62+
}
63+
64+
private List<String> rulesEngineJavaFilePaths(Collection<String> runtimeEngineFiles) {
65+
return runtimeEngineFiles.stream()
66+
.filter(e -> e.endsWith(".java.resource"))
67+
.collect(Collectors.toList());
68+
}
69+
70+
private String rulesEngineFileContent(String path) {
71+
return "package " + engineInternalPackageName + ";\n" +
72+
"\n"
73+
+ loadResourceAsString(path);
74+
}
75+
76+
private String loadResourceAsString(String path) {
77+
try {
78+
return IoUtils.toUtf8String(loadResource(path));
79+
} catch (IOException e) {
80+
throw new UncheckedIOException(e);
81+
}
82+
}
83+
84+
private InputStream loadResource(String name) {
85+
InputStream resourceAsStream = RulesEngineRuntimeGeneratorTask2.class.getResourceAsStream(name);
86+
Validate.notNull(resourceAsStream, "Failed to load resource from %s", name);
87+
return resourceAsStream;
88+
}
89+
90+
private String computeNewName(String path) {
91+
String[] pathComponents = path.split("/");
92+
return StringUtils.replace(pathComponents[pathComponents.length - 1], ".resource", "");
93+
}
94+
}

codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/CustomizationConfig.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,11 @@ public class CustomizationConfig {
295295

296296
private boolean s3ExpressAuthSupport;
297297

298+
/**
299+
* Set to true to enable compiled endpoint rules. Currently defaults to false.
300+
*/
301+
private boolean enableGenerateCompiledEndpointRules = false;
302+
298303
/**
299304
* Customization related to auth scheme derived from endpoints.
300305
*/
@@ -708,6 +713,14 @@ public void setUseS3ExpressSessionAuth(boolean useS3ExpressSessionAuth) {
708713
this.useS3ExpressSessionAuth = useS3ExpressSessionAuth;
709714
}
710715

716+
public boolean isEnableGenerateCompiledEndpointRules() {
717+
return enableGenerateCompiledEndpointRules;
718+
}
719+
720+
public void setEnableGenerateCompiledEndpointRules(boolean enableGenerateCompiledEndpointRules) {
721+
this.enableGenerateCompiledEndpointRules = enableGenerateCompiledEndpointRules;
722+
}
723+
711724
public Map<String, String> getSkipEndpointTests() {
712725
return skipEndpointTests;
713726
}

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,19 @@ public List<String> rulesEngineResourceFiles() {
198198
try (JarFile jarFile = new JarFile(currentJarUrl.getFile())) {
199199
return jarFile.stream()
200200
.map(ZipEntry::getName)
201-
.filter(e -> e.startsWith("software/amazon/awssdk/codegen/rules"))
201+
.filter(e -> e.startsWith("software/amazon/awssdk/codegen/rules/"))
202+
.collect(Collectors.toList());
203+
} catch (IOException e) {
204+
throw new UncheckedIOException(e);
205+
}
206+
}
207+
208+
public List<String> rulesEngineResourceFiles2() {
209+
URL currentJarUrl = EndpointRulesSpecUtils.class.getProtectionDomain().getCodeSource().getLocation();
210+
try (JarFile jarFile = new JarFile(currentJarUrl.getFile())) {
211+
return jarFile.stream()
212+
.map(ZipEntry::getName)
213+
.filter(e -> e.startsWith("software/amazon/awssdk/codegen/rules2/"))
202214
.collect(Collectors.toList());
203215
} catch (IOException e) {
204216
throw new UncheckedIOException(e);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 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.
14+
*/
15+
16+
package software.amazon.awssdk.codegen.poet.rules2;
17+
18+
/**
19+
* Assigns an identifier to each rule then we use as a name for the generated method.
20+
*/
21+
public final class AssignIdentifierVisitor extends RewriteRuleExpressionVisitor {
22+
private int index;
23+
24+
@Override
25+
public RuleExpression visitRuleSetExpression(RuleSetExpression expr) {
26+
String ruleId = "endpointRule" + index;
27+
expr = expr.toBuilder().ruleId(ruleId).build();
28+
index += 1;
29+
return super.visitRuleSetExpression(expr);
30+
}
31+
}

0 commit comments

Comments
 (0)