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

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

commit 5ed599e4ed1130dc4b730f1405a5819ed6585c51
Author: TungTV <vtt...@linagora.com>
AuthorDate: Tue Nov 19 10:17:14 2024 +0700

    JAMES-4085 Introduce S3MinioExtension - support https
---
 server/blob/blob-s3/pom.xml                        |   6 ++
 .../blob/objectstorage/aws/S3MinioDocker.java      | 109 +++++++++++++++++++++
 .../blob/objectstorage/aws/S3MinioExtension.java   |  59 +++++++++++
 .../james/blob/objectstorage/aws/S3MinioTest.java  |  40 ++------
 .../blob-s3/src/test/resources/minio/private.key   |   5 +
 .../blob-s3/src/test/resources/minio/public.crt    |  14 +++
 6 files changed, 199 insertions(+), 34 deletions(-)

diff --git a/server/blob/blob-s3/pom.xml b/server/blob/blob-s3/pom.xml
index 2de0f6a4c1..01573fdaf7 100644
--- a/server/blob/blob-s3/pom.xml
+++ b/server/blob/blob-s3/pom.xml
@@ -56,6 +56,12 @@
             <groupId>${james.groupId}</groupId>
             <artifactId>james-core</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-guice-common</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>james-server-lifecycle-api</artifactId>
diff --git 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3MinioDocker.java
 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3MinioDocker.java
