15
15
16
16
package software .amazon .smithy .aws .typescript .codegen ;
17
17
18
+ import java .util .ArrayList ;
18
19
import java .util .List ;
19
20
import java .util .Map ;
20
21
import java .util .Optional ;
24
25
import software .amazon .smithy .aws .traits .ServiceTrait ;
25
26
import software .amazon .smithy .aws .traits .auth .SigV4Trait ;
26
27
import software .amazon .smithy .codegen .core .CodegenException ;
28
+ import software .amazon .smithy .model .node .ArrayNode ;
27
29
import software .amazon .smithy .model .node .Node ;
28
30
import software .amazon .smithy .model .node .ObjectNode ;
29
31
import software .amazon .smithy .model .node .StringNode ;
@@ -90,15 +92,16 @@ private void loadServiceEndpoints() {
90
92
91
93
for (Map .Entry <String , Node > entry : endpointMap .getStringMap ().entrySet ()) {
92
94
ObjectNode config = entry .getValue ().expectObjectNode ();
95
+ // TODO: Do not populate config if "deprecated" is present.
93
96
if (config .containsMember ("hostname" )) {
94
97
// Resolve the hostname.
95
98
String hostName = config .expectStringMember ("hostname" ).getValue ();
96
99
hostName = hostName .replace ("{dnsSuffix}" , dnsSuffix );
97
100
hostName = hostName .replace ("{service}" , endpointPrefix );
98
101
hostName = hostName .replace ("{region}" , entry .getKey ());
99
102
config = config .withMember ("hostname" , hostName );
100
- endpoints .put (entry .getKey (), config );
101
103
}
104
+ endpoints .put (entry .getKey (), config );
102
105
}
103
106
}
104
107
}
@@ -134,6 +137,14 @@ private void writePartitionHash() {
134
137
OptionalUtils .ifPresentOrElse (partition .getPartitionEndpoint (),
135
138
endpoint -> writer .write ("endpoint: $S," , endpoint ),
136
139
() -> writer .write ("hostname: $S," , partition .hostnameTemplate ));
140
+ List <Node > variants = partition .getVariants ();
141
+ if (!variants .isEmpty ()) {
142
+ writer .openBlock ("variants: [" , "]," , () -> {
143
+ variants .forEach (variant -> {
144
+ writer .write ("$L, " , Node .prettyPrintJson (variant ));
145
+ });
146
+ });
147
+ }
137
148
});
138
149
});
139
150
});
@@ -157,10 +168,18 @@ private void writeEndpointProviderFunction() {
157
168
}
158
169
159
170
private void writeEndpointSpecificResolver (String region , ObjectNode resolved ) {
160
- if (resolved .containsMember ("hostname" ) || resolved .containsMember ("credentialScope" )) {
171
+ if (resolved .containsMember ("variants" )
172
+ || resolved .containsMember ("hostname" )
173
+ || resolved .containsMember ("credentialScope" )) {
161
174
writer .openBlock ("$S: {" , "}," , region , () -> {
162
- String hostname = resolved .expectStringMember ("hostname" ).getValue ();
163
- writer .write ("hostname: $S," , hostname );
175
+ if (resolved .containsMember ("hostname" )) {
176
+ String hostname = resolved .expectStringMember ("hostname" ).getValue ();
177
+ writer .write ("hostname: $S," , hostname );
178
+ }
179
+ if (resolved .containsMember ("variants" )) {
180
+ ArrayNode variants = resolved .expectArrayMember ("variants" );
181
+ writer .write ("variants: $L," , ArrayNode .prettyPrintJson (variants ));
182
+ }
164
183
resolved .getObjectMember ("credentialScope" ).ifPresent (scope -> {
165
184
scope .getStringMember ("region" ).ifPresent (signingRegion -> {
166
185
writer .write ("signingRegion: $S," , signingRegion );
@@ -175,10 +194,10 @@ private void writeEndpointSpecificResolver(String region, ObjectNode resolved) {
175
194
176
195
private final class Partition {
177
196
final ObjectNode defaults ;
178
- final String hostnameTemplate ;
179
197
final String dnsSuffix ;
180
198
final String identifier ;
181
199
final String regionRegex ;
200
+ final String hostnameTemplate ;
182
201
private final ObjectNode config ;
183
202
184
203
private Partition (ObjectNode config , String partition ) {
@@ -187,15 +206,15 @@ private Partition(ObjectNode config, String partition) {
187
206
ObjectNode partitionDefaults = config .expectObjectMember ("defaults" );
188
207
defaults = partitionDefaults .merge (getService ().getObjectMember ("defaults" ).orElse (Node .objectNode ()));
189
208
209
+ dnsSuffix = config .expectStringMember ("dnsSuffix" ).getValue ();
210
+ identifier = partition ;
211
+ regionRegex = config .expectStringMember ("regionRegex" ).getValue ();
212
+
190
213
// Resolve the template to use for this service in this partition.
191
214
String template = defaults .expectStringMember ("hostname" ).getValue ();
192
215
template = template .replace ("{service}" , endpointPrefix );
193
- template = template .replace ("{dnsSuffix}" , config . expectStringMember ( " dnsSuffix" ). getValue () );
216
+ template = template .replace ("{dnsSuffix}" , dnsSuffix );
194
217
hostnameTemplate = template ;
195
-
196
- dnsSuffix = config .expectStringMember ("dnsSuffix" ).getValue ();
197
- identifier = partition ;
198
- regionRegex = config .expectStringMember ("regionRegex" ).getValue ();
199
218
}
200
219
201
220
ObjectNode getDefaults () {
@@ -220,6 +239,27 @@ Set<String> getAllRegions() {
220
239
return regions ;
221
240
}
222
241
242
+ List <Node > getVariants () {
243
+ List <Node > allVariants = new ArrayList <Node >();
244
+
245
+ if (defaults .containsMember ("variants" )) {
246
+ ArrayNode variants = defaults .expectArrayMember ("variants" );
247
+ variants .forEach (variant -> {
248
+ ObjectNode variantNode = variant .expectObjectNode ();
249
+ String hostname = variantNode .expectStringMember ("hostname" ).getValue ();
250
+ if (variantNode .containsMember ("dnsSuffix" )) {
251
+ String dnsSuffix = variantNode .expectStringMember ("dnsSuffix" ).getValue ();
252
+ hostname = hostname .replace ("{dnsSuffix}" , dnsSuffix );
253
+ }
254
+ hostname = hostname .replace ("{service}" , endpointPrefix );
255
+ hostname = hostname .replace ("{dnsSuffix}" , dnsSuffix );
256
+ allVariants .add (variantNode .withMember ("hostname" , hostname ).withoutMember ("dnsSuffix" ));
257
+ });
258
+ }
259
+
260
+ return allVariants ;
261
+ }
262
+
223
263
Optional <String > getPartitionEndpoint () {
224
264
ObjectNode service = getService ();
225
265
// Note: regionalized services always use regionalized endpoints.
0 commit comments