Skip to content

Commit 7d92528

Browse files
committed
Wiring up configuration
1 parent 56f5207 commit 7d92528

File tree

19 files changed

+969
-17
lines changed

19 files changed

+969
-17
lines changed

codegen-lite-maven-plugin/src/main/java/software/amazon/awssdk/codegen/lite/maven/plugin/DefaultsModeGenerationMojo.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import software.amazon.awssdk.codegen.lite.CodeGenerator;
2626
import software.amazon.awssdk.codegen.lite.defaultsmode.DefaultConfiguration;
2727
import software.amazon.awssdk.codegen.lite.defaultsmode.DefaultsLoader;
28+
import software.amazon.awssdk.codegen.lite.defaultsmode.DefaultsModeConfigurationGenerator;
2829
import software.amazon.awssdk.codegen.lite.defaultsmode.DefaultsModeGenerator;
2930

3031
/**
@@ -34,6 +35,7 @@
3435
public class DefaultsModeGenerationMojo extends AbstractMojo {
3536

3637
private static final String DEFAULTS_MODE_BASE = "software.amazon.awssdk.defaultsmode";
38+
private static final String DEFAULTS_MODE_CONFIGURATION_BASE = "software.amazon.awssdk.internal.defaultsmode";
3739

3840
@Parameter(property = "outputDirectory", defaultValue = "${project.build.directory}")
3941
private String outputDirectory;
@@ -52,6 +54,7 @@ public void execute() {
5254
DefaultConfiguration configuration = DefaultsLoader.load(defaultConfigurationFile);
5355

5456
generateDefaultsModeClass(baseSourcesDirectory, configuration);
57+
generateDefaultsModeConfiguartionClass(baseSourcesDirectory, configuration);
5558

5659
project.addCompileSourceRoot(baseSourcesDirectory.toFile().getAbsolutePath());
5760
project.addTestCompileSourceRoot(testsDirectory.toFile().getAbsolutePath());
@@ -62,4 +65,10 @@ public void generateDefaultsModeClass(Path baseSourcesDirectory, DefaultConfigur
6265
new CodeGenerator(sourcesDirectory.toString(), new DefaultsModeGenerator(DEFAULTS_MODE_BASE, configuration)).generate();
6366
}
6467

68+
public void generateDefaultsModeConfiguartionClass(Path baseSourcesDirectory, DefaultConfiguration configuration) {
69+
Path sourcesDirectory = baseSourcesDirectory.resolve(DEFAULTS_MODE_CONFIGURATION_BASE.replace(".", "/"));
70+
new CodeGenerator(sourcesDirectory.toString(), new DefaultsModeConfigurationGenerator(DEFAULTS_MODE_CONFIGURATION_BASE,
71+
DEFAULTS_MODE_BASE,
72+
configuration)).generate();
73+
}
6574
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
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.lite.defaultsmode;
17+
18+
import static javax.lang.model.element.Modifier.FINAL;
19+
import static javax.lang.model.element.Modifier.PRIVATE;
20+
import static javax.lang.model.element.Modifier.PUBLIC;
21+
import static javax.lang.model.element.Modifier.STATIC;
22+
23+
import com.squareup.javapoet.AnnotationSpec;
24+
import com.squareup.javapoet.ClassName;
25+
import com.squareup.javapoet.CodeBlock;
26+
import com.squareup.javapoet.FieldSpec;
27+
import com.squareup.javapoet.MethodSpec;
28+
import com.squareup.javapoet.TypeSpec;
29+
import java.util.HashMap;
30+
import java.util.Locale;
31+
import java.util.Map;
32+
import java.util.Set;
33+
import javax.lang.model.element.Modifier;
34+
import software.amazon.awssdk.annotations.Generated;
35+
import software.amazon.awssdk.annotations.SdkInternalApi;
36+
import software.amazon.awssdk.codegen.lite.PoetClass;
37+
import software.amazon.awssdk.utils.AttributeMap;
38+
39+
/**
40+
* Generates DefaultsModeConfiguration class that contains default options for each mode
41+
*/
42+
public class DefaultsModeConfigurationGenerator implements PoetClass {
43+
44+
private final String basePackage;
45+
private final String defaultsModeBase;
46+
private final DefaultConfiguration configuration;
47+
48+
private static final Map<String, OptionMetadata> CONFIGURATION_MAPPING = new HashMap<>();
49+
50+
private static final Map<String, OptionMetadata> HTTP_CONFIGURATION_MAPPING = new HashMap<>();
51+
52+
static {
53+
HTTP_CONFIGURATION_MAPPING.put("connectTimeoutInMillis",
54+
new OptionMetadata(ClassName.get("java.time", "Duration"),
55+
ClassName.get("software.amazon.awssdk.http",
56+
"SdkHttpConfigurationOption", "CONNECTION_TIMEOUT")));
57+
CONFIGURATION_MAPPING.put("retryMode", new OptionMetadata(ClassName.get("software.amazon.awssdk.core.retry", "RetryMode"
58+
), ClassName.get("software.amazon.awssdk.core.client.config","SdkClientOption", "DEFAULT_RETRY_MODE")));
59+
}
60+
61+
public DefaultsModeConfigurationGenerator(String basePackage, String defaultsModeBase, DefaultConfiguration configuration) {
62+
this.basePackage = basePackage;
63+
this.configuration = configuration;
64+
this.defaultsModeBase = defaultsModeBase;
65+
}
66+
67+
@Override
68+
public TypeSpec poetClass() {
69+
TypeSpec.Builder builder = TypeSpec.classBuilder(className())
70+
.addModifiers(PUBLIC, FINAL)
71+
.addJavadoc(documentation())
72+
.addAnnotation(SdkInternalApi.class)
73+
.addAnnotation(AnnotationSpec.builder(Generated.class)
74+
.addMember("value",
75+
"$S",
76+
"software.amazon.awssdk:codegen")
77+
.build())
78+
.addMethod(defaultHttpConfigMethod(configuration.modeDefaults().keySet()))
79+
.addMethod(defaultSdkConfigMethod(configuration.modeDefaults().keySet()))
80+
.addMethod(createConstructor());
81+
82+
83+
configuration.modeDefaults().entrySet().forEach(entry -> {
84+
builder.addField(addDefaultsFieldForMode(entry));
85+
builder.addField(addHttpDefaultsFieldForMode(entry));
86+
});
87+
88+
addDefaultsFieldForLegacy(builder, "LEGACY_DEFAULTS");
89+
addDefaultsFieldForLegacy(builder, "LEGACY_HTTP_DEFAULTS");
90+
return builder.build();
91+
}
92+
93+
@Override
94+
public ClassName className() {
95+
return ClassName.get(basePackage, "DefaultsModeConfiguration");
96+
}
97+
98+
private FieldSpec addDefaultsFieldForMode(Map.Entry<String, Map<String, String>> modeEntry) {
99+
String mode = modeEntry.getKey();
100+
String fieldName = sanitizeMode(mode) + "_DEFAULTS";
101+
102+
103+
CodeBlock.Builder attributeBuilder = CodeBlock.builder()
104+
.add("$T.builder()", AttributeMap.class);
105+
106+
modeEntry.getValue()
107+
.entrySet()
108+
.stream()
109+
.filter(e -> CONFIGURATION_MAPPING.containsKey(e.getKey()))
110+
.forEach(e -> attributeMapBuilder(e.getKey(), e.getValue(), attributeBuilder));
111+
112+
113+
FieldSpec.Builder fieldSpec = FieldSpec.builder(AttributeMap.class, fieldName, PRIVATE, STATIC, FINAL)
114+
.initializer(attributeBuilder
115+
.add(".build()")
116+
.build());
117+
118+
119+
return fieldSpec.build();
120+
}
121+
122+
private void addDefaultsFieldForLegacy(TypeSpec.Builder builder, String name) {
123+
FieldSpec field = FieldSpec.builder(AttributeMap.class, name, PRIVATE, STATIC, FINAL)
124+
.initializer("$T.empty()", AttributeMap.class).build();
125+
builder.addField(field);
126+
}
127+
128+
private void attributeMapBuilder(String option, String value, CodeBlock.Builder attributeBuilder) {
129+
OptionMetadata optionMetadata = CONFIGURATION_MAPPING.get(option);
130+
switch (option) {
131+
case "retryMode":
132+
attributeBuilder.add(".put($T, $T.$N)", optionMetadata.attribute, optionMetadata.type, value.toUpperCase(Locale.US));
133+
break;
134+
default:
135+
throw new IllegalStateException("Unsupported option " + option);
136+
}
137+
}
138+
139+
private void httpAttributeMapBuilder(String option, String value, CodeBlock.Builder attributeBuilder) {
140+
OptionMetadata optionMetadata = HTTP_CONFIGURATION_MAPPING.get(option);
141+
switch (option) {
142+
case "connectTimeoutInMillis":
143+
attributeBuilder.add(".put($T, $T.ofMillis($N))", optionMetadata.attribute, optionMetadata.type, value);
144+
break;
145+
default:
146+
throw new IllegalStateException("Unsupported option " + option);
147+
}
148+
}
149+
150+
private FieldSpec addHttpDefaultsFieldForMode(Map.Entry<String, Map<String, String>> modeEntry) {
151+
String mode = modeEntry.getKey();
152+
String fieldName = sanitizeMode(mode) + "_HTTP_DEFAULTS";
153+
154+
CodeBlock.Builder attributeBuilder = CodeBlock.builder()
155+
.add("$T.builder()", AttributeMap.class);
156+
157+
modeEntry.getValue()
158+
.entrySet()
159+
.stream()
160+
.filter(e -> HTTP_CONFIGURATION_MAPPING.containsKey(e.getKey()))
161+
.forEach(e -> httpAttributeMapBuilder(e.getKey(), e.getValue(), attributeBuilder));
162+
163+
FieldSpec.Builder fieldSpec = FieldSpec.builder(AttributeMap.class, fieldName, PRIVATE, STATIC, FINAL)
164+
.initializer(attributeBuilder
165+
.add(".build()")
166+
.build());
167+
168+
return fieldSpec.build();
169+
}
170+
171+
private String sanitizeMode(String str) {
172+
return str.replace('-', '_').toUpperCase(Locale.US);
173+
}
174+
175+
private CodeBlock documentation() {
176+
CodeBlock.Builder builder = CodeBlock.builder()
177+
.add("Contains a collection of default configuration options for each "
178+
+ "DefaultsMode");
179+
180+
return builder.build();
181+
}
182+
183+
184+
private MethodSpec defaultHttpConfigMethod(Set<String> modes) {
185+
String nameSuffix = "_HTTP_DEFAULTS";
186+
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("defaultHttpConfig")
187+
.returns(AttributeMap.class)
188+
.addModifiers(PUBLIC, STATIC)
189+
.addJavadoc("Return the default HTTP config options for a given defaults "
190+
+ "mode")
191+
.addParameter(defaultsModeClassName(), "mode")
192+
.beginControlFlow("switch (mode)");
193+
194+
195+
addSwitchCaseForEachMode(modes, nameSuffix, methodBuilder);
196+
197+
addLegacyCase(methodBuilder, "LEGACY" + nameSuffix);
198+
199+
return methodBuilder
200+
.addStatement("default: throw new IllegalArgumentException($S + $N)", "Unsupported mode: ", "mode")
201+
.endControlFlow()
202+
.build();
203+
}
204+
205+
private void addSwitchCaseForEachMode(Set<String> modes, String nameSuffix, MethodSpec.Builder methodBuilder) {
206+
modes.forEach(m -> {
207+
String mode = sanitizeMode(m);
208+
methodBuilder.addCode("case $N:", mode);
209+
methodBuilder.addStatement("return $N", mode + nameSuffix);
210+
});
211+
}
212+
213+
private MethodSpec defaultSdkConfigMethod(Set<String> modes) {
214+
String nameSuffix = "_DEFAULTS";
215+
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("defaultConfig")
216+
.returns(AttributeMap.class)
217+
.addModifiers(PUBLIC, STATIC)
218+
.addJavadoc("Return the default SDK config options for a given defaults "
219+
+ "mode")
220+
.addParameter(defaultsModeClassName(), "mode")
221+
.beginControlFlow("switch (mode)");
222+
223+
224+
addSwitchCaseForEachMode(modes, nameSuffix, methodBuilder);
225+
addLegacyCase(methodBuilder, "LEGACY" + nameSuffix);
226+
227+
return methodBuilder
228+
.addStatement("default: throw new IllegalArgumentException($S + $N)", "Unsupported mode: ", "mode")
229+
.endControlFlow()
230+
.build();
231+
}
232+
233+
private void addLegacyCase(MethodSpec.Builder methodBuilder, String name) {
234+
methodBuilder.addCode("case LEGACY:");
235+
methodBuilder.addStatement("return $N", name);
236+
}
237+
238+
private ClassName defaultsModeClassName() {
239+
return ClassName.get(defaultsModeBase, "DefaultsMode");
240+
}
241+
242+
private MethodSpec createConstructor() {
243+
return MethodSpec.constructorBuilder()
244+
.addModifiers(Modifier.PRIVATE)
245+
.build();
246+
}
247+
248+
private static final class OptionMetadata {
249+
private final ClassName type;
250+
private final ClassName attribute;
251+
252+
public OptionMetadata(ClassName type, ClassName attribute) {
253+
this.type = type;
254+
this.attribute = attribute;
255+
}
256+
}
257+
}

