22
22
import java .net .URI ;
23
23
24
24
import com .amazonaws .ClientConfiguration ;
25
+ import com .amazonaws .SdkClientException ;
25
26
import com .amazonaws .client .builder .AwsClientBuilder ;
26
27
import com .amazonaws .handlers .RequestHandler2 ;
27
28
import com .amazonaws .services .s3 .AmazonS3 ;
41
42
import org .apache .hadoop .conf .Configuration ;
42
43
import org .apache .hadoop .conf .Configured ;
43
44
import org .apache .hadoop .fs .s3a .statistics .impl .AwsStatisticsCollector ;
45
+ import org .apache .hadoop .fs .store .LogExactlyOnce ;
44
46
45
47
import static org .apache .hadoop .fs .s3a .Constants .AWS_REGION ;
48
+ import static org .apache .hadoop .fs .s3a .Constants .AWS_S3_CENTRAL_REGION ;
46
49
import static org .apache .hadoop .fs .s3a .Constants .EXPERIMENTAL_AWS_INTERNAL_THROTTLING ;
47
50
import static org .apache .hadoop .fs .s3a .Constants .EXPERIMENTAL_AWS_INTERNAL_THROTTLING_DEFAULT ;
51
+ import static org .apache .hadoop .fs .s3a .S3AUtils .translateException ;
48
52
49
53
/**
50
54
* The default {@link S3ClientFactory} implementation.
@@ -64,6 +68,19 @@ public class DefaultS3ClientFactory extends Configured
64
68
protected static final Logger LOG =
65
69
LoggerFactory .getLogger (DefaultS3ClientFactory .class );
66
70
71
+ /**
72
+ * A one-off warning of default region chains in use.
73
+ */
74
+ private static final LogExactlyOnce WARN_OF_DEFAULT_REGION_CHAIN =
75
+ new LogExactlyOnce (LOG );
76
+
77
+ /**
78
+ * Warning message printed when the SDK Region chain is in use.
79
+ */
80
+ private static final String SDK_REGION_CHAIN_IN_USE =
81
+ "S3A filesystem client is using"
82
+ + " the SDK region resolution chain." ;
83
+
67
84
/**
68
85
* Create the client by preparing the AwsConf configuration
69
86
* and then invoking {@code buildAmazonS3Client()}.
@@ -94,9 +111,14 @@ public AmazonS3 createS3Client(
94
111
awsConf .setUserAgentSuffix (parameters .getUserAgentSuffix ());
95
112
}
96
113
97
- return buildAmazonS3Client (
98
- awsConf ,
99
- parameters );
114
+ try {
115
+ return buildAmazonS3Client (
116
+ awsConf ,
117
+ parameters );
118
+ } catch (SdkClientException e ) {
119
+ // SDK refused to build.
120
+ throw translateException ("creating AWS S3 client" , uri .toString (), e );
121
+ }
100
122
}
101
123
102
124
/**
@@ -109,6 +131,7 @@ public AmazonS3 createS3Client(
109
131
* @param awsConf AWS configuration
110
132
* @param parameters parameters
111
133
* @return new AmazonS3 client
134
+ * @throws SdkClientException if the configuration is invalid.
112
135
*/
113
136
protected AmazonS3 buildAmazonS3Client (
114
137
final ClientConfiguration awsConf ,
@@ -141,6 +164,21 @@ protected AmazonS3 buildAmazonS3Client(
141
164
// no idea what the endpoint is, so tell the SDK
142
165
// to work it out at the cost of an extra HEAD request
143
166
b .withForceGlobalBucketAccessEnabled (true );
167
+ // HADOOP-17771 force set the region so the build process doesn't halt.
168
+ String region = getConf ().getTrimmed (AWS_REGION , AWS_S3_CENTRAL_REGION );
169
+ LOG .debug ("fs.s3a.endpoint.region=\" {}\" " , region );
170
+ if (!region .isEmpty ()) {
171
+ // there's either an explicit region or we have fallen back
172
+ // to the central one.
173
+ LOG .debug ("Using default endpoint; setting region to {}" , region );
174
+ b .setRegion (region );
175
+ } else {
176
+ // no region.
177
+ // allow this if people really want it; it is OK to rely on this
178
+ // when deployed in EC2.
179
+ WARN_OF_DEFAULT_REGION_CHAIN .warn (SDK_REGION_CHAIN_IN_USE );
180
+ LOG .debug (SDK_REGION_CHAIN_IN_USE );
181
+ }
144
182
}
145
183
final AmazonS3 client = b .build ();
146
184
return client ;
@@ -206,7 +244,7 @@ protected static AmazonS3 configureAmazonS3Client(AmazonS3 s3,
206
244
createEndpointConfiguration (
207
245
final String endpoint , final ClientConfiguration awsConf ,
208
246
String awsRegion ) {
209
- LOG .debug ("Creating endpoint configuration for {} " , endpoint );
247
+ LOG .debug ("Creating endpoint configuration for \" {} \" " , endpoint );
210
248
if (endpoint == null || endpoint .isEmpty ()) {
211
249
// the default endpoint...we should be using null at this point.
212
250
LOG .debug ("Using default endpoint -no need to generate a configuration" );
0 commit comments