Skip to content

Use partitions.json to generate Region class #6120

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jun 9, 2025
6 changes: 6 additions & 0 deletions .changes/next-release/feature-AWSSDKforJavav2-7e045dc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "feature",
"category": "AWS SDK for Java v2",
"contributor": "",
"description": "Updated Region class generation to use Partitions.json instead of the Endpoints.json and removed the hardcoded global regions."
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@
import software.amazon.awssdk.codegen.lite.regions.RegionMetadataGenerator;
import software.amazon.awssdk.codegen.lite.regions.RegionMetadataLoader;
import software.amazon.awssdk.codegen.lite.regions.RegionMetadataProviderGenerator;
import software.amazon.awssdk.codegen.lite.regions.RegionPartitionsMetadataLoader;
import software.amazon.awssdk.codegen.lite.regions.ServiceMetadataGenerator;
import software.amazon.awssdk.codegen.lite.regions.ServiceMetadataProviderGenerator;
import software.amazon.awssdk.codegen.lite.regions.model.Partitions;
import software.amazon.awssdk.codegen.lite.regions.model.RegionPartitionsMetadata;
import software.amazon.awssdk.utils.StringUtils;

/**
Expand All @@ -59,19 +61,24 @@ public class RegionGenerationMojo extends AbstractMojo {
"${basedir}/src/main/resources/software/amazon/awssdk/regions/internal/region/endpoints.json")
private File endpoints;

@Parameter(property = "partitionsJson", defaultValue =
"${basedir}/../../codegen/src/main/resources/software/amazon/awssdk/codegen/rules/partitions.json.resource")
private File partitionsJson;

@Override
public void execute() throws MojoExecutionException {
Path baseSourcesDirectory = Paths.get(outputDirectory).resolve("generated-sources").resolve("sdk");
Path testsDirectory = Paths.get(outputDirectory).resolve("generated-test-sources").resolve("sdk-tests");

Partitions partitions = RegionMetadataLoader.build(endpoints);
RegionPartitionsMetadata regionPartitions = RegionPartitionsMetadataLoader.build(partitionsJson);

generatePartitionMetadataClass(baseSourcesDirectory, partitions);
generateRegionClass(baseSourcesDirectory, partitions);
generateRegionClass(baseSourcesDirectory, regionPartitions);
generateServiceMetadata(baseSourcesDirectory, partitions);
generateRegions(baseSourcesDirectory, partitions);
generateRegions(baseSourcesDirectory, regionPartitions);
generatePartitionProvider(baseSourcesDirectory, partitions);
generateRegionProvider(baseSourcesDirectory, partitions);
generateRegionProvider(baseSourcesDirectory, regionPartitions);
generateServiceProvider(baseSourcesDirectory, partitions);
generateEndpointTags(baseSourcesDirectory, partitions);

Expand All @@ -88,7 +95,7 @@ public void generatePartitionMetadataClass(Path baseSourcesDirectory, Partitions
REGION_BASE)).generate());
}

public void generateRegionClass(Path baseSourcesDirectory, Partitions partitions) {
public void generateRegionClass(Path baseSourcesDirectory, RegionPartitionsMetadata partitions) {
Path sourcesDirectory = baseSourcesDirectory.resolve(StringUtils.replace(REGION_BASE, ".", "/"));
new CodeGenerator(sourcesDirectory.toString(), new RegionGenerator(partitions, REGION_BASE)).generate();
}
Expand All @@ -105,7 +112,7 @@ public void generateServiceMetadata(Path baseSourcesDirectory, Partitions partit
.generate());
}

public void generateRegions(Path baseSourcesDirectory, Partitions partitions) {
public void generateRegions(Path baseSourcesDirectory, RegionPartitionsMetadata partitions) {
Path sourcesDirectory = baseSourcesDirectory.resolve(StringUtils.replace(REGION_METADATA_BASE, ".", "/"));
partitions.getPartitions()
.forEach(p -> p.getRegions().forEach((k, v) ->
Expand All @@ -126,7 +133,7 @@ public void generatePartitionProvider(Path baseSourcesDirectory, Partitions part
.generate();
}

public void generateRegionProvider(Path baseSourcesDirectory, Partitions partitions) {
public void generateRegionProvider(Path baseSourcesDirectory, RegionPartitionsMetadata partitions) {
Path sourcesDirectory = baseSourcesDirectory.resolve(StringUtils.replace(REGION_BASE, ".", "/"));
new CodeGenerator(sourcesDirectory.toString(), new RegionMetadataProviderGenerator(partitions,
REGION_METADATA_BASE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@
import software.amazon.awssdk.annotations.Generated;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.codegen.lite.PoetClass;
import software.amazon.awssdk.codegen.lite.regions.model.Partitions;
import software.amazon.awssdk.codegen.lite.regions.model.RegionPartitionsMetadata;
import software.amazon.awssdk.utils.Validate;
import software.amazon.awssdk.utils.http.SdkHttpUtils;

public class RegionGenerator implements PoetClass {

private final Partitions partitions;
private final RegionPartitionsMetadata partitions;
private final String basePackage;

public RegionGenerator(Partitions partitions,
public RegionGenerator(RegionPartitionsMetadata partitions,
String basePackage) {
this.partitions = partitions;
this.basePackage = basePackage;
Expand Down Expand Up @@ -100,21 +100,15 @@ private void regions(TypeSpec.Builder builder) {
.add("$T.unmodifiableList($T.asList(", Collections.class, Arrays.class);

String regionsCodeBlock = regions.stream().map(r -> {
boolean isGlobal = r.contains("global");
builder.addField(FieldSpec.builder(className(), regionName(r))
.addModifiers(PUBLIC, STATIC, FINAL)
.initializer("$T.of($S)", className(), r)
.initializer(isGlobal ? "$T.of($S, true)" : "$T.of($S)", className(), r)
.build());
return regionName(r);
}).collect(Collectors.joining(", "));

addGlobalRegions(builder);

regionsArray.add(regionsCodeBlock + ", ")
.add("AWS_GLOBAL, ")
.add("AWS_CN_GLOBAL, ")
.add("AWS_US_GOV_GLOBAL, ")
.add("AWS_ISO_GLOBAL, ")
.add("AWS_ISO_B_GLOBAL");
regionsArray.add(regionsCodeBlock);
regionsArray.add("))");

TypeName listOfRegions = ParameterizedTypeName.get(ClassName.get(List.class), className());
Expand All @@ -123,29 +117,6 @@ private void regions(TypeSpec.Builder builder) {
.initializer(regionsArray.build()).build());
}

private void addGlobalRegions(TypeSpec.Builder builder) {
builder.addField(FieldSpec.builder(className(), "AWS_GLOBAL")
.addModifiers(PUBLIC, STATIC, FINAL)
.initializer("$T.of($S, true)", className(), "aws-global")
.build())
.addField(FieldSpec.builder(className(), "AWS_CN_GLOBAL")
.addModifiers(PUBLIC, STATIC, FINAL)
.initializer("$T.of($S, true)", className(), "aws-cn-global")
.build())
.addField(FieldSpec.builder(className(), "AWS_US_GOV_GLOBAL")
.addModifiers(PUBLIC, STATIC, FINAL)
.initializer("$T.of($S, true)", className(), "aws-us-gov-global")
.build())
.addField(FieldSpec.builder(className(), "AWS_ISO_GLOBAL")
.addModifiers(PUBLIC, STATIC, FINAL)
.initializer("$T.of($S, true)", className(), "aws-iso-global")
.build())
.addField(FieldSpec.builder(className(), "AWS_ISO_B_GLOBAL")
.addModifiers(PUBLIC, STATIC, FINAL)
.initializer("$T.of($S, true)", className(), "aws-iso-b-global")
.build());
}

private String regionName(String region) {
return region.replace("-", "_").toUpperCase(Locale.US);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.codegen.lite.PoetClass;
import software.amazon.awssdk.codegen.lite.Utils;
import software.amazon.awssdk.codegen.lite.regions.model.Partition;
import software.amazon.awssdk.codegen.lite.regions.model.RegionPartitionMetadata;

public class RegionMetadataGenerator implements PoetClass {

private final Partition partition;
private final RegionPartitionMetadata partition;
private final String region;
private final String regionDescription;
private final String basePackage;
private final String regionBasePackage;

public RegionMetadataGenerator(Partition partition,
public RegionMetadataGenerator(RegionPartitionMetadata partition,
String region,
String regionDescription,
String basePackage,
Expand All @@ -65,9 +65,9 @@ public TypeSpec poetClass() {
.addModifiers(FINAL)
.addSuperinterface(ClassName.get(regionBasePackage, "RegionMetadata"))
.addField(staticFinalField("ID", region))
.addField(staticFinalField("DOMAIN", partition.getDnsSuffix()))
.addField(staticFinalField("DOMAIN", partition.getOutputs().getDnsSuffix()))
.addField(staticFinalField("DESCRIPTION", regionDescription))
.addField(staticFinalField("PARTITION_ID", partition.getPartition()))
.addField(staticFinalField("PARTITION_ID", partition.getId()))
.addMethod(getter("id", "ID"))
.addMethod(getter("domain", "DOMAIN"))
.addMethod(getter("description", "DESCRIPTION"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,16 @@
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.codegen.lite.PoetClass;
import software.amazon.awssdk.codegen.lite.Utils;
import software.amazon.awssdk.codegen.lite.regions.model.Partitions;
import software.amazon.awssdk.codegen.lite.regions.model.RegionPartitionsMetadata;
import software.amazon.awssdk.utils.ImmutableMap;

public class RegionMetadataProviderGenerator implements PoetClass {

private final Partitions partitions;
private final RegionPartitionsMetadata partitions;
private final String basePackage;
private final String regionBasePackage;

public RegionMetadataProviderGenerator(Partitions partitions,
public RegionMetadataProviderGenerator(RegionPartitionsMetadata partitions,
String basePackage,
String regionBasePackage) {
this.partitions = partitions;
Expand Down Expand Up @@ -79,7 +79,7 @@ public ClassName className() {
return ClassName.get(regionBasePackage, "GeneratedRegionMetadataProvider");
}

private CodeBlock regions(Partitions partitions) {
private CodeBlock regions(RegionPartitionsMetadata partitions) {
CodeBlock.Builder builder = CodeBlock.builder().add("$T.<Region, RegionMetadata>builder()", ImmutableMap.class);

partitions.getPartitions()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.awssdk.codegen.lite.regions;

import com.fasterxml.jackson.jr.ob.JSON;
import java.io.File;
import java.io.IOException;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.codegen.lite.regions.model.RegionPartitionsMetadata;

/**
* Loads and parses the partitions.json file into {@link RegionPartitionsMetadata}.
*/
@SdkInternalApi
public final class RegionPartitionsMetadataLoader {

private RegionPartitionsMetadataLoader() {
}

public static RegionPartitionsMetadata build(File path) {
return loadPartitionFromStream(path, path.toString());
}

private static RegionPartitionsMetadata loadPartitionFromStream(File stream, String location) {

try {
return JSON.std.with(JSON.Feature.USE_IS_GETTERS)
.beanFrom(RegionPartitionsMetadata.class, stream);

} catch (IOException | RuntimeException e) {
throw new RuntimeException("Error while loading partitions file from " + location, e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ public Partition() {

public Partition(@JsonProperty(value = "partition") String partition,
@JsonProperty(value = "regions") Map<String, PartitionRegion>
regions,
regions,
@JsonProperty(value = "services") Map<String,
Service> services) {
Service> services) {
this.partition = Validate.paramNotNull(partition, "Partition");
this.regions = regions;
this.services = services;
Expand Down Expand Up @@ -186,4 +186,4 @@ private boolean hasServiceEndpoint(String endpoint) {
}
return false;
}
}
}
Loading
Loading