1
15
16 package software.amazon.awssdk.regions.servicemetadata;
17
18 import java.net.URI;
19 import java.util.List;
20 import java.util.function.Supplier;
21 import software.amazon.awssdk.annotations.SdkPublicApi;
22 import software.amazon.awssdk.core.SdkSystemSetting;
23 import software.amazon.awssdk.profiles.ProfileFile;
24 import software.amazon.awssdk.profiles.ProfileFileSystemSetting;
25 import software.amazon.awssdk.profiles.ProfileProperty;
26 import software.amazon.awssdk.regions.Region;
27 import software.amazon.awssdk.regions.ServiceMetadata;
28 import software.amazon.awssdk.regions.ServiceMetadataConfiguration;
29 import software.amazon.awssdk.regions.ServicePartitionMetadata;
30 import software.amazon.awssdk.utils.Lazy;
31 import software.amazon.awssdk.utils.Logger;
32
33
38 @SdkPublicApi
39 public final class EnhancedS3ServiceMetadata implements ServiceMetadata {
40 private static final Logger log = Logger.loggerFor(EnhancedS3ServiceMetadata.class);
41 private static final String REGIONAL_SETTING = "regional";
42
43 private final Lazy<Boolean> useUsEast1RegionalEndpoint;
44 private final ServiceMetadata s3ServiceMetadata;
45
46 public EnhancedS3ServiceMetadata() {
47 this(ServiceMetadataConfiguration.builder().build());
48 }
49
50 private EnhancedS3ServiceMetadata(ServiceMetadataConfiguration config) {
51 Supplier<ProfileFile> profileFile = config.profileFile() != null ? config.profileFile()
52 : ProfileFile::defaultProfileFile;
53 Supplier<String> profileName = config.profileName() != null ? () -> config.profileName()
54 : ProfileFileSystemSetting.AWS_PROFILE::getStringValueOrThrow;
55
56 this.useUsEast1RegionalEndpoint = new Lazy<>(() -> useUsEast1RegionalEndpoint(profileFile, profileName));
57 this.s3ServiceMetadata = new S3ServiceMetadata().reconfigure(config);
58 }
59
60 @Override
61 public URI endpointFor(Region region) {
62 if (Region.US_EAST_1.equals(region) && !useUsEast1RegionalEndpoint.getValue()) {
63 return URI.create("s3.amazonaws.com");
64 }
65 return s3ServiceMetadata.endpointFor(region);
66 }
67
68 @Override
69 public Region signingRegion(Region region) {
70 return s3ServiceMetadata.signingRegion(region);
71 }
72
73 @Override
74 public List<Region> regions() {
75 return s3ServiceMetadata.regions();
76 }
77
78 @Override
79 public List<ServicePartitionMetadata> servicePartitions() {
80 return s3ServiceMetadata.servicePartitions();
81 }
82
83 private boolean useUsEast1RegionalEndpoint(Supplier<ProfileFile> profileFile, Supplier<String> profileName) {
84 String env = envVarSetting();
85
86 if (env != null) {
87 return REGIONAL_SETTING.equalsIgnoreCase(env);
88 }
89
90 String profile = profileFileSetting(profileFile, profileName);
91
92 if (profile != null) {
93 return REGIONAL_SETTING.equalsIgnoreCase(profile);
94 }
95
96 return false;
97 }
98
99 private static String envVarSetting() {
100 return SdkSystemSetting.AWS_S3_US_EAST_1_REGIONAL_ENDPOINT.getStringValue().orElse(null);
101 }
102
103 private String profileFileSetting(Supplier<ProfileFile> profileFileSupplier, Supplier<String> profileNameSupplier) {
104 try {
105 ProfileFile profileFile = profileFileSupplier.get();
106 String profileName = profileNameSupplier.get();
107 if (profileFile == null || profileName == null) {
108 return null;
109 }
110 return profileFile.profile(profileName)
111 .flatMap(p -> p.property(ProfileProperty.S3_US_EAST_1_REGIONAL_ENDPOINT))
112 .orElse(null);
113 } catch (Exception t) {
114 log.warn(() -> "Unable to load config file", t);
115 return null;
116 }
117 }
118
119 @Override
120 public ServiceMetadata reconfigure(ServiceMetadataConfiguration configuration) {
121 return new EnhancedS3ServiceMetadata(configuration);
122 }
123 }
124