This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git


The following commit(s) were added to refs/heads/master by this push:
     new 84affde91f JAMES-3028 Introduce S3ClientFactory and inject to 
S3BlobStoreDAO (#2353)
84affde91f is described below

commit 84affde91fa40108f94bd31fa2e73c6128fda886
Author: vttran <vtt...@linagora.com>
AuthorDate: Wed Jul 17 12:29:54 2024 +0700

    JAMES-3028 Introduce S3ClientFactory and inject to S3BlobStoreDAO (#2353)
---
 .../blob/objectstorage/aws/S3BlobStoreDAO.java     | 116 +---------------
 .../blob/objectstorage/aws/S3ClientFactory.java    | 149 +++++++++++++++++++++
 .../blob/objectstorage/aws/S3BlobStoreDAOTest.java |   7 +-
 .../aws/S3DeDuplicationBlobStoreTest.java          |   6 +-
 .../blob/objectstorage/aws/S3HealthCheckTest.java  |   3 +-
 .../james/blob/objectstorage/aws/S3MinioTest.java  |   7 +-
 .../blob/objectstorage/aws/S3NamespaceTest.java    |   6 +-
 .../aws/S3PassThroughBlobStoreTest.java            |   7 +-
 .../aws/S3PrefixAndNamespaceTest.java              |   7 +-
 .../james/blob/objectstorage/aws/S3PrefixTest.java |   6 +-
 10 files changed, 190 insertions(+), 124 deletions(-)

diff --git 
a/server/blob/blob-s3/src/main/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAO.java
 
b/server/blob/blob-s3/src/main/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAO.java
index c3b3dc3727..6f49e4d64e 100644
--- 
a/server/blob/blob-s3/src/main/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAO.java
+++ 
b/server/blob/blob-s3/src/main/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAO.java
@@ -21,24 +21,14 @@ package org.apache.james.blob.objectstorage.aws;
 
 import static org.apache.james.util.ReactorUtils.DEFAULT_CONCURRENCY;
 
-import java.io.Closeable;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.security.cert.X509Certificate;
 import java.time.Duration;
 import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-
-import jakarta.annotation.PreDestroy;
 import jakarta.inject.Inject;
 import jakarta.inject.Singleton;
 
@@ -48,9 +38,6 @@ import org.apache.james.blob.api.BlobStoreDAO;
 import org.apache.james.blob.api.BucketName;
 import org.apache.james.blob.api.ObjectNotFoundException;
 import org.apache.james.blob.api.ObjectStoreIOException;
-import org.apache.james.lifecycle.api.Startable;
-import org.apache.james.metrics.api.GaugeRegistry;
-import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.util.ReactorUtils;
 import org.reactivestreams.Publisher;
 
@@ -66,17 +53,12 @@ import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 import reactor.core.scheduler.Schedulers;
 import reactor.util.retry.RetryBackoffSpec;
-import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
-import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
 import software.amazon.awssdk.core.BytesWrapper;
 import software.amazon.awssdk.core.async.AsyncRequestBody;
 import software.amazon.awssdk.core.async.AsyncResponseTransformer;
 import software.amazon.awssdk.core.async.SdkPublisher;
 import software.amazon.awssdk.core.exception.SdkClientException;
-import software.amazon.awssdk.http.TlsTrustManagersProvider;
-import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
 import software.amazon.awssdk.services.s3.S3AsyncClient;
-import software.amazon.awssdk.services.s3.S3Configuration;
 import software.amazon.awssdk.services.s3.model.Bucket;
 import 
software.amazon.awssdk.services.s3.model.BucketAlreadyOwnedByYouException;
 import software.amazon.awssdk.services.s3.model.DeleteObjectsResponse;
@@ -89,26 +71,7 @@ import 
software.amazon.awssdk.services.s3.model.ObjectIdentifier;
 import software.amazon.awssdk.services.s3.model.PutObjectResponse;
 import software.amazon.awssdk.services.s3.model.S3Object;
 
-public class S3BlobStoreDAO implements BlobStoreDAO, Startable, Closeable {
-    private static final TrustManager DUMMY_TRUST_MANAGER = new 
X509TrustManager() {
-        @Override
-        public X509Certificate[] getAcceptedIssuers() {
-            return new X509Certificate[0];
-        }
-
-        @Override
-        public void checkClientTrusted(X509Certificate[] chain, String 
authType) {
-            // Always trust
-        }
-
-        @Override
-        public void checkServerTrusted(X509Certificate[] chain, String 
authType) {
-            // Always trust
-        }
-    };
-
-    private static final String S3_METRICS_ENABLED_PROPERTY_KEY = 
"james.s3.metrics.enabled";
-    private static final String S3_METRICS_ENABLED_DEFAULT_VALUE = "true";
+public class S3BlobStoreDAO implements BlobStoreDAO {
 
     private static class FileBackedOutputStreamByteSource extends ByteSource {
         private final FileBackedOutputStream stream;
@@ -145,34 +108,17 @@ public class S3BlobStoreDAO implements BlobStoreDAO, 
Startable, Closeable {
 
     private final BucketNameResolver bucketNameResolver;
     private final S3AsyncClient client;
-    private final BlobId.Factory blobIdFactory;
     private final S3BlobStoreConfiguration configuration;
+    private final BlobId.Factory blobIdFactory;
 
     @Inject
     @Singleton
-    S3BlobStoreDAO(S3BlobStoreConfiguration configuration, BlobId.Factory 
blobIdFactory, MetricFactory metricFactory, GaugeRegistry gaugeRegistry) {
-        this.blobIdFactory = blobIdFactory;
+    S3BlobStoreDAO(S3ClientFactory s3ClientFactory,
+                   S3BlobStoreConfiguration configuration,
+                   BlobId.Factory blobIdFactory) {
         this.configuration = configuration;
-        AwsS3AuthConfiguration authConfiguration = 
this.configuration.getSpecificAuthConfiguration();
-
-        S3Configuration pathStyleAccess = S3Configuration.builder()
-            .pathStyleAccessEnabled(true)
-            .build();
-
-        client = S3AsyncClient.builder()
-            .credentialsProvider(StaticCredentialsProvider.create(
-                AwsBasicCredentials.create(authConfiguration.getAccessKeyId(), 
authConfiguration.getSecretKey())))
-            .httpClientBuilder(httpClientBuilder(configuration))
-            .endpointOverride(authConfiguration.getEndpoint())
-            .region(configuration.getRegion().asAws())
-            .serviceConfiguration(pathStyleAccess)
-            .overrideConfiguration(builder -> {
-                boolean s3MetricsEnabled = 
Boolean.parseBoolean(System.getProperty(S3_METRICS_ENABLED_PROPERTY_KEY, 
S3_METRICS_ENABLED_DEFAULT_VALUE));
-                if (s3MetricsEnabled) {
-                    builder.addMetricPublisher(new 
JamesS3MetricPublisher(metricFactory, gaugeRegistry));
-                }
-            })
-            .build();
+        this.client = s3ClientFactory.get();
+        this.blobIdFactory = blobIdFactory;
 
         bucketNameResolver = BucketNameResolver.builder()
             .prefix(configuration.getBucketPrefix())
@@ -180,54 +126,6 @@ public class S3BlobStoreDAO implements BlobStoreDAO, 
Startable, Closeable {
             .build();
     }
 
-    private NettyNioAsyncHttpClient.Builder 
httpClientBuilder(S3BlobStoreConfiguration configuration) {
-        NettyNioAsyncHttpClient.Builder result = 
NettyNioAsyncHttpClient.builder()
-            
.tlsTrustManagersProvider(getTrustManagerProvider(configuration.getSpecificAuthConfiguration()))
-            .maxConcurrency(configuration.getHttpConcurrency())
-            .maxPendingConnectionAcquires(10_000);
-        configuration.getWriteTimeout().ifPresent(result::writeTimeout);
-        configuration.getReadTimeout().ifPresent(result::readTimeout);
-        
configuration.getConnectionTimeout().ifPresent(result::connectionTimeout);
-        result.useNonBlockingDnsResolver(true);
-        return result;
-    }
-
-    private TlsTrustManagersProvider 
getTrustManagerProvider(AwsS3AuthConfiguration configuration) {
-        if (configuration.isTrustAll()) {
-            return () -> ImmutableList.of(DUMMY_TRUST_MANAGER).toArray(new 
TrustManager[0]);
-        }
-        try {
-            TrustManagerFactory trustManagerFactory = 
TrustManagerFactory.getInstance(
-                
configuration.getTrustStoreAlgorithm().orElse(TrustManagerFactory.getDefaultAlgorithm()));
-            KeyStore trustStore = loadTrustStore(configuration);
-            trustManagerFactory.init(trustStore);
-            return trustManagerFactory::getTrustManagers;
-        } catch (GeneralSecurityException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private KeyStore loadTrustStore(AwsS3AuthConfiguration configuration) {
-        if (configuration.getTrustStorePath().isEmpty()) {
-            return null; // use java default truststore
-        }
-        try (FileInputStream trustStoreStream = new 
FileInputStream(configuration.getTrustStorePath().get())) {
-            char[] secret = 
configuration.getTrustStoreSecret().map(String::toCharArray).orElse(null);
-            KeyStore trustStore = KeyStore.getInstance(
-                
configuration.getTrustStoreType().orElse(KeyStore.getDefaultType()));
-            trustStore.load(trustStoreStream, secret);
-            return trustStore;
-        } catch (GeneralSecurityException | IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    @Override
-    @PreDestroy
-    public void close() {
-        client.close();
-    }
-
     @Override
     public InputStream read(BucketName bucketName, BlobId blobId) throws 
ObjectStoreIOException, ObjectNotFoundException {
         BucketName resolvedBucketName = bucketNameResolver.resolve(bucketName);
diff --git 
a/server/blob/blob-s3/src/main/java/org/apache/james/blob/objectstorage/aws/S3ClientFactory.java
 
b/server/blob/blob-s3/src/main/java/org/apache/james/blob/objectstorage/aws/S3ClientFactory.java
new file mode 100644
index 0000000000..75e64ba3fa
--- /dev/null
+++ 
b/server/blob/blob-s3/src/main/java/org/apache/james/blob/objectstorage/aws/S3ClientFactory.java
@@ -0,0 +1,149 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.blob.objectstorage.aws;
+
+import java.io.Closeable;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import jakarta.annotation.PreDestroy;
+import jakarta.inject.Inject;
+import jakarta.inject.Singleton;
+
+import org.apache.james.lifecycle.api.Startable;
+import org.apache.james.metrics.api.GaugeRegistry;
+import org.apache.james.metrics.api.MetricFactory;
+
+import com.google.common.collect.ImmutableList;
+
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.http.TlsTrustManagersProvider;
+import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
+import software.amazon.awssdk.services.s3.S3AsyncClient;
+import software.amazon.awssdk.services.s3.S3Configuration;
+
+public class S3ClientFactory implements Startable, Closeable {
+    private static final TrustManager DUMMY_TRUST_MANAGER = new 
X509TrustManager() {
+        @Override
+        public X509Certificate[] getAcceptedIssuers() {
+            return new X509Certificate[0];
+        }
+
+        @Override
+        public void checkClientTrusted(X509Certificate[] chain, String 
authType) {
+            // Always trust
+        }
+
+        @Override
+        public void checkServerTrusted(X509Certificate[] chain, String 
authType) {
+            // Always trust
+        }
+    };
+
+    private static final String S3_METRICS_ENABLED_PROPERTY_KEY = 
"james.s3.metrics.enabled";
+    private static final String S3_METRICS_ENABLED_DEFAULT_VALUE = "true";
+
+    private final S3AsyncClient s3Client;
+
+    @Inject
+    @Singleton
+    public S3ClientFactory(S3BlobStoreConfiguration configuration, 
MetricFactory metricFactory, GaugeRegistry gaugeRegistry) {
+
+        AwsS3AuthConfiguration authConfiguration = 
configuration.getSpecificAuthConfiguration();
+        S3Configuration pathStyleAccess = S3Configuration.builder()
+            .pathStyleAccessEnabled(true)
+            .build();
+
+        s3Client = S3AsyncClient.builder()
+            .credentialsProvider(StaticCredentialsProvider.create(
+                AwsBasicCredentials.create(authConfiguration.getAccessKeyId(), 
authConfiguration.getSecretKey())))
+            .httpClientBuilder(httpClientBuilder(configuration))
+            .endpointOverride(authConfiguration.getEndpoint())
+            .region(configuration.getRegion().asAws())
+            .serviceConfiguration(pathStyleAccess)
+            .overrideConfiguration(builder -> {
+                boolean s3MetricsEnabled = 
Boolean.parseBoolean(System.getProperty(S3_METRICS_ENABLED_PROPERTY_KEY, 
S3_METRICS_ENABLED_DEFAULT_VALUE));
+                if (s3MetricsEnabled) {
+                    builder.addMetricPublisher(new 
JamesS3MetricPublisher(metricFactory, gaugeRegistry));
+                }
+            })
+            .build();
+    }
+
+    private NettyNioAsyncHttpClient.Builder 
httpClientBuilder(S3BlobStoreConfiguration configuration) {
+        NettyNioAsyncHttpClient.Builder result = 
NettyNioAsyncHttpClient.builder()
+            
.tlsTrustManagersProvider(getTrustManagerProvider(configuration.getSpecificAuthConfiguration()))
+            .maxConcurrency(configuration.getHttpConcurrency())
+            .maxPendingConnectionAcquires(10_000);
+        configuration.getWriteTimeout().ifPresent(result::writeTimeout);
+        configuration.getReadTimeout().ifPresent(result::readTimeout);
+        
configuration.getConnectionTimeout().ifPresent(result::connectionTimeout);
+        result.useNonBlockingDnsResolver(true);
+        return result;
+    }
+
+    private TlsTrustManagersProvider 
getTrustManagerProvider(AwsS3AuthConfiguration configuration) {
+        if (configuration.isTrustAll()) {
+            return () -> ImmutableList.of(DUMMY_TRUST_MANAGER).toArray(new 
TrustManager[0]);
+        }
+        try {
+            TrustManagerFactory trustManagerFactory = 
TrustManagerFactory.getInstance(
+                
configuration.getTrustStoreAlgorithm().orElse(TrustManagerFactory.getDefaultAlgorithm()));
+            KeyStore trustStore = loadTrustStore(configuration);
+            trustManagerFactory.init(trustStore);
+            return trustManagerFactory::getTrustManagers;
+        } catch (GeneralSecurityException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private KeyStore loadTrustStore(AwsS3AuthConfiguration configuration) {
+        if (configuration.getTrustStorePath().isEmpty()) {
+            return null; // use java default truststore
+        }
+        try (FileInputStream trustStoreStream = new 
FileInputStream(configuration.getTrustStorePath().get())) {
+            char[] secret = 
configuration.getTrustStoreSecret().map(String::toCharArray).orElse(null);
+            KeyStore trustStore = KeyStore.getInstance(
+                
configuration.getTrustStoreType().orElse(KeyStore.getDefaultType()));
+            trustStore.load(trustStoreStream, secret);
+            return trustStore;
+        } catch (GeneralSecurityException | IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public S3AsyncClient get() {
+        return s3Client;
+    }
+
+    @Override
+    @PreDestroy
+    public void close() {
+        s3Client.close();
+    }
+}
diff --git 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAOTest.java
 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAOTest.java
index 0e2851b218..b852ca25ac 100644
--- 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAOTest.java
+++ 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAOTest.java
@@ -49,6 +49,7 @@ import reactor.util.retry.Retry;
 @ExtendWith(DockerAwsS3Extension.class)
 public class S3BlobStoreDAOTest implements BlobStoreDAOContract {
     private static S3BlobStoreDAO testee;
+    private static S3ClientFactory s3ClientFactory;
 
     @BeforeAll
     static void setUp(DockerAwsS3Container dockerAwsS3) {
@@ -65,7 +66,9 @@ public class S3BlobStoreDAOTest implements 
BlobStoreDAOContract {
                 .filter(UPLOAD_RETRY_EXCEPTION_PREDICATE)))
             .build();
 
-        testee = new S3BlobStoreDAO(s3Configuration, new TestBlobId.Factory(), 
new RecordingMetricFactory(), new NoopGaugeRegistry());
+        s3ClientFactory = new S3ClientFactory(s3Configuration, new 
RecordingMetricFactory(), new NoopGaugeRegistry());
+
+        testee = new S3BlobStoreDAO(s3ClientFactory, s3Configuration, new 
TestBlobId.Factory());
     }
 
     @AfterEach
@@ -75,7 +78,7 @@ public class S3BlobStoreDAOTest implements 
BlobStoreDAOContract {
 
     @AfterAll
     static void tearDownClass() {
-        testee.close();
+        s3ClientFactory.close();
     }
 
     @Override
diff --git 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3DeDuplicationBlobStoreTest.java
 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3DeDuplicationBlobStoreTest.java
index a1af4d3976..9f823a836c 100644
--- 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3DeDuplicationBlobStoreTest.java
+++ 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3DeDuplicationBlobStoreTest.java
@@ -36,6 +36,7 @@ class S3DeDuplicationBlobStoreTest implements 
BlobStoreContract {
 
     private static BlobStore testee;
     private static S3BlobStoreDAO s3BlobStoreDAO;
+    private static S3ClientFactory s3ClientFactory;
 
     @BeforeAll
     static void setUpClass(DockerAwsS3Container dockerAwsS3) {
@@ -51,7 +52,8 @@ class S3DeDuplicationBlobStoreTest implements 
BlobStoreContract {
             .build();
 
         HashBlobId.Factory blobIdFactory = new HashBlobId.Factory();
-        s3BlobStoreDAO = new S3BlobStoreDAO(s3Configuration, blobIdFactory, 
new RecordingMetricFactory(), new NoopGaugeRegistry());
+        s3ClientFactory = new S3ClientFactory(s3Configuration, new 
RecordingMetricFactory(), new NoopGaugeRegistry());
+        s3BlobStoreDAO = new S3BlobStoreDAO(s3ClientFactory, s3Configuration, 
blobIdFactory);
 
         testee = BlobStoreFactory.builder()
             .blobStoreDAO(s3BlobStoreDAO)
@@ -67,7 +69,7 @@ class S3DeDuplicationBlobStoreTest implements 
BlobStoreContract {
 
     @AfterAll
     static void tearDownClass() {
-        s3BlobStoreDAO.close();
+        s3ClientFactory.close();
     }
 
     @Override
diff --git 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3HealthCheckTest.java
 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3HealthCheckTest.java
index 36a56e72e5..b660948195 100644
--- 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3HealthCheckTest.java
+++ 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3HealthCheckTest.java
@@ -50,7 +50,8 @@ public class S3HealthCheckTest {
             .region(dockerAwsS3.dockerAwsS3().region())
             .build();
 
-        BlobStoreDAO s3BlobStoreDAO = new S3BlobStoreDAO(s3Configuration, new 
TestBlobId.Factory(), new RecordingMetricFactory(), new NoopGaugeRegistry());
+        S3ClientFactory s3ClientFactory = new S3ClientFactory(s3Configuration, 
new RecordingMetricFactory(), new NoopGaugeRegistry());
+        BlobStoreDAO s3BlobStoreDAO = new S3BlobStoreDAO(s3ClientFactory, 
s3Configuration, new TestBlobId.Factory());
         s3HealthCheck = new ObjectStorageHealthCheck(s3BlobStoreDAO);
     }
 
diff --git 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3MinioTest.java
 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3MinioTest.java
index f1e380d2a8..62f9f0ff57 100644
--- 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3MinioTest.java
+++ 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3MinioTest.java
@@ -62,6 +62,8 @@ public class S3MinioTest implements BlobStoreDAOContract {
     private static final int MINIO_PORT = 9000;
     private static S3BlobStoreDAO testee;
 
+    private static S3ClientFactory s3ClientFactory;
+
     @Container
     private static final GenericContainer<?> minioContainer = new 
GenericContainer<>(MINIO_IMAGE_FULL)
         .withExposedPorts(MINIO_PORT)
@@ -86,12 +88,13 @@ public class S3MinioTest implements BlobStoreDAOContract {
                 .filter(UPLOAD_RETRY_EXCEPTION_PREDICATE)))
             .build();
 
-        testee = new S3BlobStoreDAO(s3Configuration, new TestBlobId.Factory(), 
new RecordingMetricFactory(), new NoopGaugeRegistry());
+        s3ClientFactory = new S3ClientFactory(s3Configuration, new 
RecordingMetricFactory(), new NoopGaugeRegistry());
+        testee = new S3BlobStoreDAO(s3ClientFactory, s3Configuration, new 
TestBlobId.Factory());
     }
 
     @AfterAll
     static void tearDownClass() {
-        testee.close();
+        s3ClientFactory.close();
     }
 
     @AfterEach
diff --git 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3NamespaceTest.java
 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3NamespaceTest.java
index fa1f898761..ea9c5ce7e1 100644
--- 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3NamespaceTest.java
+++ 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3NamespaceTest.java
@@ -36,6 +36,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
 class S3NamespaceTest implements BlobStoreContract {
     private static BlobStore testee;
     private static S3BlobStoreDAO s3BlobStoreDAO;
+    private static S3ClientFactory s3ClientFactory;
 
     @BeforeAll
     static void setUpClass(DockerAwsS3Container dockerAwsS3) {
@@ -52,7 +53,8 @@ class S3NamespaceTest implements BlobStoreContract {
             .build();
 
         HashBlobId.Factory blobIdFactory = new HashBlobId.Factory();
-        s3BlobStoreDAO = new S3BlobStoreDAO(s3Configuration, blobIdFactory, 
new RecordingMetricFactory(), new NoopGaugeRegistry());
+        s3ClientFactory = new S3ClientFactory(s3Configuration, new 
RecordingMetricFactory(), new NoopGaugeRegistry());
+        s3BlobStoreDAO = new S3BlobStoreDAO(s3ClientFactory, s3Configuration, 
blobIdFactory);
 
         testee = BlobStoreFactory.builder()
             .blobStoreDAO(s3BlobStoreDAO)
@@ -68,7 +70,7 @@ class S3NamespaceTest implements BlobStoreContract {
 
     @AfterAll
     static void tearDownClass() {
-        s3BlobStoreDAO.close();
+        s3ClientFactory.close();
     }
 
     @Override
diff --git 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3PassThroughBlobStoreTest.java
 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3PassThroughBlobStoreTest.java
index 6b6f316c58..516f0b7ade 100644
--- 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3PassThroughBlobStoreTest.java
+++ 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3PassThroughBlobStoreTest.java
@@ -37,6 +37,8 @@ class S3PassThroughBlobStoreTest implements BlobStoreContract 
{
     private static BlobStore testee;
     private static S3BlobStoreDAO s3BlobStoreDAO;
 
+    private static S3ClientFactory s3ClientFactory;
+
     @BeforeAll
     static void setUpClass(DockerAwsS3Container dockerAwsS3) {
         AwsS3AuthConfiguration authConfiguration = 
AwsS3AuthConfiguration.builder()
@@ -51,7 +53,8 @@ class S3PassThroughBlobStoreTest implements BlobStoreContract 
{
             .build();
 
         HashBlobId.Factory blobIdFactory = new HashBlobId.Factory();
-        s3BlobStoreDAO = new S3BlobStoreDAO(s3Configuration, blobIdFactory, 
new RecordingMetricFactory(), new NoopGaugeRegistry());
+        s3ClientFactory = new S3ClientFactory(s3Configuration, new 
RecordingMetricFactory(), new NoopGaugeRegistry());
+        s3BlobStoreDAO = new S3BlobStoreDAO(s3ClientFactory, s3Configuration, 
blobIdFactory);
 
         testee = BlobStoreFactory.builder()
             .blobStoreDAO(s3BlobStoreDAO)
@@ -67,7 +70,7 @@ class S3PassThroughBlobStoreTest implements BlobStoreContract 
{
 
     @AfterAll
     static void tearDownClass() {
-        s3BlobStoreDAO.close();
+        s3ClientFactory.close();
     }
 
     @Override
diff --git 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3PrefixAndNamespaceTest.java
 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3PrefixAndNamespaceTest.java
index 480e562552..dbfaf0425b 100644
--- 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3PrefixAndNamespaceTest.java
+++ 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3PrefixAndNamespaceTest.java
@@ -37,6 +37,8 @@ class S3PrefixAndNamespaceTest implements BlobStoreContract {
     private static BlobStore testee;
     private static S3BlobStoreDAO s3BlobStoreDAO;
 
+    private static S3ClientFactory s3ClientFactory;
+
     @BeforeAll
     static void setUpClass(DockerAwsS3Container dockerAwsS3) {
         AwsS3AuthConfiguration authConfiguration = 
AwsS3AuthConfiguration.builder()
@@ -53,7 +55,8 @@ class S3PrefixAndNamespaceTest implements BlobStoreContract {
             .build();
 
         HashBlobId.Factory blobIdFactory = new HashBlobId.Factory();
-        s3BlobStoreDAO = new S3BlobStoreDAO(s3Configuration, blobIdFactory, 
new RecordingMetricFactory(), new NoopGaugeRegistry());
+        s3ClientFactory = new S3ClientFactory(s3Configuration, new 
RecordingMetricFactory(), new NoopGaugeRegistry());
+        s3BlobStoreDAO = new S3BlobStoreDAO(s3ClientFactory, s3Configuration, 
blobIdFactory);
 
         testee = BlobStoreFactory.builder()
             .blobStoreDAO(s3BlobStoreDAO)
@@ -69,7 +72,7 @@ class S3PrefixAndNamespaceTest implements BlobStoreContract {
 
     @AfterAll
     static void tearDownClass() {
-        s3BlobStoreDAO.close();
+        s3ClientFactory.close();
     }
 
     @Override
diff --git 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3PrefixTest.java
 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3PrefixTest.java
index 1be11eff1a..72b867f480 100644
--- 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3PrefixTest.java
+++ 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3PrefixTest.java
@@ -35,6 +35,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
 class S3PrefixTest implements BlobStoreContract {
     private static BlobStore testee;
     private static S3BlobStoreDAO s3BlobStoreDAO;
+    private static S3ClientFactory s3ClientFactory;
 
     @BeforeAll
     static void setUpClass(DockerAwsS3Container dockerAwsS3) {
@@ -51,7 +52,8 @@ class S3PrefixTest implements BlobStoreContract {
             .build();
 
         HashBlobId.Factory blobIdFactory = new HashBlobId.Factory();
-        s3BlobStoreDAO = new S3BlobStoreDAO(s3Configuration, blobIdFactory, 
new RecordingMetricFactory(), new NoopGaugeRegistry());
+        s3ClientFactory = new S3ClientFactory(s3Configuration, new 
RecordingMetricFactory(), new NoopGaugeRegistry());
+        s3BlobStoreDAO = new S3BlobStoreDAO(s3ClientFactory, s3Configuration, 
blobIdFactory);
 
         testee = BlobStoreFactory.builder()
             .blobStoreDAO(s3BlobStoreDAO)
@@ -67,7 +69,7 @@ class S3PrefixTest implements BlobStoreContract {
 
     @AfterAll
     static void tearDownClass() {
-        s3BlobStoreDAO.close();
+        s3ClientFactory.close();
     }
 
     @Override


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org
For additional commands, e-mail: notifications-h...@james.apache.org

Reply via email to