@@ -93,36 +93,24 @@ class S3StorageClient {
9393 private static final Set <String > NOT_FOUND_CODES = Set .of ("NoSuchKey" , "404 Not Found" );
9494
9595 private final S3Client s3Client ;
96+ private final S3BackupRepositoryConfig configuration ;
9697
97- /**
98- * The S3 bucket where we read/write all data.
99- */
100- private final String bucketName ;
101-
102- S3StorageClient (
103- String bucketName , String region , String proxyHost , int proxyPort , String endpoint , String accessKey , String secretKey , Boolean pathStyleAccessEnabled , Boolean checksumValidationEnabled ) throws URISyntaxException {
104- this (createInternalClient (region , proxyHost , proxyPort , endpoint , accessKey , secretKey , pathStyleAccessEnabled , checksumValidationEnabled ), bucketName );
98+ S3StorageClient (S3BackupRepositoryConfig config ) throws URISyntaxException {
99+ this (createInternalClient (config ), config );
105100 }
106101
107102 @ VisibleForTesting
108- S3StorageClient (S3Client s3Client , String bucketName ) {
103+ S3StorageClient (S3Client s3Client , S3BackupRepositoryConfig configuration ) {
109104 this .s3Client = s3Client ;
110- this .bucketName = bucketName ;
105+ this .configuration = configuration ;
111106 }
112107
113- private static S3Client createInternalClient (
114- String region ,
115- String proxyHost ,
116- int proxyPort ,
117- String endpoint ,
118- String accessKey ,
119- String secretKey , Boolean pathStyleAccessEnabled ,
120- Boolean checksumValidationEnabled ) throws URISyntaxException {
108+ private static S3Client createInternalClient (S3BackupRepositoryConfig config ) throws URISyntaxException {
121109
122110 S3ClientBuilder clientBuilder = S3Client .builder ();
123111
124112 S3Configuration configuration = S3Configuration .builder ()
125- .checksumValidationEnabled (checksumValidationEnabled )
113+ .checksumValidationEnabled (config . getChecksumValidationEnabled () )
126114 .build ();
127115 clientBuilder .serviceConfiguration (configuration );
128116
@@ -131,9 +119,9 @@ private static S3Client createInternalClient(
131119 * not on a general client configuration object.
132120 */
133121 ApacheHttpClient .Builder httpClientBuilder = ApacheHttpClient .builder ();
134- if (!StringUtils .isEmpty (proxyHost )) {
122+ if (!StringUtils .isEmpty (config . getProxyHost () )) {
135123 ProxyConfiguration .Builder proxyConfigBuilder = ProxyConfiguration .builder ()
136- .endpoint (URI .create (proxyHost + ":" + proxyPort ));
124+ .endpoint (URI .create (config . getProxyHost () + ":" + config . getProxyPort () ));
137125 httpClientBuilder .proxyConfiguration (proxyConfigBuilder .build ());
138126 }
139127 clientBuilder .httpClientBuilder (httpClientBuilder );
@@ -145,9 +133,9 @@ private static S3Client createInternalClient(
145133 */
146134 clientBuilder .overrideConfiguration (ClientOverrideConfiguration .builder ().build ());
147135
148- if (!(StringUtils .isEmpty (accessKey ) || StringUtils .isEmpty (secretKey ))) {
136+ if (!(StringUtils .isEmpty (config . getAccessKey ()) || StringUtils .isEmpty (config . getSecretKey () ))) {
149137 clientBuilder .credentialsProvider (
150- StaticCredentialsProvider .create (AwsBasicCredentials .create (accessKey , secretKey )));
138+ StaticCredentialsProvider .create (AwsBasicCredentials .create (config . getAccessKey (), config . getSecretKey () )));
151139 } else {
152140 log .info ("No accessKey or secretKey configured, using default credentials provider chain" );
153141 }
@@ -156,17 +144,17 @@ private static S3Client createInternalClient(
156144 * SDK v2 Migration: `setEndpointConfiguration` from v1 is replaced by
157145 * `endpointOverride`. The region must still be set separately.
158146 */
159- if (!StringUtils .isEmpty (endpoint )) {
160- clientBuilder .endpointOverride (new URI (endpoint ));
147+ if (!StringUtils .isEmpty (config . getEndpoint () )) {
148+ clientBuilder .endpointOverride (new URI (config . getEndpoint () ));
161149 }
162- clientBuilder .region (Region .of (region ));
150+ clientBuilder .region (Region .of (config . getRegion () ));
163151
164152 /*
165153 * SDK v2 Migration: The method `withPathStyleAccessEnabled(boolean)` from v1 is
166154 * replaced by `forcePathStyle(boolean)` in v2.
167155 */
168- if (pathStyleAccessEnabled != null ) {
169- clientBuilder .forcePathStyle (pathStyleAccessEnabled );
156+ if (config . getPathStyleAccessEnabled () != null ) {
157+ clientBuilder .forcePathStyle (config . getPathStyleAccessEnabled () );
170158 }
171159
172160 return clientBuilder .build ();
@@ -192,7 +180,7 @@ void createDirectory(String path) throws S3Exception {
192180 * In v2, request parameters like bucket and key are set using builder methods.
193181 */
194182 PutObjectRequest putRequest = PutObjectRequest .builder ()
195- .bucket (bucketName )
183+ .bucket (this . configuration . getBucketName () )
196184 .key (path )
197185 .contentType (S3_DIR_CONTENT_TYPE )
198186 .metadata (Collections .singletonMap ("Content-Type" , S3_DIR_CONTENT_TYPE ))
@@ -257,7 +245,7 @@ String[] listDir(String path) throws S3Exception {
257245
258246 // The request MUST include the delimiter.
259247 ListObjectsV2Request listRequest = ListObjectsV2Request .builder ()
260- .bucket (bucketName )
248+ .bucket (this . configuration . getBucketName () )
261249 .prefix (prefix )
262250 .delimiter (S3_FILE_PATH_DELIMITER )
263251 .build ();
@@ -312,7 +300,7 @@ HeadObjectResponse getObjectMetadata(String path) throws SdkException {
312300 * This is the standard v2 way to retrieve object metadata without fetching the object's content.
313301 */
314302 HeadObjectRequest request = HeadObjectRequest .builder ()
315- .bucket (bucketName )
303+ .bucket (this . configuration . getBucketName () )
316304 .key (path )
317305 .build ();
318306 return s3Client .headObject (request );
@@ -418,7 +406,10 @@ InputStream pullStream(String path) throws S3Exception {
418406 path = sanitizedFilePath (path );
419407
420408 try {
421- ResponseInputStream <GetObjectResponse > requestedObject = s3Client .getObject (GetObjectRequest .builder ().bucket (bucketName ).key (path )
409+ ResponseInputStream <GetObjectResponse > requestedObject = s3Client
410+ .getObject (GetObjectRequest .builder ()
411+ .bucket (this .configuration .getBucketName ())
412+ .key (path )
422413 .build ());
423414 // This InputStream instance needs to be closed by the caller
424415 return requestedObject ;
@@ -441,7 +432,7 @@ OutputStream pushStream(String path) throws S3Exception {
441432 }
442433
443434 try {
444- return new S3OutputStream (s3Client , path , bucketName );
435+ return new S3OutputStream (s3Client , path , this . configuration );
445436 } catch (SdkException ase ) {
446437 throw handleAmazonException (ase );
447438 }
@@ -519,7 +510,10 @@ Collection<String> deleteObjects(Collection<String> entries, int batchSize) thro
519510 if (deleteIndividually ) {
520511 for (ObjectIdentifier k : keysToDelete ) {
521512 try {
522- s3Client .deleteObject (DeleteObjectRequest .builder ().bucket (bucketName ).key (k .key ())
513+ s3Client .deleteObject (DeleteObjectRequest
514+ .builder ()
515+ .bucket (this .configuration .getBucketName ())
516+ .key (k .key ())
523517 .build ());
524518 deletedPaths .add (k .key ());
525519 } catch (SdkException e ) {
@@ -541,7 +535,7 @@ private DeleteObjectsRequest createBatchDeleteRequest(List<ObjectIdentifier> key
541535 .build ();
542536
543537 return DeleteObjectsRequest .builder ()
544- .bucket (bucketName )
538+ .bucket (this . configuration . getBucketName () )
545539 .delete (deleteAction )
546540 .build ();
547541 }
@@ -554,7 +548,7 @@ private List<String> listAll(String path) throws S3Exception {
554548 * `ListObjectsV2Request`.
555549 */
556550 ListObjectsV2Request listRequest = ListObjectsV2Request .builder ()
557- .bucket (bucketName )
551+ .bucket (this . configuration . getBucketName () )
558552 .prefix (prefix )
559553 .build ();
560554
0 commit comments