1
15 package com.amazonaws.services.s3.internal;
16
17 import com.amazonaws.SdkClientException;
18 import com.amazonaws.annotation.SdkInternalApi;
19 import com.amazonaws.annotation.ThreadSafe;
20 import com.amazonaws.auth.profile.ProfilesConfigFile;
21 import com.amazonaws.auth.profile.internal.AwsProfileNameLoader;
22 import com.amazonaws.auth.profile.internal.BasicProfile;
23 import com.amazonaws.profile.path.AwsProfileFileLocationProvider;
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26
27 import java.io.File;
28
29
32 @ThreadSafe
33 @SdkInternalApi
34 public final class RegionalEndpointsOptionResolver {
35 private enum Option {
36 LEGACY,
37 REGIONAL
38 }
39 private static final Log log = LogFactory.getLog(RegionalEndpointsOptionResolver.class);
40 private static final String ENV_VAR = "AWS_S3_US_EAST_1_REGIONAL_ENDPOINT";
41 private static final String PROFILE_PROPERTY = "s3_us_east_1_regional_endpoint";
42
43 private final AwsProfileFileLocationProvider configFileLocationProvider;
44
45 private volatile String profileName;
46 private volatile ProfilesConfigFile configFile;
47 private volatile boolean profileLoadAttempted;
48
49 public RegionalEndpointsOptionResolver() {
50 configFileLocationProvider = AwsProfileFileLocationProvider.DEFAULT_CONFIG_LOCATION_PROVIDER;
51 }
52
53 public RegionalEndpointsOptionResolver(AwsProfileFileLocationProvider configFileLocationProvider) {
54 this.configFileLocationProvider = configFileLocationProvider;
55 }
56
57 public boolean useRegionalMode() {
58 Option option = envVarOption();
59 if (option == null) {
60 option = profileOption();
61 }
62 return option == Option.REGIONAL;
63 }
64
65 private Option envVarOption() {
66 String val = System.getenv(ENV_VAR);
67 return resolveOption(val, String.format("Unexpected value set for %s environment variable: '%s'", ENV_VAR,
68 val));
69 }
70
71 private synchronized Option profileOption() {
72 String profileName = getProfileName();
73 BasicProfile profile = getProfile(profileName);
74 if (profile == null) {
75 return null;
76 }
77 String val = profile.getPropertyValue(PROFILE_PROPERTY);
78 return resolveOption(val, String.format("Unexpected option for '%s' property in profile '%s': %s",
79 PROFILE_PROPERTY, profileName, val));
80 }
81
82 private Option resolveOption(String value, String errMsg) {
83 if (value == null) {
84 return null;
85 }
86
87 if ("legacy".equalsIgnoreCase(value)) {
88 return Option.LEGACY;
89 }
90
91 if ("regional".equalsIgnoreCase(value)) {
92 return Option.REGIONAL;
93 }
94
95 throw new SdkClientException(errMsg);
96 }
97
98 private String getProfileName() {
99 if (profileName == null) {
100 synchronized (this) {
101 if (profileName == null) {
102 profileName = AwsProfileNameLoader.INSTANCE.loadProfileName();
103 }
104 }
105 }
106 return profileName;
107 }
108
109 private synchronized BasicProfile getProfile(String profileName) {
110 ProfilesConfigFile profilesConfigFile = getProfilesConfigFile();
111 if (profilesConfigFile != null) {
112 return profilesConfigFile.getAllBasicProfiles().get(profileName);
113 }
114 return null;
115 }
116
117
118 private ProfilesConfigFile getProfilesConfigFile() {
119 if (!profileLoadAttempted) {
120 synchronized (this) {
121 if (!profileLoadAttempted) {
122 File location = null;
123 try {
124 location = configFileLocationProvider.getLocation();
125 if (location != null) {
126 configFile = new ProfilesConfigFile(location);
127 }
128 } catch (Exception e) {
129 if (log.isWarnEnabled()) {
130 log.warn("Unable to load config file " + location, e);
131 }
132 } finally {
133 profileLoadAttempted = true;
134 }
135 }
136 }
137 }
138 return configFile;
139 }
140 }
141