Skip to content

Commit e748cb4

Browse files
authored
Merge pull request #1602 from aws/millem/global-service-error-improvements
Improved messaging for all UnknownHostExceptions. Added ServiceMetadata.servicePartitions()
2 parents dff6955 + 0937a6d commit e748cb4

File tree

22 files changed

+546
-142
lines changed

22 files changed

+546
-142
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type": "feature",
3+
"category": "AWS SDK for Java v2",
4+
"description": "Added ServiceMetadata.servicePartitions() to get partition metadata for a specific service"
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type": "feature",
3+
"category": "AWS SDK for Java v2",
4+
"description": "Improved error messages on UnknownHostExceptions"
5+
}

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,7 @@ public void generateServiceMetadata(Path baseSourcesDirectory, Partitions partit
9494
Set<String> services = new HashSet<>();
9595
partitions.getPartitions().forEach(p -> services.addAll(p.getServices().keySet()));
9696

97-
services.stream()
98-
// Use hardcoded file for elasticache until the incorrect fips endpoint is fixed
99-
//TODO Remove once elasticache endpoints are fixed at source
100-
.filter(s -> !"elasticache".equals(s))
101-
.forEach(s -> new CodeGenerator(sourcesDirectory.toString(), new ServiceMetadataGenerator(partitions,
97+
services.forEach(s -> new CodeGenerator(sourcesDirectory.toString(), new ServiceMetadataGenerator(partitions,
10298
s,
10399
SERVICE_METADATA_BASE,
104100
REGION_BASE))

codegen-lite/src/main/java/software/amazon/awssdk/codegen/lite/regions/ServiceMetadataGenerator.java

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,16 @@
5050
public class ServiceMetadataGenerator implements PoetClass {
5151

5252
private final Partitions partitions;
53-
private final String service;
53+
private final String serviceEndpointPrefix;
5454
private final String basePackage;
5555
private final String regionBasePackage;
5656

5757
public ServiceMetadataGenerator(Partitions partitions,
58-
String service,
58+
String serviceEndpointPrefix,
5959
String basePackage,
6060
String regionBasePackage) {
6161
this.partitions = partitions;
62-
this.service = service;
62+
this.serviceEndpointPrefix = serviceEndpointPrefix;
6363
this.basePackage = basePackage;
6464
this.regionBasePackage = regionBasePackage;
6565
}
@@ -68,6 +68,8 @@ public ServiceMetadataGenerator(Partitions partitions,
6868
public TypeSpec poetClass() {
6969
TypeName listOfRegions = ParameterizedTypeName.get(ClassName.get(List.class), ClassName.get(regionBasePackage, "Region"));
7070
TypeName mapOfStringString = ParameterizedTypeName.get(Map.class, String.class, String.class);
71+
TypeName listOfServicePartitionMetadata =
72+
ParameterizedTypeName.get(ClassName.get(List.class), ClassName.get(regionBasePackage, "ServicePartitionMetadata"));
7173

7274
return TypeSpec.classBuilder(className())
7375
.addModifiers(Modifier.PUBLIC)
@@ -79,7 +81,7 @@ public TypeSpec poetClass() {
7981
.addSuperinterface(ClassName.get(regionBasePackage, "ServiceMetadata"))
8082
.addField(FieldSpec.builder(String.class, "ENDPOINT_PREFIX")
8183
.addModifiers(PRIVATE, FINAL, STATIC)
82-
.initializer("$S", service)
84+
.initializer("$S", serviceEndpointPrefix)
8385
.build())
8486
.addField(FieldSpec.builder(mapOfStringString, "PARTITION_OVERRIDDEN_ENDPOINTS")
8587
.addModifiers(PRIVATE, FINAL, STATIC)
@@ -97,15 +99,20 @@ public TypeSpec poetClass() {
9799
.addModifiers(PRIVATE, FINAL, STATIC)
98100
.initializer(signingRegionOverrides(partitions))
99101
.build())
102+
.addField(FieldSpec.builder(listOfServicePartitionMetadata, "PARTITIONS")
103+
.addModifiers(PRIVATE, FINAL, STATIC)
104+
.initializer(servicePartitions(partitions))
105+
.build())
100106
.addMethod(regions())
101107
.addMethod(endpointFor())
102108
.addMethod(signingRegion())
109+
.addMethod(partitions(listOfServicePartitionMetadata))
103110
.build();
104111
}
105112

106113
@Override
107114
public ClassName className() {
108-
String sanitizedServiceName = service.replace(".", "-");
115+
String sanitizedServiceName = serviceEndpointPrefix.replace(".", "-");
109116
return ClassName.get(basePackage, Stream.of(sanitizedServiceName.split("-"))
110117
.map(Utils::capitalize)
111118
.collect(Collectors.joining()) + "ServiceMetadata");
@@ -150,8 +157,8 @@ private CodeBlock regionsField(Partitions partitions) {
150157

151158
partitions.getPartitions()
152159
.stream()
153-
.filter(p -> p.getServices().containsKey(service))
154-
.forEach(p -> regions.addAll(p.getServices().get(service).getEndpoints().keySet()
160+
.filter(p -> p.getServices().containsKey(serviceEndpointPrefix))
161+
.forEach(p -> regions.addAll(p.getServices().get(serviceEndpointPrefix).getEndpoints().keySet()
155162
.stream()
156163
.filter(r -> RegionValidationUtil.validRegion(r, p.getRegionRegex()))
157164
.collect(Collectors.toList())));
@@ -185,6 +192,39 @@ private CodeBlock signingRegionOverrides(Partitions partitions) {
185192
return builder.add(".build()").build();
186193
}
187194

195+
private CodeBlock servicePartitions(Partitions partitions) {
196+
return CodeBlock.builder()
197+
.add("$T.unmodifiableList($T.asList(", Collections.class, Arrays.class)
198+
.add(commaSeparatedServicePartitions(partitions))
199+
.add("))")
200+
.build();
201+
}
202+
203+
private CodeBlock commaSeparatedServicePartitions(Partitions partitions) {
204+
ClassName defaultServicePartitionMetadata = ClassName.get(regionBasePackage + ".internal",
205+
"DefaultServicePartitionMetadata");
206+
return partitions.getPartitions()
207+
.stream()
208+
.filter(p -> p.getServices().containsKey(serviceEndpointPrefix))
209+
.map(p -> CodeBlock.of("new $T($S, $L)",
210+
defaultServicePartitionMetadata,
211+
p.getPartition(),
212+
globalRegion(p)))
213+
.collect(CodeBlock.joining(","));
214+
}
215+
216+
private CodeBlock globalRegion(Partition partition) {
217+
ClassName region = ClassName.get(regionBasePackage, "Region");
218+
Service service = partition.getServices().get(this.serviceEndpointPrefix);
219+
boolean hasGlobalRegionForPartition = service.isRegionalized() != null &&
220+
!service.isRegionalized() &&
221+
service.isPartitionWideEndpointAvailable();
222+
String globalRegionForPartition = hasGlobalRegionForPartition ? service.getPartitionEndpoint() : null;
223+
return globalRegionForPartition == null
224+
? CodeBlock.of("null")
225+
: CodeBlock.of("$T.of($S)", region, globalRegionForPartition);
226+
}
227+
188228
private MethodSpec regions() {
189229
TypeName listOfRegions = ParameterizedTypeName.get(ClassName.get(List.class),
190230
ClassName.get(regionBasePackage, "Region"));
@@ -219,14 +259,23 @@ private MethodSpec signingRegion() {
219259
.build();
220260
}
221261

262+
private MethodSpec partitions(TypeName listOfServicePartitionMetadata) {
263+
return MethodSpec.methodBuilder("servicePartitions")
264+
.addModifiers(Modifier.PUBLIC)
265+
.addAnnotation(Override.class)
266+
.returns(listOfServicePartitionMetadata)
267+
.addStatement("return $L", "PARTITIONS")
268+
.build();
269+
}
270+
222271
private Map<Partition, Service> getServiceData(Partitions partitions) {
223272
Map<Partition, Service> serviceData = new TreeMap<>(Comparator.comparing(Partition::getPartition));
224273

225274
partitions.getPartitions()
226275
.forEach(p -> p.getServices()
227276
.entrySet()
228277
.stream()
229-
.filter(s -> s.getKey().equalsIgnoreCase(service))
278+
.filter(s -> s.getKey().equalsIgnoreCase(serviceEndpointPrefix))
230279
.forEach(s -> serviceData.put(p, s.getValue())));
231280

232281
return serviceData;

codegen-lite/src/main/java/software/amazon/awssdk/codegen/lite/regions/model/Service.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public final class Service {
4545
/**
4646
* Returns true if the service is regionalized.
4747
*/
48-
private boolean isRegionalized;
48+
private Boolean isRegionalized;
4949

5050
public Service() {}
5151

@@ -99,15 +99,15 @@ public void setPartitionEndpoint(String partitionEndpoint) {
9999
/**
100100
* returns true if the service is regionalized.
101101
*/
102-
public boolean isRegionalized() {
102+
public Boolean isRegionalized() {
103103
return isRegionalized;
104104
}
105105

106106
/**
107107
* sets the regionalized property for a service..
108108
*/
109109
@JsonProperty(value = "isRegionalized")
110-
public void setIsRegionalized(boolean regionalized) {
110+
public void setIsRegionalized(Boolean regionalized) {
111111
isRegionalized = regionalized;
112112
}
113113

codegen-lite/src/test/resources/software/amazon/awssdk/codegen/lite/regions/s3-service-metadata.java

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import software.amazon.awssdk.annotations.SdkPublicApi;
1010
import software.amazon.awssdk.regions.Region;
1111
import software.amazon.awssdk.regions.ServiceMetadata;
12+
import software.amazon.awssdk.regions.ServicePartitionMetadata;
13+
import software.amazon.awssdk.regions.internal.DefaultServicePartitionMetadata;
1214
import software.amazon.awssdk.utils.ImmutableMap;
1315

1416
@Generated("software.amazon.awssdk:codegen")
@@ -19,22 +21,26 @@ public final class S3ServiceMetadata implements ServiceMetadata {
1921
private static final Map<String, String> PARTITION_OVERRIDDEN_ENDPOINTS = ImmutableMap.<String, String> builder().build();
2022

2123
private static final Map<String, String> REGION_OVERRIDDEN_ENDPOINTS = ImmutableMap.<String, String> builder()
22-
.put("ap-northeast-1", "s3.ap-northeast-1.amazonaws.com").put("ap-southeast-1", "s3.ap-southeast-1.amazonaws.com")
23-
.put("ap-southeast-2", "s3.ap-southeast-2.amazonaws.com").put("eu-west-1", "s3.eu-west-1.amazonaws.com")
24-
.put("sa-east-1", "s3.sa-east-1.amazonaws.com").put("us-east-1", "s3.amazonaws.com")
25-
.put("us-west-1", "s3.us-west-1.amazonaws.com").put("us-west-2", "s3.us-west-2.amazonaws.com")
26-
.put("fips-us-gov-west-1", "s3-fips-us-gov-west-1.amazonaws.com")
27-
.put("us-gov-west-1", "s3.us-gov-west-1.amazonaws.com").build();
24+
.put("ap-northeast-1", "s3.ap-northeast-1.amazonaws.com").put("ap-southeast-1", "s3.ap-southeast-1.amazonaws.com")
25+
.put("ap-southeast-2", "s3.ap-southeast-2.amazonaws.com").put("eu-west-1", "s3.eu-west-1.amazonaws.com")
26+
.put("sa-east-1", "s3.sa-east-1.amazonaws.com").put("us-east-1", "s3.amazonaws.com")
27+
.put("us-west-1", "s3.us-west-1.amazonaws.com").put("us-west-2", "s3.us-west-2.amazonaws.com")
28+
.put("fips-us-gov-west-1", "s3-fips-us-gov-west-1.amazonaws.com")
29+
.put("us-gov-west-1", "s3.us-gov-west-1.amazonaws.com").build();
2830

2931
private static final List<Region> REGIONS = Collections.unmodifiableList(Arrays.asList(Region.of("ap-northeast-1"),
30-
Region.of("ap-northeast-2"), Region.of("ap-northeast-3"), Region.of("ap-south-1"), Region.of("ap-southeast-1"),
31-
Region.of("ap-southeast-2"), Region.of("ca-central-1"), Region.of("eu-central-1"), Region.of("eu-west-1"),
32-
Region.of("eu-west-2"), Region.of("eu-west-3"), Region.of("sa-east-1"), Region.of("us-east-1"),
33-
Region.of("us-east-2"), Region.of("us-west-1"), Region.of("us-west-2"), Region.of("cn-north-1"),
34-
Region.of("cn-northwest-1"), Region.of("fips-us-gov-west-1"), Region.of("us-gov-west-1")));
32+
Region.of("ap-northeast-2"), Region.of("ap-northeast-3"), Region.of("ap-south-1"), Region.of("ap-southeast-1"),
33+
Region.of("ap-southeast-2"), Region.of("ca-central-1"), Region.of("eu-central-1"), Region.of("eu-west-1"),
34+
Region.of("eu-west-2"), Region.of("eu-west-3"), Region.of("sa-east-1"), Region.of("us-east-1"),
35+
Region.of("us-east-2"), Region.of("us-west-1"), Region.of("us-west-2"), Region.of("cn-north-1"),
36+
Region.of("cn-northwest-1"), Region.of("fips-us-gov-west-1"), Region.of("us-gov-west-1")));
3537

3638
private static final Map<String, String> SIGNING_REGION_OVERRIDES = ImmutableMap.<String, String> builder()
37-
.put("fips-us-gov-west-1", "us-gov-west-1").build();
39+
.put("fips-us-gov-west-1", "us-gov-west-1").build();
40+
41+
private static final List<ServicePartitionMetadata> PARTITIONS = Collections.unmodifiableList(Arrays.asList(
42+
new DefaultServicePartitionMetadata("aws", null), new DefaultServicePartitionMetadata("aws-cn", null),
43+
new DefaultServicePartitionMetadata("aws-us-gov", null)));
3844

3945
@Override
4046
public List<Region> regions() {
@@ -44,11 +50,16 @@ public List<Region> regions() {
4450
@Override
4551
public URI endpointFor(Region region) {
4652
return URI.create(REGION_OVERRIDDEN_ENDPOINTS.containsKey(region.id()) ? REGION_OVERRIDDEN_ENDPOINTS.get(region.id())
47-
: computeEndpoint(ENDPOINT_PREFIX, PARTITION_OVERRIDDEN_ENDPOINTS, region));
53+
: computeEndpoint(ENDPOINT_PREFIX, PARTITION_OVERRIDDEN_ENDPOINTS, region));
4854
}
4955

5056
@Override
5157
public Region signingRegion(Region region) {
5258
return Region.of(SIGNING_REGION_OVERRIDES.getOrDefault(region.id(), region.id()));
5359
}
60+
61+
@Override
62+
public List<ServicePartitionMetadata> servicePartitions() {
63+
return PARTITIONS;
64+
}
5465
}

codegen-lite/src/test/resources/software/amazon/awssdk/codegen/lite/regions/sts-service-metadata.java

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,3 @@
1-
/*
2-
* Copyright 2010-2020 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-
161
package software.amazon.awssdk.regions.servicemetadata;
172

183
import java.net.URI;
@@ -24,6 +9,8 @@
249
import software.amazon.awssdk.annotations.SdkPublicApi;
2510
import software.amazon.awssdk.regions.Region;
2611
import software.amazon.awssdk.regions.ServiceMetadata;
12+
import software.amazon.awssdk.regions.ServicePartitionMetadata;
13+
import software.amazon.awssdk.regions.internal.DefaultServicePartitionMetadata;
2714
import software.amazon.awssdk.utils.ImmutableMap;
2815

2916
@Generated("software.amazon.awssdk:codegen")
@@ -51,6 +38,10 @@ public final class StsServiceMetadata implements ServiceMetadata {
5138
.put("ap-northeast-2", "ap-northeast-2").put("us-east-1-fips", "us-east-1").put("us-east-2-fips", "us-east-2")
5239
.put("us-west-1-fips", "us-west-1").put("us-west-2-fips", "us-west-2").build();
5340

41+
private static final List<ServicePartitionMetadata> PARTITIONS = Collections.unmodifiableList(Arrays.asList(
42+
new DefaultServicePartitionMetadata("aws", null), new DefaultServicePartitionMetadata("aws-cn", null),
43+
new DefaultServicePartitionMetadata("aws-us-gov", null)));
44+
5445
@Override
5546
public List<Region> regions() {
5647
return REGIONS;
@@ -66,4 +57,9 @@ public URI endpointFor(Region region) {
6657
public Region signingRegion(Region region) {
6758
return Region.of(SIGNING_REGION_OVERRIDES.getOrDefault(region.id(), region.id()));
6859
}
60+
61+
@Override
62+
public List<ServicePartitionMetadata> servicePartitions() {
63+
return PARTITIONS;
64+
}
6965
}

core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsExecutionAttribute.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import software.amazon.awssdk.annotations.SdkPublicApi;
1919
import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute;
20+
import software.amazon.awssdk.awscore.client.config.AwsClientOption;
2021
import software.amazon.awssdk.core.interceptor.ExecutionAttribute;
2122
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
2223
import software.amazon.awssdk.core.interceptor.SdkExecutionAttribute;
@@ -33,5 +34,10 @@ public final class AwsExecutionAttribute extends SdkExecutionAttribute {
3334
*/
3435
public static final ExecutionAttribute<Region> AWS_REGION = new ExecutionAttribute<>("AwsRegion");
3536

37+
/**
38+
* The {@link AwsClientOption#ENDPOINT_PREFIX} for the client.
39+
*/
40+
public static final ExecutionAttribute<String> ENDPOINT_PREFIX = new ExecutionAttribute<>("AwsEndpointPrefix");
41+
3642
private AwsExecutionAttribute() {}
3743
}

0 commit comments

Comments
 (0)