codegen-lite/src/test/java/software/amazon/awssdk/codegen/lite/defaultsmode/DefaultsModeGenerationTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,10 @@ public void defaultsModeEnum() {
4242
assertThat(generator, generatesTo("defaults-mode.java"));
4343
}
4444

45+
@Test
46+
public void defaultsModeConfigurationClass() {
47+
DefaultsModeConfigurationGenerator generator = new DefaultsModeConfigurationGenerator(DEFAULTS_MODE_BASE, DEFAULTS_MODE_BASE, defaultConfiguration);
48+
assertThat(generator, generatesTo("defaults-mode-configuration.java"));
49+
}
50+
4551
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package software.amazon.awssdk.defaultsmode;
2+
3+
import java.time.Duration;
4+
import software.amazon.awssdk.annotations.Generated;
5+
import software.amazon.awssdk.annotations.SdkInternalApi;
6+
import software.amazon.awssdk.core.client.config.SdkClientOption;
7+
import software.amazon.awssdk.core.retry.RetryMode;
8+
import software.amazon.awssdk.http.SdkHttpConfigurationOption;
9+
import software.amazon.awssdk.utils.AttributeMap;
10+
11+
/**
12+
* Contains a collection of default configuration options for each DefaultsMode
13+
*/
14+
@SdkInternalApi
15+
@Generated("software.amazon.awssdk:codegen")
16+
public final class DefaultsModeConfiguration {
17+
private static final AttributeMap STANDARD_DEFAULTS = AttributeMap.builder()
18+
.put(SdkClientOption.DEFAULT_RETRY_MODE, RetryMode.STANDARD).build();
19+
20+
private static final AttributeMap STANDARD_HTTP_DEFAULTS = AttributeMap.builder()
21+
.put(SdkHttpConfigurationOption.CONNECTION_TIMEOUT, Duration.ofMillis(2000)).build();
22+
23+
private static final AttributeMap MOBILE_DEFAULTS = AttributeMap.builder()
24+
.put(SdkClientOption.DEFAULT_RETRY_MODE, RetryMode.ADAPTIVE).build();
25+
26+
private static final AttributeMap MOBILE_HTTP_DEFAULTS = AttributeMap.builder()
27+
.put(SdkHttpConfigurationOption.CONNECTION_TIMEOUT, Duration.ofMillis(10000)).build();
28+
29+
private static final AttributeMap CROSS_REGION_DEFAULTS = AttributeMap.builder()
30+
.put(SdkClientOption.DEFAULT_RETRY_MODE, RetryMode.STANDARD).build();
31+
32+
private static final AttributeMap CROSS_REGION_HTTP_DEFAULTS = AttributeMap.builder()
33+
.put(SdkHttpConfigurationOption.CONNECTION_TIMEOUT, Duration.ofMillis(2800)).build();
34+
35+
private static final AttributeMap IN_REGION_DEFAULTS = AttributeMap.builder()
36+
.put(SdkClientOption.DEFAULT_RETRY_MODE, RetryMode.STANDARD).build();
37+
38+
private static final AttributeMap IN_REGION_HTTP_DEFAULTS = AttributeMap.builder()
39+
.put(SdkHttpConfigurationOption.CONNECTION_TIMEOUT, Duration.ofMillis(1000)).build();
40+
41+
private static final AttributeMap LEGACY_DEFAULTS = AttributeMap.empty();
42+
43+
private static final AttributeMap LEGACY_HTTP_DEFAULTS = AttributeMap.empty();
44+
45+
private DefaultsModeConfiguration() {
46+
}
47+
48+
/**
49+
* Return the default HTTP config options for a given defaults mode
50+
*/
51+
public static AttributeMap defaultHttpConfig(DefaultsMode mode) {
52+
switch (mode) {
53+
case STANDARD:
54+
return STANDARD_HTTP_DEFAULTS;
55+
case MOBILE:
56+
return MOBILE_HTTP_DEFAULTS;
57+
case CROSS_REGION:
58+
return CROSS_REGION_HTTP_DEFAULTS;
59+
case IN_REGION:
60+
return IN_REGION_HTTP_DEFAULTS;
61+
case LEGACY:
62+
return LEGACY_HTTP_DEFAULTS;
63+
default:
64+
throw new IllegalArgumentException("Unsupported mode: " + mode);
65+
}
66+
}
67+
68+
/**
69+
* Return the default SDK config options for a given defaults mode
70+
*/
71+
public static AttributeMap defaultConfig(DefaultsMode mode) {
72+
switch (mode) {
73+
case STANDARD:
74+
return STANDARD_DEFAULTS;
75+
case MOBILE:
76+
return MOBILE_DEFAULTS;
77+
case CROSS_REGION:
78+
return CROSS_REGION_DEFAULTS;
79+
case IN_REGION:
80+
return IN_REGION_DEFAULTS;
81+
case LEGACY:
82+
return LEGACY_DEFAULTS;
83+
default:
84+
throw new IllegalArgumentException("Unsupported mode: " + mode);
85+
}
86+
}
87+
}

0 commit comments

Comments
 (0)