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 package com.amazonaws.services.s3.internal;
16
17 import com.amazonaws.annotation.SdkInternalApi;
18 import com.amazonaws.annotation.ThreadSafe;
19
20 import java.io.File;
21
22 import com.amazonaws.auth.profile.ProfilesConfigFile;
23 import com.amazonaws.auth.profile.internal.AwsProfileNameLoader;
24 import com.amazonaws.auth.profile.internal.BasicProfile;
25 import com.amazonaws.profile.path.AwsProfileFileLocationProvider;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 /**
30  * Resolves the use arn region option for S3.
31  */

32 @ThreadSafe
33 @SdkInternalApi
34 public final class UseArnRegionResolver {
35
36     private static final Log log = LogFactory.getLog(UseArnRegionResolver.class);
37     private static final String ENV_VAR = "AWS_S3_USE_ARN_REGION";
38     private static final String PROFILE_PROPERTY = "s3_use_arn_region";
39
40     private final AwsProfileFileLocationProvider configFileLocationProvider;
41     private final boolean useArnRegion;
42
43     private volatile String profileName;
44     private volatile ProfilesConfigFile configFile;
45     private volatile boolean profileLoadAttempted;
46
47     public UseArnRegionResolver() {
48         this(AwsProfileFileLocationProvider.DEFAULT_CONFIG_LOCATION_PROVIDER);
49     }
50
51     public UseArnRegionResolver(AwsProfileFileLocationProvider configFileLocationProvider) {
52         this.configFileLocationProvider = configFileLocationProvider;
53         this.useArnRegion = resolveUseArnRegion();
54     }
55
56     public boolean useArnRegion() {
57         return useArnRegion;
58     }
59
60     private boolean resolveUseArnRegion() {
61         String useArnRegionString = envVar();
62
63         if (useArnRegionString == null) {
64             useArnRegionString = profile();
65         }
66
67         return Boolean.valueOf(useArnRegionString);
68     }
69
70     private String envVar() {
71         return System.getenv(ENV_VAR);
72     }
73
74     private String profile() {
75         String loadedProfileName = getProfileName();
76         BasicProfile profile = getProfile(loadedProfileName);
77         if (profile == null) {
78             return null;
79         }
80         String val = profile.getPropertyValue(PROFILE_PROPERTY);
81         return val;
82     }
83
84     private String getProfileName() {
85         if (profileName == null) {
86             synchronized (this) {
87                 if (profileName == null) {
88                     profileName = AwsProfileNameLoader.INSTANCE.loadProfileName();
89                 }
90             }
91         }
92         return profileName;
93     }
94
95     private BasicProfile getProfile(String profileName) {
96         ProfilesConfigFile profilesConfigFile = getProfilesConfigFile();
97         if (profilesConfigFile != null) {
98             return profilesConfigFile.getAllBasicProfiles().get(profileName);
99         }
100         return null;
101     }
102
103     // ProfilesConfigFile immediately loads the profiles at construction time
104     private ProfilesConfigFile getProfilesConfigFile() {
105         if (!profileLoadAttempted) {
106             synchronized (this) {
107                 if (!profileLoadAttempted) {
108                     File location = null;
109                     try {
110                         location = configFileLocationProvider.getLocation();
111                         if (location != null) {
112                             configFile = new ProfilesConfigFile(location);
113                         }
114                     } catch (Exception e) {
115                         if (log.isWarnEnabled()) {
116                             log.warn("Unable to load config file " + location, e);
117                         }
118                     } finally {
119                         profileLoadAttempted = true;
120                     }
121                 }
122             }
123         }
124         return configFile;
125     }
126 }