This is an automated email from the ASF dual-hosted git repository. rouazana pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit fa24a096a5853459c3769a34ccc68feb91626bfa Author: Antoine Duprat <[email protected]> AuthorDate: Mon Mar 4 14:35:11 2019 +0100 JAMES-2671 Introduce AWS S3 blob store implementation --- server/blob/blob-objectstorage/pom.xml | 5 ++ .../james/blob/objectstorage/AESPayloadCodec.java | 72 +++++++++++------- .../blob/objectstorage/ObjectStorageBlobsDAO.java | 6 ++ .../blob/objectstorage/aws/AwsS3ObjectStorage.java | 67 +++++++++++++++++ .../blob/objectstorage/AESPayloadCodecTest.java | 10 +-- .../aws/AwsS3ObjectStorageBlobsDAOBuilderTest.java | 85 ++++++++++++++++++++++ .../objectstorage/aws/DockerAwsS3Container.java | 71 ++++++++++++++++++ .../objectstorage/aws/DockerAwsS3Extension.java | 53 ++++++++++++++ .../src/test/resources/logback-test.xml | 1 + .../ObjectStorageDependenciesModule.java | 9 ++- 10 files changed, 344 insertions(+), 35 deletions(-) diff --git a/server/blob/blob-objectstorage/pom.xml b/server/blob/blob-objectstorage/pom.xml index 09db947..2cddbd9 100644 --- a/server/blob/blob-objectstorage/pom.xml +++ b/server/blob/blob-objectstorage/pom.xml @@ -81,6 +81,11 @@ <version>${jclouds.version}</version> </dependency> <dependency> + <groupId>org.apache.jclouds.api</groupId> + <artifactId>s3</artifactId> + <version>${jclouds.version}</version> + </dependency> + <dependency> <groupId>org.apache.jclouds.driver</groupId> <artifactId>jclouds-slf4j</artifactId> <version>${jclouds.version}</version> diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/AESPayloadCodec.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/AESPayloadCodec.java index b92f73a..ca0e54d 100644 --- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/AESPayloadCodec.java +++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/AESPayloadCodec.java @@ -19,51 +19,67 @@ package org.apache.james.blob.objectstorage; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; +import java.math.BigInteger; import java.security.GeneralSecurityException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; import java.util.Optional; -import java.util.concurrent.atomic.AtomicLong; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + +import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.james.blob.objectstorage.crypto.CryptoConfig; -import org.apache.james.blob.objectstorage.crypto.PBKDF2StreamingAeadFactory; import org.jclouds.io.Payloads; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.crypto.tink.subtle.AesGcmHkdfStreaming; +import com.google.common.io.ByteSource; +import com.google.common.io.FileBackedOutputStream; +import com.google.crypto.tink.Aead; +import com.google.crypto.tink.aead.AeadConfig; +import com.google.crypto.tink.subtle.AesGcmJce; public class AESPayloadCodec implements PayloadCodec { + private static final Logger LOGGER = LoggerFactory.getLogger(AESPayloadCodec.class); - private final AesGcmHkdfStreaming streamingAead; + private static final byte[] EMPTY_ASSOCIATED_DATA = new byte[0]; + private static final int PBKDF2_ITERATIONS = 65536; + private static final int KEY_SIZE = 256; + private static final String SECRET_KEY_FACTORY_ALGORITHM = "PBKDF2WithHmacSHA256"; + private static final BigInteger MAX_BYTES = FileUtils.ONE_MB_BI; + + private final Aead aead; public AESPayloadCodec(CryptoConfig cryptoConfig) { - streamingAead = PBKDF2StreamingAeadFactory.newAesGcmHkdfStreaming(cryptoConfig); + try { + AeadConfig.register(); + + SecretKey secretKey = deriveKey(cryptoConfig); + aead = new AesGcmJce(secretKey.getEncoded()); + } catch (GeneralSecurityException e) { + throw new RuntimeException("Error while starting AESPayloadCodec", e); + } + } + + private static SecretKey deriveKey(CryptoConfig cryptoConfig) throws NoSuchAlgorithmException, InvalidKeySpecException { + byte[] saltBytes = cryptoConfig.salt(); + SecretKeyFactory skf = SecretKeyFactory.getInstance(SECRET_KEY_FACTORY_ALGORITHM); + PBEKeySpec spec = new PBEKeySpec(cryptoConfig.password(), saltBytes, PBKDF2_ITERATIONS, KEY_SIZE); + return skf.generateSecret(spec); } @Override - public Payload write(InputStream is) { - PipedInputStream snk = new PipedInputStream(); - try { - AtomicLong length = new AtomicLong(); - PipedOutputStream src = new PipedOutputStream(snk); - OutputStream outputStream = streamingAead.newEncryptingStream(src, PBKDF2StreamingAeadFactory.EMPTY_ASSOCIATED_DATA); - Thread copyThread = new Thread(() -> { - try (OutputStream stream = outputStream) { - length.addAndGet(IOUtils.copy(is, stream)); - } catch (IOException e) { - throw new RuntimeException("Stream copy failure ", e); - } - }); - copyThread.setUncaughtExceptionHandler((Thread t, Throwable e) -> - LOGGER.error("Unable to encrypt payload's input stream",e) - ); - copyThread.start(); - return new Payload(Payloads.newInputStreamPayload(snk), Optional.of(length.get())); + public Payload write(InputStream inputStream) { + try (FileBackedOutputStream outputStream = new FileBackedOutputStream(MAX_BYTES.intValue())) { + outputStream.write(aead.encrypt(IOUtils.toByteArray(inputStream), EMPTY_ASSOCIATED_DATA)); + ByteSource data = outputStream.asByteSource(); + return new Payload(Payloads.newByteSourcePayload(data), Optional.of(Long.valueOf(data.size()))); } catch (IOException | GeneralSecurityException e) { throw new RuntimeException("Unable to build payload for object storage, failed to " + "encrypt", e); @@ -73,7 +89,9 @@ public class AESPayloadCodec implements PayloadCodec { @Override public InputStream read(Payload payload) throws IOException { try { - return streamingAead.newDecryptingStream(payload.getPayload().openStream(), PBKDF2StreamingAeadFactory.EMPTY_ASSOCIATED_DATA); + byte[] ciphertext = IOUtils.toByteArray(payload.getPayload().openStream()); + byte[] decrypt = aead.decrypt(ciphertext, EMPTY_ASSOCIATED_DATA); + return new ByteArrayInputStream(decrypt); } catch (GeneralSecurityException e) { throw new IOException("Incorrect crypto setup", e); } diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java index d870912..857553d 100644 --- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java +++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java @@ -28,6 +28,8 @@ import org.apache.commons.io.IOUtils; import org.apache.james.blob.api.BlobId; import org.apache.james.blob.api.BlobStore; import org.apache.james.blob.api.ObjectStoreException; +import org.apache.james.blob.objectstorage.aws.AwsS3AuthConfiguration; +import org.apache.james.blob.objectstorage.aws.AwsS3ObjectStorage; import org.apache.james.blob.objectstorage.swift.SwiftKeystone2ObjectStorage; import org.apache.james.blob.objectstorage.swift.SwiftKeystone3ObjectStorage; import org.apache.james.blob.objectstorage.swift.SwiftTempAuthObjectStorage; @@ -73,6 +75,10 @@ public class ObjectStorageBlobsDAO implements BlobStore { return SwiftKeystone3ObjectStorage.daoBuilder(testConfig); } + public static ObjectStorageBlobsDAOBuilder.RequireContainerName builder(AwsS3AuthConfiguration testConfig) { + return AwsS3ObjectStorage.daoBuilder(testConfig); + } + public Mono<ContainerName> createContainer(ContainerName name) { return Mono.fromCallable(() -> blobStore.createContainerInLocation(DEFAULT_LOCATION, name.value())) .filter(created -> created == false) diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorage.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorage.java new file mode 100644 index 0000000..be5eac5 --- /dev/null +++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorage.java @@ -0,0 +1,67 @@ +/* + * 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.util.Properties; +import java.util.function.Supplier; + +import org.apache.james.blob.objectstorage.ObjectStorageBlobsDAOBuilder; +import org.jclouds.ContextBuilder; +import org.jclouds.blobstore.BlobStore; +import org.jclouds.blobstore.BlobStoreContext; +import org.jclouds.logging.slf4j.config.SLF4JLoggingModule; + +import com.google.common.collect.ImmutableSet; +import com.google.inject.Module; + +public class AwsS3ObjectStorage { + + private static final Iterable<Module> JCLOUDS_MODULES = + ImmutableSet.of(new SLF4JLoggingModule()); + + public static ObjectStorageBlobsDAOBuilder.RequireContainerName daoBuilder(AwsS3AuthConfiguration configuration) { + return ObjectStorageBlobsDAOBuilder.forBlobStore(new BlobStoreBuilder(configuration)); + } + + private static class BlobStoreBuilder implements Supplier<BlobStore> { + private final AwsS3AuthConfiguration configuration; + + private BlobStoreBuilder(AwsS3AuthConfiguration configuration) { + this.configuration = configuration; + } + + public BlobStore get() { + Properties overrides = new Properties(); + overrides.setProperty("PROPERTY_S3_VIRTUAL_HOST_BUCKETS", "false"); + + return contextBuilder() + .endpoint(configuration.getEndpoint()) + .credentials(configuration.getAccessKeyId(), configuration.getSecretKey()) + .overrides(overrides) + .modules(JCLOUDS_MODULES) + .buildView(BlobStoreContext.class) + .getBlobStore(); + } + + private ContextBuilder contextBuilder() { + return ContextBuilder.newBuilder("s3"); + } + } +} diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/AESPayloadCodecTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/AESPayloadCodecTest.java index 3127916..9fbd588 100644 --- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/AESPayloadCodecTest.java +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/AESPayloadCodecTest.java @@ -26,6 +26,8 @@ import java.io.ByteArrayInputStream; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Base64; import java.util.Optional; import org.apache.commons.io.IOUtils; @@ -37,7 +39,7 @@ import org.junit.jupiter.api.Test; import com.google.crypto.tink.subtle.Hex; class AESPayloadCodecTest implements PayloadCodecContract { - private static final byte[] ENCRYPTED_BYTES = Hex.decode("28cdfb53c283185598ec7c49c415c6b56e85d3d74af89740270c2d2cd8006e1265a301436d919ed7acfc14586b5bd193e34c744ef1641230457dae3475"); + private static final byte[] ENCRYPTED_BYTES = Hex.decode("0d5321372dae79366a2cc4ca7f52a9acd9bb6408e50a6bcb7b0008d0b10c90db46"); @Override public PayloadCodec codec() { @@ -83,10 +85,6 @@ class AESPayloadCodecTest implements PayloadCodecContract { } }), Optional.empty()); - int i = ENCRYPTED_BYTES.length / 2; - byte[] bytes = new byte[i]; - InputStream is = codec().read(payload); - assertThatThrownBy(() -> is.read(bytes, 0, i)).isInstanceOf(IOException.class); - + assertThatThrownBy(() -> codec().read(payload)).isInstanceOf(IOException.class); } } diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorageBlobsDAOBuilderTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorageBlobsDAOBuilderTest.java new file mode 100644 index 0000000..afa6447 --- /dev/null +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorageBlobsDAOBuilderTest.java @@ -0,0 +1,85 @@ +/* + * 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 static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.UUID; + +import org.apache.james.blob.api.HashBlobId; +import org.apache.james.blob.objectstorage.ContainerName; +import org.apache.james.blob.objectstorage.ObjectStorageBlobsDAO; +import org.apache.james.blob.objectstorage.ObjectStorageBlobsDAOBuilder; +import org.apache.james.blob.objectstorage.ObjectStorageBlobsDAOContract; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +@ExtendWith(DockerAwsS3Extension.class) +class AwsS3ObjectStorageBlobsDAOBuilderTest implements ObjectStorageBlobsDAOContract { + + private ContainerName containerName; + private AwsS3AuthConfiguration configuration; + + @BeforeEach + void setUp(DockerAwsS3Container dockerAwsS3Container) { + containerName = ContainerName.of(UUID.randomUUID().toString()); + configuration = AwsS3AuthConfiguration.builder() + .endpoint(dockerAwsS3Container.getEndpoint()) + .accessKeyId(DockerAwsS3Container.SCALITY_ACCESS_KEY_ID) + .secretKey(DockerAwsS3Container.SCALITY_SECRET_ACCESS_KEY) + .build(); + } + + @Override + public ContainerName containerName() { + return containerName; + } + + @Test + void containerNameIsMandatoryToBuildBlobsDAO() { + ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO + .builder(configuration) + .container(null) + .blobIdFactory(new HashBlobId.Factory()); + + assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class); + } + + @Test + void blobIdFactoryIsMandatoryToBuildBlobsDAO() { + ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO + .builder(configuration) + .container(containerName) + .blobIdFactory(null); + + assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class); + } + + @Test + void builtBlobsDAOCanStoreAndRetrieve() { + ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO + .builder(configuration) + .container(containerName) + .blobIdFactory(new HashBlobId.Factory()); + + assertBlobsDAOCanStoreAndRetrieve(builder); + } +} \ No newline at end of file diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/aws/DockerAwsS3Container.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/aws/DockerAwsS3Container.java new file mode 100644 index 0000000..bef1009 --- /dev/null +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/aws/DockerAwsS3Container.java @@ -0,0 +1,71 @@ +/* + * 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.util.Host; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; + +public class DockerAwsS3Container { + + private static final String AWS_S3_DOCKER_IMAGE = "scality/s3server:mem-6018536a"; + private static final int AWS_S3_PORT = 8000; + private static final int ONE_TIME = 1; + + public static final String SCALITY_ACCESS_KEY_ID = "newAccessKey"; + public static final String SCALITY_SECRET_ACCESS_KEY = "newSecretKey"; + + private final GenericContainer<?> awsS3Container; + + public DockerAwsS3Container() { + this.awsS3Container = new GenericContainer<>(AWS_S3_DOCKER_IMAGE); + this.awsS3Container + .withExposedPorts(AWS_S3_PORT) + .withEnv("S3BACKEND", "mem") + .withEnv("SCALITY_ACCESS_KEY_ID", SCALITY_ACCESS_KEY_ID) + .withEnv("SCALITY_SECRET_ACCESS_KEY", SCALITY_SECRET_ACCESS_KEY) + .withEnv("LOG_LEVEL", "trace") + .waitingFor(Wait.forLogMessage(".*\"message\":\"server started\".*\\n", ONE_TIME)); + } + + public void start() { + awsS3Container.start(); + } + + public void stop() { + awsS3Container.stop(); + } + + public Host getHost() { + return Host.from(getIp(), getPort()); + } + + public String getIp() { + return awsS3Container.getContainerIpAddress(); + } + + public int getPort() { + return awsS3Container.getMappedPort(AWS_S3_PORT); + } + + public String getEndpoint() { + return "http://" + getIp() + ":" + getPort() + "/"; + } +} diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/aws/DockerAwsS3Extension.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/aws/DockerAwsS3Extension.java new file mode 100644 index 0000000..571fbb5 --- /dev/null +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/aws/DockerAwsS3Extension.java @@ -0,0 +1,53 @@ +/* + * 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.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolutionException; +import org.junit.jupiter.api.extension.ParameterResolver; + +public class DockerAwsS3Extension implements ParameterResolver, BeforeAllCallback, AfterAllCallback { + + private DockerAwsS3Container awsS3Container; + + @Override + public void beforeAll(ExtensionContext context) { + awsS3Container = new DockerAwsS3Container(); + awsS3Container.start(); + } + + @Override + public void afterAll(ExtensionContext context) { + awsS3Container.stop(); + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { + return (parameterContext.getParameter().getType() == DockerAwsS3Container.class); + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { + return awsS3Container; + } +} diff --git a/server/blob/blob-objectstorage/src/test/resources/logback-test.xml b/server/blob/blob-objectstorage/src/test/resources/logback-test.xml index b48b76f..8bcda7f 100644 --- a/server/blob/blob-objectstorage/src/test/resources/logback-test.xml +++ b/server/blob/blob-objectstorage/src/test/resources/logback-test.xml @@ -35,5 +35,6 @@ </root> + <logger name="jclouds.headers" level="DEBUG"/> <logger name="org.apache.james" level="ERROR"/> </configuration> \ No newline at end of file diff --git a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageDependenciesModule.java b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageDependenciesModule.java index a4acb21..56ec3cd 100644 --- a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageDependenciesModule.java +++ b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageDependenciesModule.java @@ -32,6 +32,8 @@ import org.apache.james.blob.api.BlobId; import org.apache.james.blob.api.HashBlobId; import org.apache.james.blob.objectstorage.ObjectStorageBlobsDAO; import org.apache.james.blob.objectstorage.ObjectStorageBlobsDAOBuilder; +import org.apache.james.blob.objectstorage.aws.AwsS3AuthConfiguration; +import org.apache.james.blob.objectstorage.aws.AwsS3ObjectStorage; import org.apache.james.modules.mailbox.ConfigurationComponent; import org.apache.james.modules.objectstorage.swift.SwiftObjectStorage; import org.apache.james.utils.PropertiesProvider; @@ -71,8 +73,11 @@ public class ObjectStorageDependenciesModule extends AbstractModule { } private ObjectStorageBlobsDAOBuilder.RequireContainerName selectDaoBuilder(ObjectStorageBlobConfiguration configuration) { - if (configuration.getProvider() == ObjectStorageProvider.SWIFT) { - return SwiftObjectStorage.builder(configuration); + switch (configuration.getProvider()) { + case SWIFT: + return SwiftObjectStorage.builder(configuration); + case AWSS3: + return AwsS3ObjectStorage.daoBuilder((AwsS3AuthConfiguration) configuration.getSpecificAuthConfiguration()); } throw new IllegalArgumentException("unknown provider " + configuration.getProvider()); } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
