5555import software .amazon .awssdk .core .interceptor .ExecutionInterceptor ;
5656import software .amazon .awssdk .core .retry .RetryPolicy ;
5757import software .amazon .awssdk .http .apache .ApacheHttpClient ;
58- import software .amazon .awssdk .http .apache . ProxyConfiguration ;
58+ import software .amazon .awssdk .http .nio . netty . NettyNioAsyncHttpClient ;
5959import software .amazon .awssdk .regions .Region ;
60+ import software .amazon .awssdk .services .s3 .S3AsyncClient ;
61+ import software .amazon .awssdk .services .s3 .S3BaseClientBuilder ;
6062import software .amazon .awssdk .services .s3 .S3Client ;
61- import software .amazon .awssdk .services .s3 .S3ClientBuilder ;
6263import software .amazon .awssdk .services .s3 .S3Configuration ;
6364import software .amazon .awssdk .services .s3 .model .HeadBucketRequest ;
6465import software .amazon .awssdk .services .s3 .model .HeadBucketResponse ;
@@ -184,34 +185,85 @@ public AmazonS3 createS3Client(
184185 }
185186 }
186187
187- /**
188- * Creates a new {@link S3Client}.
189- *
190- * @param uri S3A file system URI
191- * @param parameters parameter object
192- * @return S3 client
193- * @throws IOException on any IO problem
194- */
195188 @ Override
196189 public S3Client createS3ClientV2 (
197190 final URI uri ,
198191 final S3ClientCreationParameters parameters ) throws IOException {
199192
200193 Configuration conf = getConf ();
201194 bucket = uri .getHost ();
195+ ApacheHttpClient .Builder httpClientBuilder = AWSClientConfig
196+ .createHttpClientBuilder (conf )
197+ .proxyConfiguration (AWSClientConfig .createProxyConfiguration (conf , bucket ));
198+ return configureClientBuilder (S3Client .builder (), parameters , conf , bucket )
199+ .httpClientBuilder (httpClientBuilder )
200+ .build ();
201+ }
202202
203- final ClientOverrideConfiguration .Builder clientOverrideConfigBuilder =
204- AWSClientConfig .createClientConfigBuilder (conf );
203+ @ Override
204+ public S3AsyncClient createS3AsyncClient (
205+ final URI uri ,
206+ final S3ClientCreationParameters parameters ) throws IOException {
205207
206- final ApacheHttpClient .Builder httpClientBuilder =
207- AWSClientConfig .createHttpClientBuilder (conf );
208+ Configuration conf = getConf ();
209+ bucket = uri .getHost ();
210+ NettyNioAsyncHttpClient .Builder httpClientBuilder = AWSClientConfig
211+ .createAsyncHttpClientBuilder (conf )
212+ .proxyConfiguration (AWSClientConfig .createAsyncProxyConfiguration (conf , bucket ));
213+ return configureClientBuilder (S3AsyncClient .builder (), parameters , conf , bucket )
214+ .httpClientBuilder (httpClientBuilder )
215+ .build ();
216+ }
208217
209- final RetryPolicy .Builder retryPolicyBuilder = AWSClientConfig .createRetryPolicyBuilder (conf );
218+ /**
219+ * Configure a sync or async S3 client builder.
220+ * This method handles all shared configuration.
221+ * @param builder S3 client builder
222+ * @param parameters parameter object
223+ * @param conf configuration object
224+ * @param bucket bucket name
225+ * @return the builder object
226+ * @param <BuilderT> S3 client builder type
227+ * @param <ClientT> S3 client type
228+ */
229+ private static <BuilderT extends S3BaseClientBuilder <BuilderT , ClientT >, ClientT >
230+ BuilderT configureClientBuilder (
231+ BuilderT builder ,
232+ S3ClientCreationParameters parameters ,
233+ Configuration conf ,
234+ String bucket ) {
210235
211- final ProxyConfiguration .Builder proxyConfigBuilder =
212- AWSClientConfig .createProxyConfigurationBuilder (conf , bucket );
236+ URI endpoint = getS3Endpoint (parameters .getEndpoint (), conf );
237+ Region region = getS3Region (conf .getTrimmed (AWS_REGION ), bucket ,
238+ parameters .getCredentialSet ());
239+ LOG .debug ("Using endpoint {}; and region {}" , endpoint , region );
213240
214- S3ClientBuilder s3ClientBuilder = S3Client .builder ();
241+ // TODO: Some configuration done in configureBasicParams is not done yet.
242+ S3Configuration serviceConfiguration = S3Configuration .builder ()
243+ .pathStyleAccessEnabled (parameters .isPathStyleAccess ())
244+ .build ();
245+
246+ return builder
247+ .overrideConfiguration (createClientOverrideConfiguration (parameters , conf ))
248+ .credentialsProvider (
249+ // use adapter classes so V1 credential providers continue to work. This will
250+ // be moved to AWSCredentialProviderList.add() when that class is updated.
251+ V1V2AwsCredentialProviderAdapter .adapt (parameters .getCredentialSet ()))
252+ .endpointOverride (endpoint )
253+ .region (region )
254+ .serviceConfiguration (serviceConfiguration );
255+ }
256+
257+ /**
258+ * Create an override configuration for an S3 client.
259+ * @param parameters parameter object
260+ * @param conf configuration object
261+ * @return the override configuration
262+ */
263+ private static ClientOverrideConfiguration createClientOverrideConfiguration (
264+ S3ClientCreationParameters parameters , Configuration conf ) {
265+ final ClientOverrideConfiguration .Builder clientOverrideConfigBuilder =
266+ AWSClientConfig .createClientConfigBuilder (conf );
215267
216268 // add any headers
217269 parameters .getHeaders ().forEach ((h , v ) -> clientOverrideConfigBuilder .putHeader (h , v ));
@@ -232,40 +284,12 @@ public S3Client createS3ClientV2(
232284 }
233285 }
234286
287+ final RetryPolicy .Builder retryPolicyBuilder = AWSClientConfig .createRetryPolicyBuilder (conf );
235288 clientOverrideConfigBuilder .retryPolicy (retryPolicyBuilder .build ());
236- httpClientBuilder .proxyConfiguration (proxyConfigBuilder .build ());
237-
238- s3ClientBuilder .httpClientBuilder (httpClientBuilder )
239- .overrideConfiguration (clientOverrideConfigBuilder .build ());
240-
241- // use adapter classes so V1 credential providers continue to work. This will be moved to
242- // AWSCredentialProviderList.add() when that class is updated.
243- s3ClientBuilder .credentialsProvider (
244- V1V2AwsCredentialProviderAdapter .adapt (parameters .getCredentialSet ()));
245-
246- URI endpoint = getS3Endpoint (parameters .getEndpoint (), conf );
247-
248- Region region =
249- getS3Region (conf .getTrimmed (AWS_REGION ), parameters .getCredentialSet ());
250-
251- LOG .debug ("Using endpoint {}; and region {}" , endpoint , region );
252-
253- s3ClientBuilder .endpointOverride (endpoint ).region (region );
254-
255- S3Configuration s3Configuration = S3Configuration .builder ()
256- .pathStyleAccessEnabled (parameters .isPathStyleAccess ())
257- .build ();
258-
259- s3ClientBuilder .serviceConfiguration (s3Configuration );
260289
261- // TODO: Some configuration done in configureBasicParams is not done yet.
262- // Need to verify how metrics collection can be done, as SDK V2 only
263- // seems to have a metrics publisher.
264-
265- return s3ClientBuilder .build ();
290+ return clientOverrideConfigBuilder .build ();
266291 }
267292
268-
269293 /**
270294 * Create an {@link AmazonS3} client of type
271295 * {@link AmazonS3EncryptionV2} if CSE is enabled.
@@ -527,10 +551,12 @@ private static URI getS3Endpoint(String endpoint, final Configuration conf) {
527551 *
528552 * @param region AWS S3 Region set in the config. This property may not be set, in which case
529553 * ask S3 for the region.
554+ * @param bucket Bucket name.
530555 * @param credentialsProvider Credentials provider to be used with the default s3 client.
531556 * @return region of the bucket.
532557 */
533- private Region getS3Region (String region , AWSCredentialsProvider credentialsProvider ) {
558+ private static Region getS3Region (String region , String bucket ,
559+ AWSCredentialsProvider credentialsProvider ) {
534560
535561 if (!StringUtils .isBlank (region )) {
536562 return Region .of (region );
0 commit comments