You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ro...@apache.org on 2019/03/22 16:18:48 UTC
[james-project] 04/04: JAMES-2671 Introduce AWS S3 blob store
implementation
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 <ad...@linagora.com>
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: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org