new file mode 100644
index 0000000000..54bf3e5a91
--- /dev/null
+++ 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3MinioDocker.java
@@ -0,0 +1,109 @@
+/****************************************************************
+ * 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.time.Duration;
+import java.util.UUID;
+
+import org.apache.http.client.utils.URIBuilder;
+import org.testcontainers.containers.BindMode;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.Network;
+import org.testcontainers.containers.wait.strategy.Wait;
+import org.testcontainers.utility.DockerImageName;
+
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+
+public class S3MinioDocker {
+
+    public static final DockerImageName DOCKER_IMAGE_NAME = 
DockerImageName.parse("minio/minio")
+        .withTag("RELEASE.2024-10-13T13-34-11Z");
+
+    public static final int MINIO_PORT = 9000;
+    public static final int MINIO_WEB_ADMIN_PORT = 9090;
+    public static final String MINIO_ROOT_USER = "minio";
+    public static final String MINIO_ROOT_PASSWORD = "minio123";
+
+    private final GenericContainer<?> container;
+
+    public S3MinioDocker() {
+        this.container = getContainer();
+    }
+
+    public S3MinioDocker(Network network) {
+        this.container = getContainer()
+            .withNetwork(network);
+    }
+
+    private GenericContainer<?> getContainer() {
+        return new GenericContainer<>(DOCKER_IMAGE_NAME)
+            .withExposedPorts(MINIO_PORT, MINIO_WEB_ADMIN_PORT)
+            .withEnv("MINIO_ROOT_USER", MINIO_ROOT_USER)
+            .withEnv("MINIO_ROOT_PASSWORD", MINIO_ROOT_PASSWORD)
+            .withCommand("server", "--certs-dir", "/opt/minio/certs", "/data", 
"--console-address", ":" + MINIO_WEB_ADMIN_PORT)
+            .withClasspathResourceMapping("/minio/private.key",
+                "/opt/minio/certs/private.key",
+                BindMode.READ_ONLY)
+            .withClasspathResourceMapping("/minio/public.crt",
+                "/opt/minio/certs/public.crt",
+                BindMode.READ_ONLY)
+            .waitingFor(Wait.forLogMessage(".*MinIO Object Storage Server.*", 
1)
+                .withStartupTimeout(Duration.ofMinutes(2)))
+            .withCreateContainerCmdModifier(createContainerCmd -> 
createContainerCmd.withName("james-minio-s3-test-" + UUID.randomUUID()));
+    }
+
+    public void start() {
+        if (!container.isRunning()) {
+            container.start();
+            setupMC();
+        }
+    }
+
+    public void stop() {
+        container.stop();
+    }
+
+    public AwsS3AuthConfiguration getAwsS3AuthConfiguration() {
+        Preconditions.checkArgument(container.isRunning(), "Container is not 
running");
+        return AwsS3AuthConfiguration.builder()
+            .endpoint(Throwing.supplier(() -> new URIBuilder()
+                .setScheme("https")
+                .setHost(container.getHost())
+                .setPort(container.getMappedPort(MINIO_PORT))
+                .build()).get())
+            .accessKeyId(MINIO_ROOT_USER)
+            .secretKey(MINIO_ROOT_PASSWORD)
+            .trustAll(true)
+            .build();
+    }
+
+    private void setupMC() {
+        Preconditions.checkArgument(container.isRunning(), "Container is not 
running");
+        Throwing.runnable(() -> container.execInContainer("mc", "alias", 
"set", "--insecure", "james", "https://localhost:9000";, MINIO_ROOT_USER, 
MINIO_ROOT_PASSWORD)).run();
+    }
+
+    public void flushAll() {
+        // Remove all objects
+        Throwing.runnable(() -> container.execInContainer("mc", "--insecure", 
"rm", "--recursive", "--force", "--dangerous", "james/")).run();
+        // Remove all buckets
+        Throwing.runnable(() -> container.execInContainer("mc", "--insecure", 
"rb", "--force", "--dangerous", "james/")).run();
+    }
+}
diff --git 
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3MinioExtension.java
 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3MinioExtension.java
new file mode 100644
index 0000000000..12d95b3170
--- /dev/null
+++ 
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3MinioExtension.java
@@ -0,0 +1,59 @@
+/****************************************************************
+ * 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 org.apache.james.GuiceModuleTestExtension;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+
+public class S3MinioExtension implements GuiceModuleTestExtension {
+
+    private static final S3MinioDocker s3MinioDocker = new S3MinioDocker();
+
+    @Override
+    public void beforeAll(ExtensionContext extensionContext) {
+        s3MinioDocker.start();
+    }
+
+    @Override
+    public void afterAll(ExtensionContext extensionContext) {
+        s3MinioDocker.stop();
+    }
+
+    @Override
+    public void afterEach(ExtensionContext extensionContext) {
+        s3MinioDocker.flushAll();
+    }
+
+    @Override
+    public boolean supportsParameter(ParameterContext parameterContext, 
ExtensionContext extensionContext) throws ParameterResolutionException {
+        return parameterContext.getParameter().getType() == 
S3MinioDocker.class;
+    }
+
+    @Override
+    public Object resolveParameter(ParameterContext parameterContext, 
ExtensionContext extensionContext) throws ParameterResolutionException {
+        return s3MinioDocker;
+    }
+
+    public S3MinioDocker minioDocker() {
+        return s3MinioDocker;
+    }
+}
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 6f372240f3..ad506127d2 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
@@ -22,15 +22,11 @@ package org.apache.james.blob.objectstorage.aws;
 import static org.apache.james.blob.api.BlobStoreDAOFixture.SHORT_BYTEARRAY;
 import static org.apache.james.blob.api.BlobStoreDAOFixture.TEST_BLOB_ID;
 import static org.apache.james.blob.api.BlobStoreDAOFixture.TEST_BUCKET_NAME;
-import static 
org.apache.james.blob.objectstorage.aws.DockerAwsS3Container.ACCESS_KEY_ID;
-import static 
org.apache.james.blob.objectstorage.aws.DockerAwsS3Container.SECRET_ACCESS_KEY;
 import static 
org.apache.james.blob.objectstorage.aws.S3BlobStoreConfiguration.UPLOAD_RETRY_EXCEPTION_PREDICATE;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
-import java.net.URI;
 import java.util.Optional;
-import java.util.UUID;
 import java.util.concurrent.ExecutionException;
 
 import org.apache.james.blob.api.BlobId;
@@ -40,50 +36,31 @@ import org.apache.james.blob.api.TestBlobId;
 import org.apache.james.metrics.api.NoopGaugeRegistry;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
 import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
-import org.testcontainers.containers.GenericContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
+import org.junit.jupiter.api.extension.RegisterExtension;
 
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 import reactor.util.retry.Retry;
 import software.amazon.awssdk.services.s3.model.S3Exception;
 
-@Testcontainers
 public class S3MinioTest implements BlobStoreDAOContract {
 
-    private static final String MINIO_IMAGE = "minio/minio";
-    private static final String MINIO_TAG = "RELEASE.2024-10-13T13-34-11Z";
-    private static final String MINIO_IMAGE_FULL = MINIO_IMAGE + ":" + 
MINIO_TAG;
-    private static final int MINIO_PORT = 9000;
-    private static S3BlobStoreDAO testee;
+    @RegisterExtension
+    static S3MinioExtension minoExtension = new S3MinioExtension();
 
+    private static S3BlobStoreDAO testee;
     private static S3ClientFactory s3ClientFactory;
 
-    @Container
-    private static final GenericContainer<?> minioContainer = new 
GenericContainer<>(MINIO_IMAGE_FULL)
-        .withExposedPorts(MINIO_PORT)
-        .withEnv("MINIO_ROOT_USER", ACCESS_KEY_ID)
-        .withEnv("MINIO_ROOT_PASSWORD", SECRET_ACCESS_KEY)
-        .withCommand("server", "/data", "--console-address", ":9090")
-        .withCreateContainerCmdModifier(createContainerCmd -> 
createContainerCmd.withName("james-minio-s3-test-" + UUID.randomUUID()));
-
-
     @BeforeAll
     static void setUp() {
-        AwsS3AuthConfiguration authConfiguration = 
AwsS3AuthConfiguration.builder()
-            .endpoint(URI.create(String.format("http://%s:%s/";, 
minioContainer.getHost(), minioContainer.getMappedPort(MINIO_PORT))))
-            .accessKeyId(ACCESS_KEY_ID)
-            .secretKey(SECRET_ACCESS_KEY)
-            .build();
+        AwsS3AuthConfiguration awsS3AuthConfiguration = 
minoExtension.minioDocker().getAwsS3AuthConfiguration();
 
         S3BlobStoreConfiguration s3Configuration = 
S3BlobStoreConfiguration.builder()
-            .authConfiguration(authConfiguration)
+            .authConfiguration(awsS3AuthConfiguration)
             .region(DockerAwsS3Container.REGION)
             .uploadRetrySpec(Optional.of(Retry.backoff(3, 
java.time.Duration.ofSeconds(1))
                 .filter(UPLOAD_RETRY_EXCEPTION_PREDICATE)))
@@ -98,11 +75,6 @@ public class S3MinioTest implements BlobStoreDAOContract {
         s3ClientFactory.close();
     }
 
-    @AfterEach
-    void tearDown() {
-        testee.deleteAllBuckets().block();
-    }
-
     @BeforeEach
     void beforeEach() throws Exception {
         // Why? 
https://github.com/apache/james-project/pull/1981#issuecomment-2380396460
diff --git a/server/blob/blob-s3/src/test/resources/minio/private.key 
b/server/blob/blob-s3/src/test/resources/minio/private.key
new file mode 100644
index 0000000000..f829a5dd37
--- /dev/null
+++ b/server/blob/blob-s3/src/test/resources/minio/private.key
@@ -0,0 +1,5 @@
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgDhp6TEYrEFHMHusJ
+Xstem4lh0czPokiWEdAzzMXRXxGhRANCAAQ7jB4mm+Rieqr3lQfdc1xoPsgAltNP
+CvUYDZyu5903CkLiDuhBU6UWvQP5F19XFt95RkaYDPvc6ka0485NWFMb
+-----END PRIVATE KEY-----
diff --git a/server/blob/blob-s3/src/test/resources/minio/public.crt 
b/server/blob/blob-s3/src/test/resources/minio/public.crt
new file mode 100644
index 0000000000..5a6013846c
--- /dev/null
+++ b/server/blob/blob-s3/src/test/resources/minio/public.crt
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICFjCCAbugAwIBAgIRAK8/sg1OIuWOQV2gWo9vDQUwCgYIKoZIzj0EAwIwTTEc
+MBoGA1UEChMTQ2VydGdlbiBEZXZlbG9wbWVudDEtMCsGA1UECwwkdHVuZ3R2QE1h
+Y0Jvb2stUHJvLmxvY2FsIChUcmFuIFR1bmcpMB4XDTI0MDkyNjAyNDcwNFoXDTI1
+MDkyNjAyNDcwNFowTTEcMBoGA1UEChMTQ2VydGdlbiBEZXZlbG9wbWVudDEtMCsG
+A1UECwwkdHVuZ3R2QE1hY0Jvb2stUHJvLmxvY2FsIChUcmFuIFR1bmcpMFkwEwYH
+KoZIzj0CAQYIKoZIzj0DAQcDQgAEO4weJpvkYnqq95UH3XNcaD7IAJbTTwr1GA2c
+rufdNwpC4g7oQVOlFr0D+RdfVxbfeUZGmAz73OpGtOPOTVhTG6N8MHowDgYDVR0P
+AQH/BAQDAgKkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8w
+HQYDVR0OBBYEFKIu0NT9bG853GA+o10GsbDOi9zMMCMGA1UdEQQcMBqCCWxvY2Fs
+aG9zdIINczNtaW5pby5sb2NhbDAKBggqhkjOPQQDAgNJADBGAiEAxLfNK4gPWw0G
+8QAv0QzARY0L5+8Lmpf5SwVzrjZ+zosCIQCA41tgccZ20+W1igansLkqnSTcY8Nw
+mtKwMTxUEwNRTw==
+-----END CERTIFICATE-----


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

Reply via email to