JAMES-2589 configuration file parsing is now done in a dedicated class

Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/4d07616f
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/4d07616f
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/4d07616f

Branch: refs/heads/master
Commit: 4d07616f1b1f54e36d506a1356a26a9f074b995c
Parents: 902e805
Author: Matthieu Baechler <matth...@apache.org>
Authored: Mon Nov 12 17:35:10 2018 +0100
Committer: Benoit Tellier <btell...@linagora.com>
Committed: Wed Nov 14 11:19:34 2018 +0700

----------------------------------------------------------------------
 .../guice/blob-objectstorage-guice/pom.xml      |   5 +
 .../ObjectStorageBlobConfiguration.java         | 308 +++++++++++++++++++
 .../ObjectStorageBlobStoreModule.java           |  10 +-
 .../ObjectStorageBlobsDAOProvider.java          | 105 -------
 .../ObjectStorageDependenciesModule.java        |  94 ++++++
 .../objectstorage/PayloadCodecFactory.java      |  43 +++
 .../objectstorage/PayloadCodecProvider.java     |  60 ----
 .../modules/objectstorage/PayloadCodecs.java    |  59 ----
 .../ObjectStorageBlobConfigurationTest.java     | 249 +++++++++++++++
 .../ObjectStorageBlobStoreModuleTest.java       | 130 ++++++++
 .../ObjectStorageBlobsDAOProviderTest.java      | 138 ---------
 .../objectstorage/PayloadCodecProviderTest.java | 169 ----------
 .../guice/DockerSwiftTestRule.java              |  21 +-
 .../objectstore/BlobStoreChoosingModule.java    |   7 +-
 .../cucumber/CucumberSwiftSingleton.java        |   4 +-
 15 files changed, 849 insertions(+), 553 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/4d07616f/server/container/guice/blob-objectstorage-guice/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/blob-objectstorage-guice/pom.xml 
b/server/container/guice/blob-objectstorage-guice/pom.xml
index 4ac1e36..2987465 100644
--- a/server/container/guice/blob-objectstorage-guice/pom.xml
+++ b/server/container/guice/blob-objectstorage-guice/pom.xml
@@ -72,6 +72,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.junit.platform</groupId>
             <artifactId>junit-platform-launcher</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/4d07616f/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageBlobConfiguration.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageBlobConfiguration.java
 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageBlobConfiguration.java
new file mode 100644
index 0000000..a58a8d9
--- /dev/null
+++ 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageBlobConfiguration.java
@@ -0,0 +1,308 @@
+/****************************************************************
+ * 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.modules.objectstorage;
+
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.Optional;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.james.blob.objectstorage.ContainerName;
+import org.apache.james.blob.objectstorage.swift.SwiftKeystone2ObjectStorage;
+import org.apache.james.blob.objectstorage.swift.SwiftKeystone3ObjectStorage;
+import org.apache.james.blob.objectstorage.swift.SwiftTempAuthObjectStorage;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Strings;
+
+public class ObjectStorageBlobConfiguration {
+
+    private static final String OBJECTSTORAGE_CONFIGURATION_NAME = 
"objectstorage";
+    private static final String OBJECTSTORAGE_NAMESPACE = 
"objectstorage.namespace";
+    private static final String OBJECTSTORAGE_PROVIDER = 
"objectstorage.provider";
+    private static final String OBJECTSTORAGE_SWIFT_AUTH_API = 
"objectstorage.swift.authapi";
+    private static final String OBJECTSTORAGE_PAYLOAD_CODEC = 
"objectstorage.payload.codec";
+    public static final String OBJECTSTORAGE_AES256_HEXSALT = 
"objectstorage.aes256.hexsalt";
+    public static final String OBJECTSTORAGE_AES256_PASSWORD = 
"objectstorage.aes256.password";
+
+    public static ObjectStorageBlobConfiguration from(Configuration 
configuration) throws ConfigurationException {
+        String provider = configuration.getString(OBJECTSTORAGE_PROVIDER, 
null);
+        String namespace = configuration.getString(OBJECTSTORAGE_NAMESPACE, 
null);
+        String authApi = configuration.getString(OBJECTSTORAGE_SWIFT_AUTH_API, 
null);
+        String codecName = 
configuration.getString(OBJECTSTORAGE_PAYLOAD_CODEC, null);
+        Optional<String> aesSalt = 
Optional.ofNullable(configuration.getString(OBJECTSTORAGE_AES256_HEXSALT, 
null));
+        Optional<char[]> aesPassword = 
Optional.ofNullable(configuration.getString(OBJECTSTORAGE_AES256_PASSWORD, 
null))
+            .map(String::toCharArray);
+
+        if (Strings.isNullOrEmpty(provider)) {
+            throw new ConfigurationException("Mandatory configuration value " 
+ OBJECTSTORAGE_PROVIDER + " is missing from " + 
OBJECTSTORAGE_CONFIGURATION_NAME + " configuration");
+        }
+        if (Strings.isNullOrEmpty(authApi)) {
+            throw new ConfigurationException("Mandatory configuration value " 
+ OBJECTSTORAGE_SWIFT_AUTH_API + " is missing from " + 
OBJECTSTORAGE_CONFIGURATION_NAME + " configuration");
+        }
+        if (Strings.isNullOrEmpty(namespace)) {
+            throw new ConfigurationException("Mandatory configuration value " 
+ OBJECTSTORAGE_NAMESPACE + " is missing from " + 
OBJECTSTORAGE_CONFIGURATION_NAME + " configuration");
+        }
+        if (Strings.isNullOrEmpty(codecName)) {
+            throw new ConfigurationException("Mandatory configuration value " 
+ OBJECTSTORAGE_PAYLOAD_CODEC  + " is missing from " + 
OBJECTSTORAGE_CONFIGURATION_NAME + " configuration");
+        }
+
+        PayloadCodecFactory payloadCodecFactory = 
Arrays.stream(PayloadCodecFactory.values())
+            .filter(name -> name.name().equals(codecName))
+            .findAny()
+            .orElseThrow(() -> new ConfigurationException("unknown payload 
codec : " + codecName));
+
+        Builder.RequireAuthConfiguration requireAuthConfiguration = builder()
+            .codec(payloadCodecFactory)
+            .swift()
+            .container(ContainerName.of(namespace));
+
+        return defineAuthApi(configuration, authApi, requireAuthConfiguration)
+            .aesSalt(aesSalt)
+            .aesPassword(aesPassword)
+            .build();
+    }
+
+    private static Builder.ReadyToBuild defineAuthApi(Configuration 
configuration, String authApi, Builder.RequireAuthConfiguration 
requireAuthConfiguration) {
+        switch (authApi) {
+            case SwiftTempAuthObjectStorage.AUTH_API_NAME:
+                return 
requireAuthConfiguration.tempAuth(SwiftTmpAuthConfigurationReader.readSwiftConfiguration(configuration));
+            case SwiftKeystone2ObjectStorage.AUTH_API_NAME:
+                return 
requireAuthConfiguration.keystone2(SwiftKeystone2ConfigurationReader.readSwiftConfiguration(configuration));
+            case SwiftKeystone3ObjectStorage.AUTH_API_NAME:
+                return 
requireAuthConfiguration.keystone3(SwiftKeystone3ConfigurationReader.readSwiftConfiguration(configuration));
+        }
+        throw new IllegalStateException("unexpected auth api " + authApi);
+    }
+
+
+    public static Builder.RequirePayloadCodec builder() {
+        return payloadCodec -> () -> container -> new 
Builder.RequireAuthConfiguration(payloadCodec,"swift", container);
+    }
+
+    public interface Builder {
+        @FunctionalInterface
+        public interface RequirePayloadCodec {
+            RequireProvider codec(PayloadCodecFactory codec);
+        }
+
+        @FunctionalInterface
+        public interface RequireProvider {
+            RequireContainerName swift();
+        }
+
+        @FunctionalInterface
+        public interface RequireContainerName {
+            RequireAuthConfiguration container(ContainerName container);
+        }
+
+        public static class RequireAuthConfiguration {
+
+            private final PayloadCodecFactory payloadCodec;
+            private final String provider;
+            private final ContainerName container;
+
+            private RequireAuthConfiguration(PayloadCodecFactory payloadCodec, 
String provider, ContainerName container) {
+                this.payloadCodec = payloadCodec;
+                this.provider = provider;
+                this.container = container;
+            }
+
+            public ReadyToBuild 
tempAuth(SwiftTempAuthObjectStorage.Configuration authConfig) {
+                return new ReadyToBuild(payloadCodec, provider, container, 
SwiftTempAuthObjectStorage.AUTH_API_NAME, Optional.of(authConfig), 
Optional.empty(), Optional.empty());
+            }
+
+            public ReadyToBuild 
keystone2(SwiftKeystone2ObjectStorage.Configuration authConfig) {
+                return new ReadyToBuild(payloadCodec, provider, container, 
SwiftKeystone2ObjectStorage.AUTH_API_NAME, Optional.empty(), 
Optional.of(authConfig), Optional.empty());
+            }
+
+            public ReadyToBuild 
keystone3(SwiftKeystone3ObjectStorage.Configuration authConfig) {
+                return new ReadyToBuild(payloadCodec, provider, container, 
SwiftKeystone3ObjectStorage.AUTH_API_NAME, Optional.empty(), Optional.empty(), 
Optional.of(authConfig));
+            }
+        }
+
+        public static class ReadyToBuild {
+
+            private final PayloadCodecFactory payloadCodecFactory;
+            private final String provider;
+            private final ContainerName container;
+            private final String authApiName;
+            private final Optional<SwiftTempAuthObjectStorage.Configuration> 
tempAuth;
+            private final Optional<SwiftKeystone2ObjectStorage.Configuration> 
keystone2Configuration;
+            private final Optional<SwiftKeystone3ObjectStorage.Configuration> 
keystone3Configuration;
+            private Optional<String> aesSalt;
+            private Optional<char[]> aesPassword;
+
+            public ReadyToBuild(PayloadCodecFactory payloadCodecFactory, 
String provider, ContainerName container, String authApiName,
+                                
Optional<SwiftTempAuthObjectStorage.Configuration> tempAuth,
+                                
Optional<SwiftKeystone2ObjectStorage.Configuration> keystone2Configuration,
+                                
Optional<SwiftKeystone3ObjectStorage.Configuration> keystone3Configuration) {
+                this.aesSalt = Optional.empty();
+                this.aesPassword = Optional.empty();
+                this.payloadCodecFactory = payloadCodecFactory;
+                this.provider = provider;
+                this.container = container;
+                this.authApiName = authApiName;
+                this.tempAuth = tempAuth;
+                this.keystone2Configuration = keystone2Configuration;
+                this.keystone3Configuration = keystone3Configuration;
+            }
+
+            public ReadyToBuild aesSalt(String aesSalt) {
+                return aesSalt(Optional.of(aesSalt));
+            }
+
+            public ReadyToBuild aesSalt(Optional<String> aesSalt) {
+                this.aesSalt = aesSalt;
+                return this;
+            }
+
+            public ReadyToBuild aesPassword(char[] aesPassword) {
+                return aesPassword(Optional.of(aesPassword));
+            }
+
+            public ReadyToBuild aesPassword(Optional<char[]> aesPassword) {
+                this.aesPassword = aesPassword;
+                return this;
+            }
+
+            public ObjectStorageBlobConfiguration build() {
+                if (payloadCodecFactory == PayloadCodecFactory.AES256) {
+                    aesSalt.filter(s -> !s.isEmpty())
+                        .orElseThrow(() -> new IllegalStateException("AES code 
requires an non-empty salt parameter"));
+                    aesPassword.filter(s -> s.length > 0)
+                        .orElseThrow(() -> new IllegalStateException("AES code 
requires an non-empty password parameter"));
+                }
+
+                return new ObjectStorageBlobConfiguration(payloadCodecFactory, 
provider, container, aesSalt, aesPassword,
+                    authApiName, tempAuth, keystone2Configuration, 
keystone3Configuration);
+            }
+
+        }
+
+    }
+
+    private final PayloadCodecFactory payloadCodec;
+    private final String authApi;
+    private final ContainerName namespace;
+    private final String provider;
+    private final Optional<SwiftTempAuthObjectStorage.Configuration> tempAuth;
+    private final Optional<SwiftKeystone2ObjectStorage.Configuration> 
keystone2Configuration;
+    private final Optional<SwiftKeystone3ObjectStorage.Configuration> 
keystone3Configuration;
+    private Optional<String> aesSalt;
+    private Optional<char[]> aesPassword;
+
+    @VisibleForTesting
+    ObjectStorageBlobConfiguration(PayloadCodecFactory payloadCodec, String 
provider, ContainerName namespace,
+                                   Optional<String> aesSalt,
+                                   Optional<char[]> aesPassword, String 
authApi,
+                                   
Optional<SwiftTempAuthObjectStorage.Configuration> tempAuth,
+                                   
Optional<SwiftKeystone2ObjectStorage.Configuration> keystone2Configuration,
+                                   
Optional<SwiftKeystone3ObjectStorage.Configuration> keystone3Configuration) {
+        this.payloadCodec = payloadCodec;
+        this.aesSalt = aesSalt;
+        this.aesPassword = aesPassword;
+        this.authApi = authApi;
+        this.namespace = namespace;
+        this.provider = provider;
+        this.tempAuth = tempAuth;
+        this.keystone2Configuration = keystone2Configuration;
+        this.keystone3Configuration = keystone3Configuration;
+    }
+
+    public String getAuthApi() {
+        return authApi;
+    }
+
+    public ContainerName getNamespace() {
+        return namespace;
+    }
+
+    public String getProvider() {
+        return provider;
+    }
+
+    public Optional<SwiftTempAuthObjectStorage.Configuration> 
getTempAuthConfiguration() {
+        return tempAuth;
+    }
+
+    public Optional<SwiftKeystone2ObjectStorage.Configuration> 
getKeystone2Configuration() {
+        return keystone2Configuration;
+    }
+
+    public Optional<SwiftKeystone3ObjectStorage.Configuration> 
getKeystone3Configuration() {
+        return keystone3Configuration;
+    }
+
+    public PayloadCodecFactory getPayloadCodecFactory() {
+        return payloadCodec;
+    }
+
+
+    public Optional<String> getAesSalt() {
+        return aesSalt;
+    }
+
+    public Optional<char[]> getAesPassword() {
+        return aesPassword;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        ObjectStorageBlobConfiguration that = (ObjectStorageBlobConfiguration) 
o;
+        return Objects.equals(payloadCodec, that.payloadCodec) &&
+            Objects.equals(authApi, that.authApi) &&
+            Objects.equals(namespace, that.namespace) &&
+            Objects.equals(provider, that.provider) &&
+            Objects.equals(tempAuth, that.tempAuth) &&
+            Objects.equals(keystone2Configuration, 
that.keystone2Configuration) &&
+            Objects.equals(keystone3Configuration, 
that.keystone3Configuration) &&
+            Objects.equals(aesSalt, that.aesSalt) &&
+            Objects.equals(aesPassword, that.aesPassword);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(payloadCodec, authApi, namespace, provider, 
tempAuth, keystone2Configuration, keystone3Configuration, aesSalt, aesPassword);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("payloadCodec", payloadCodec)
+            .add("authApi", authApi)
+            .add("namespace", namespace)
+            .add("provider", provider)
+            .add("tempAuth", tempAuth)
+            .add("keystone2Configuration", keystone2Configuration)
+            .add("keystone3Configuration", keystone3Configuration)
+            .add("aesSalt", aesSalt)
+            .add("aesPassword", aesPassword)
+            .toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4d07616f/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageBlobStoreModule.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageBlobStoreModule.java
 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageBlobStoreModule.java
index b6cba09..d31ec08 100644
--- 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageBlobStoreModule.java
+++ 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageBlobStoreModule.java
@@ -19,19 +19,19 @@
 
 package org.apache.james.modules.objectstorage;
 
+import org.apache.james.blob.api.BlobId;
 import org.apache.james.blob.api.BlobStore;
+import org.apache.james.blob.api.HashBlobId;
 import org.apache.james.blob.objectstorage.ObjectStorageBlobsDAO;
-import org.apache.james.blob.objectstorage.PayloadCodec;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Scopes;
 
 public class ObjectStorageBlobStoreModule extends AbstractModule {
 
     @Override
     protected void configure() {
-        
bind(PayloadCodec.class).toProvider(PayloadCodecProvider.class).in(Scopes.SINGLETON);
-        
bind(ObjectStorageBlobsDAO.class).toProvider(ObjectStorageBlobsDAOProvider.class).in(Scopes.SINGLETON);
-        
bind(BlobStore.class).toProvider(ObjectStorageBlobsDAOProvider.class).in(Scopes.SINGLETON);
+        install(new ObjectStorageDependenciesModule());
+        bind(BlobStore.class).to(ObjectStorageBlobsDAO.class);
     }
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4d07616f/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageBlobsDAOProvider.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageBlobsDAOProvider.java
 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageBlobsDAOProvider.java
deleted file mode 100644
index b6aa4fe..0000000
--- 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageBlobsDAOProvider.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/****************************************************************
- * 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.modules.objectstorage;
-
-import java.io.FileNotFoundException;
-import java.util.function.Supplier;
-
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.james.blob.api.BlobId;
-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.swift.SwiftKeystone2ObjectStorage;
-import org.apache.james.blob.objectstorage.swift.SwiftKeystone3ObjectStorage;
-import org.apache.james.blob.objectstorage.swift.SwiftTempAuthObjectStorage;
-import org.apache.james.utils.PropertiesProvider;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-
-public class ObjectStorageBlobsDAOProvider implements 
Provider<ObjectStorageBlobsDAO> {
-    static final String OBJECTSTORAGE_CONFIGURATION_NAME = "objectstorage";
-
-    static final String OBJECTSTORAGE_NAMESPACE = "objectstorage.namespace";
-    static final String OBJECTSTORAGE_PROVIDER = "objectstorage.provider";
-    static final String OBJECTSTORAGE_SWIFT_AUTH_API = 
"objectstorage.swift.authapi";
-
-    public static final String OBJECTSTORAGE_PROVIDER_SWIFT = "swift";
-
-    private final Configuration configuration;
-    private final BlobId.Factory blobIdFactory;
-    private final ImmutableMap<String, 
Supplier<ObjectStorageBlobsDAOBuilder.RequireContainerName>> providersByName;
-    private final ImmutableMap<String, 
Supplier<ObjectStorageBlobsDAOBuilder.RequireContainerName>> swiftAuthApiByName;
-
-    @Inject
-    public ObjectStorageBlobsDAOProvider(PropertiesProvider propertiesProvider,
-                                         BlobId.Factory blobIdFactory) throws 
ConfigurationException {
-        //This provider map will allow to implement S3 provider
-        providersByName = ImmutableMap.of(OBJECTSTORAGE_PROVIDER_SWIFT, 
this::selectSwiftAuthApi);
-        swiftAuthApiByName = ImmutableMap.of(
-            SwiftTempAuthObjectStorage.AUTH_API_NAME, this::swiftTempAuth,
-            SwiftKeystone2ObjectStorage.AUTH_API_NAME, 
this::swiftKeystone2Auth,
-            SwiftKeystone3ObjectStorage.AUTH_API_NAME, 
this::swiftKeystone3Auth);
-
-        this.blobIdFactory = blobIdFactory;
-        try {
-            this.configuration = 
propertiesProvider.getConfiguration(OBJECTSTORAGE_CONFIGURATION_NAME);
-        } catch (FileNotFoundException e) {
-            throw new ConfigurationException(OBJECTSTORAGE_CONFIGURATION_NAME 
+ " configuration " +
-                "was not found");
-        }
-    }
-
-    @Override
-    public ObjectStorageBlobsDAO get() {
-        String provider = configuration.getString(OBJECTSTORAGE_PROVIDER, 
null);
-        String namespace = configuration.getString(OBJECTSTORAGE_NAMESPACE, 
null);
-        Preconditions.checkArgument(provider != null,
-            "Mandatory configuration value " + OBJECTSTORAGE_PROVIDER + " is 
missing from " + OBJECTSTORAGE_CONFIGURATION_NAME + " configuration");
-        Preconditions.checkArgument(namespace != null,
-            "Mandatory configuration value " + OBJECTSTORAGE_NAMESPACE + " is 
missing from " + OBJECTSTORAGE_CONFIGURATION_NAME + " configuration");
-
-        return 
providersByName.get(provider).get().container(ContainerName.of(namespace)).blobIdFactory(blobIdFactory).build();
-    }
-
-    private ObjectStorageBlobsDAOBuilder.RequireContainerName 
selectSwiftAuthApi() {
-        String authApi = configuration.getString(OBJECTSTORAGE_SWIFT_AUTH_API, 
null);
-        Preconditions.checkArgument(authApi != null,
-            "Mandatory configuration value " + OBJECTSTORAGE_PROVIDER + " is 
missing from " + OBJECTSTORAGE_CONFIGURATION_NAME + " configuration");
-        return swiftAuthApiByName.get(authApi).get();
-    }
-
-    private ObjectStorageBlobsDAOBuilder.RequireContainerName swiftTempAuth() {
-        return 
ObjectStorageBlobsDAO.builder(SwiftTmpAuthConfigurationReader.readSwiftConfiguration(configuration));
-    }
-
-    private ObjectStorageBlobsDAOBuilder.RequireContainerName 
swiftKeystone2Auth() {
-        return 
ObjectStorageBlobsDAO.builder(SwiftKeystone2ConfigurationReader.readSwiftConfiguration(configuration));
-    }
-
-    private ObjectStorageBlobsDAOBuilder.RequireContainerName 
swiftKeystone3Auth() {
-        return 
ObjectStorageBlobsDAO.builder(SwiftKeystone3ConfigurationReader.readSwiftConfiguration(configuration));
-    }
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4d07616f/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageDependenciesModule.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..ce13f7a
--- /dev/null
+++ 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/ObjectStorageDependenciesModule.java
@@ -0,0 +1,94 @@
+/****************************************************************
+ * 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.modules.objectstorage;
+
+import java.io.FileNotFoundException;
+
+import javax.inject.Singleton;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+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.PayloadCodec;
+import org.apache.james.blob.objectstorage.swift.SwiftKeystone2ObjectStorage;
+import org.apache.james.blob.objectstorage.swift.SwiftKeystone3ObjectStorage;
+import org.apache.james.blob.objectstorage.swift.SwiftTempAuthObjectStorage;
+import org.apache.james.utils.PropertiesProvider;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+import com.google.inject.Scopes;
+
+public class ObjectStorageDependenciesModule extends AbstractModule {
+
+    private static final String OBJECTSTORAGE_CONFIGURATION_NAME = 
"objectstorage";
+    private static final String OBJECTSTORAGE_PROVIDER_SWIFT = "swift";
+
+    @Override
+    protected void configure() {
+        
bind(BlobId.Factory.class).to(HashBlobId.Factory.class).in(Scopes.SINGLETON);
+    }
+
+    @Provides
+    @Singleton
+    private PayloadCodec buildPayloadCodec(ObjectStorageBlobConfiguration 
configuration) {
+        return configuration.getPayloadCodecFactory().create(configuration);
+    }
+
+    @Provides
+    @Singleton
+    private ObjectStorageBlobConfiguration 
getObjectStorageConfiguration(PropertiesProvider propertiesProvider) throws 
ConfigurationException {
+        try {
+            Configuration configuration = 
propertiesProvider.getConfiguration(OBJECTSTORAGE_CONFIGURATION_NAME);
+            return ObjectStorageBlobConfiguration.from(configuration);
+        } catch (FileNotFoundException e) {
+            throw new ConfigurationException(OBJECTSTORAGE_CONFIGURATION_NAME 
+ " configuration was not found");
+        }
+    }
+
+    @Provides
+    @Singleton
+    private ObjectStorageBlobsDAO 
buildObjectStore(ObjectStorageBlobConfiguration configuration, BlobId.Factory 
blobIdFactory) {
+        return selectDaoBuilder(configuration)
+            .container(configuration.getNamespace())
+            .blobIdFactory(blobIdFactory)
+            .build();
+    }
+
+    private ObjectStorageBlobsDAOBuilder.RequireContainerName 
selectDaoBuilder(ObjectStorageBlobConfiguration configuration) {
+        if (!configuration.getProvider().equals(OBJECTSTORAGE_PROVIDER_SWIFT)) 
{
+            throw new IllegalArgumentException("unknown provider " + 
configuration.getProvider());
+        }
+        switch (configuration.getAuthApi()) {
+            case SwiftTempAuthObjectStorage.AUTH_API_NAME:
+                return 
ObjectStorageBlobsDAO.builder(configuration.getTempAuthConfiguration().get());
+            case SwiftKeystone2ObjectStorage.AUTH_API_NAME:
+                return 
ObjectStorageBlobsDAO.builder(configuration.getKeystone2Configuration().get());
+            case SwiftKeystone3ObjectStorage.AUTH_API_NAME:
+                return 
ObjectStorageBlobsDAO.builder(configuration.getKeystone3Configuration().get());
+            default:
+                throw new IllegalArgumentException("unknown auth api " + 
configuration.getAuthApi());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4d07616f/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/PayloadCodecFactory.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/PayloadCodecFactory.java
 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/PayloadCodecFactory.java
new file mode 100644
index 0000000..211a0b9
--- /dev/null
+++ 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/PayloadCodecFactory.java
@@ -0,0 +1,43 @@
+/****************************************************************
+ * 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.modules.objectstorage;
+
+import org.apache.james.blob.objectstorage.AESPayloadCodec;
+import org.apache.james.blob.objectstorage.DefaultPayloadCodec;
+import org.apache.james.blob.objectstorage.PayloadCodec;
+import org.apache.james.blob.objectstorage.crypto.CryptoConfig;
+
+public enum PayloadCodecFactory {
+    DEFAULT {
+        @Override
+        public PayloadCodec create(ObjectStorageBlobConfiguration 
configuration) {
+            return new DefaultPayloadCodec();
+        }
+    },
+    AES256 {
+        @Override
+        public PayloadCodec create(ObjectStorageBlobConfiguration 
configuration) {
+            return new AESPayloadCodec(new 
CryptoConfig(configuration.getAesSalt().get(), 
configuration.getAesPassword().get()));
+        }
+    };
+
+    public abstract PayloadCodec create(ObjectStorageBlobConfiguration 
configuration);
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4d07616f/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/PayloadCodecProvider.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/PayloadCodecProvider.java
 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/PayloadCodecProvider.java
deleted file mode 100644
index 7981136..0000000
--- 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/PayloadCodecProvider.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************
- * 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.modules.objectstorage;
-
-import java.io.FileNotFoundException;
-
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.james.blob.objectstorage.PayloadCodec;
-import org.apache.james.utils.PropertiesProvider;
-
-import com.amazonaws.util.StringUtils;
-import com.google.common.base.Preconditions;
-
-public class PayloadCodecProvider implements Provider<PayloadCodec> {
-    static final String OBJECTSTORAGE_PAYLOAD_CODEC = 
"objectstorage.payload.codec";
-
-    private static final String OBJECTSTORAGE_CONFIGURATION_NAME = 
"objectstorage";
-
-    private final Configuration configuration;
-
-    @Inject
-    public PayloadCodecProvider(PropertiesProvider propertiesProvider)
-            throws ConfigurationException {
-        try {
-            this.configuration =
-                
propertiesProvider.getConfiguration(OBJECTSTORAGE_CONFIGURATION_NAME);
-        } catch (FileNotFoundException e) {
-            throw new ConfigurationException(OBJECTSTORAGE_CONFIGURATION_NAME 
+ "configuration was not found");
-        }
-    }
-
-    @Override
-    public PayloadCodec get() {
-        String codecName = 
configuration.getString(OBJECTSTORAGE_PAYLOAD_CODEC, null);
-        Preconditions.checkArgument(!StringUtils.isNullOrEmpty(codecName),
-            OBJECTSTORAGE_PAYLOAD_CODEC + " is a mandatory configuration 
value");
-        return PayloadCodecs.valueOf(codecName).codec(configuration);
-    }
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4d07616f/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/PayloadCodecs.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/PayloadCodecs.java
 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/PayloadCodecs.java
deleted file mode 100644
index 36e0d15..0000000
--- 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/PayloadCodecs.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************
- * 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.modules.objectstorage;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.james.blob.objectstorage.AESPayloadCodec;
-import org.apache.james.blob.objectstorage.DefaultPayloadCodec;
-import org.apache.james.blob.objectstorage.PayloadCodec;
-import org.apache.james.blob.objectstorage.crypto.CryptoConfig;
-
-import com.amazonaws.util.StringUtils;
-import com.google.common.base.Preconditions;
-
-public enum PayloadCodecs {
-    DEFAULT {
-        @Override
-        public PayloadCodec codec(Configuration configuration) {
-            return new DefaultPayloadCodec();
-        }
-    },
-    AES256 {
-        @Override
-        public PayloadCodec codec(Configuration configuration) {
-            String salt = 
configuration.getString(OBJECTSTORAGE_AES256_HEXSALT);
-            String password = 
configuration.getString(OBJECTSTORAGE_AES256_PASSWORD);
-            Preconditions.checkArgument(!StringUtils.isNullOrEmpty(salt),
-                OBJECTSTORAGE_AES256_HEXSALT + " is a " +
-                    "mandatory configuration value");
-            Preconditions.checkArgument(!StringUtils.isNullOrEmpty(password),
-                OBJECTSTORAGE_AES256_PASSWORD + " is a " +
-                    "mandatory configuration value");
-            return new AESPayloadCodec(new CryptoConfig(salt, 
password.toCharArray()));
-        }
-    };
-
-    public static final String OBJECTSTORAGE_AES256_HEXSALT = 
"objectstorage.aes256.hexsalt";
-    public static final String OBJECTSTORAGE_AES256_PASSWORD = 
"objectstorage.aes256.password";
-
-    public abstract PayloadCodec codec(Configuration configuration);
-
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4d07616f/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/ObjectStorageBlobConfigurationTest.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/ObjectStorageBlobConfigurationTest.java
 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/ObjectStorageBlobConfigurationTest.java
new file mode 100644
index 0000000..7157ccf
--- /dev/null
+++ 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/ObjectStorageBlobConfigurationTest.java
@@ -0,0 +1,249 @@
+package org.apache.james.modules.objectstorage;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.stream.Stream;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.MapConfiguration;
+import org.apache.james.blob.objectstorage.ContainerName;
+import org.apache.james.blob.objectstorage.swift.Credentials;
+import org.apache.james.blob.objectstorage.swift.DomainName;
+import org.apache.james.blob.objectstorage.swift.IdentityV3;
+import org.apache.james.blob.objectstorage.swift.PassHeaderName;
+import org.apache.james.blob.objectstorage.swift.Project;
+import org.apache.james.blob.objectstorage.swift.ProjectName;
+import org.apache.james.blob.objectstorage.swift.SwiftKeystone2ObjectStorage;
+import org.apache.james.blob.objectstorage.swift.SwiftKeystone3ObjectStorage;
+import org.apache.james.blob.objectstorage.swift.SwiftTempAuthObjectStorage;
+import org.apache.james.blob.objectstorage.swift.TenantName;
+import org.apache.james.blob.objectstorage.swift.UserHeaderName;
+import org.apache.james.blob.objectstorage.swift.UserName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.ArgumentsProvider;
+import org.junit.jupiter.params.provider.ArgumentsSource;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+class ObjectStorageBlobConfigurationTest {
+
+    static final ImmutableMap<String, Object> CONFIGURATION_WITHOUT_CODEC = 
ImmutableMap.<String, Object>builder()
+        .put("objectstorage.provider", "swift")
+        .put("objectstorage.namespace", "foo")
+        .put("objectstorage.swift.authapi", "tmpauth")
+        .put("objectstorage.swift.endpoint", "http://swift/endpoint";)
+        .put("objectstorage.swift.credentials", "testing")
+        .put("objectstorage.swift.tempauth.username", "tester")
+        .put("objectstorage.swift.tempauth.tenantname", "test")
+        .put("objectstorage.swift.tempauth.passheadername", "X-Storage-Pass")
+        .put("objectstorage.swift.tempauth.userheadername", "X-Storage-User")
+        .build();
+
+    static final ImmutableMap<String, Object> VALID_CONFIGURATION = 
ImmutableMap.<String, Object>builder()
+        .putAll(CONFIGURATION_WITHOUT_CODEC)
+        .put("objectstorage.payload.codec", "DEFAULT")
+        .build();
+
+    static class RequiredParameters implements ArgumentsProvider {
+        @Override
+        public Stream<? extends Arguments> provideArguments(ExtensionContext 
context) {
+            return Stream.of("objectstorage.provider", 
"objectstorage.namespace", "objectstorage.swift.authapi", 
"objectstorage.payload.codec")
+                    .map(Arguments::of);
+        }
+    }
+
+    @ParameterizedTest
+    @ArgumentsSource(RequiredParameters.class)
+    void shouldThrowWhenRequiredParameterOmitted(String toOmit) {
+        Map<String, Object> configurationWithFilteredKey = 
Maps.filterKeys(VALID_CONFIGURATION, key -> !toOmit.equals(key));
+
+        assertThat(configurationWithFilteredKey).doesNotContainKeys(toOmit);
+        assertThatThrownBy(() -> ObjectStorageBlobConfiguration.from(new 
MapConfiguration(configurationWithFilteredKey)))
+            .isInstanceOf(ConfigurationException.class);
+    }
+
+    @ParameterizedTest
+    @ArgumentsSource(RequiredParameters.class)
+    void shouldThrowWhenRequiredParameterEmpty(String toEmpty) {
+        Map<String, Object> configurationWithFilteredKey = 
Maps.transformEntries(VALID_CONFIGURATION, (key, value) -> {
+            if (toEmpty.equals(key)) {
+                return "";
+            } else {
+                return value;
+            }
+        });
+
+        assertThat(configurationWithFilteredKey).containsEntry(toEmpty, "");
+        assertThatThrownBy(() -> ObjectStorageBlobConfiguration.from(new 
MapConfiguration(configurationWithFilteredKey)))
+            .isInstanceOf(ConfigurationException.class);
+    }
+
+    @Test
+    void shouldBuildAnAESPayloadCodecForAESConfig() throws Exception {
+        ObjectStorageBlobConfiguration actual = 
ObjectStorageBlobConfiguration.from(new MapConfiguration(
+            ImmutableMap.<String, Object>builder()
+                .putAll(CONFIGURATION_WITHOUT_CODEC)
+                .put("objectstorage.payload.codec", 
PayloadCodecFactory.AES256.name())
+                .put("objectstorage.aes256.hexsalt", "12345123451234512345")
+                .put("objectstorage.aes256.password", "james is great")
+            .build()));
+        
assertThat(actual.getPayloadCodecFactory()).isEqualTo(PayloadCodecFactory.AES256);
+        assertThat(actual.getAesSalt()).contains("12345123451234512345");
+        assertThat(actual.getAesPassword()).contains("james is 
great".toCharArray());
+    }
+
+    @Test
+    void shouldFailIfCodecKeyIsIncorrect() throws Exception {
+        MapConfiguration configuration = new MapConfiguration(
+            ImmutableMap.<String, Object>builder()
+                .putAll(CONFIGURATION_WITHOUT_CODEC)
+                .put("objectstorage.payload.codec", "aes255")
+                .build());
+        assertThatThrownBy(() -> 
ObjectStorageBlobConfiguration.from(configuration)).isInstanceOf(ConfigurationException.class);
+    }
+
+    @Test
+    void shouldFailForAESCodecWhenSaltKeyIsMissing() throws Exception {
+        MapConfiguration configuration = new MapConfiguration(
+            ImmutableMap.<String, Object>builder()
+                .putAll(CONFIGURATION_WITHOUT_CODEC)
+                .put("objectstorage.payload.codec", 
PayloadCodecFactory.AES256.name())
+                .put("objectstorage.aes256.password", "james is great")
+                .build());
+        assertThatThrownBy(() -> 
ObjectStorageBlobConfiguration.from(configuration)).isInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
+    void shouldFailForAESCodecWhenSaltKeyIsEmpty() throws Exception {
+        MapConfiguration configuration = new MapConfiguration(
+            ImmutableMap.<String, Object>builder()
+                .putAll(CONFIGURATION_WITHOUT_CODEC)
+                .put("objectstorage.payload.codec", 
PayloadCodecFactory.AES256.name())
+                .put("objectstorage.aes256.hexsalt", "")
+                .put("objectstorage.aes256.password", "james is great")
+                .build());
+        assertThatThrownBy(() -> 
ObjectStorageBlobConfiguration.from(configuration)).isInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
+    void shouldFailForAESCodecWhenPasswordKeyIsMissing() throws Exception {
+        MapConfiguration configuration = new MapConfiguration(
+            ImmutableMap.<String, Object>builder()
+                .putAll(CONFIGURATION_WITHOUT_CODEC)
+                .put("objectstorage.payload.codec", 
PayloadCodecFactory.AES256.name())
+                .put("objectstorage.aes256.hexsalt", "12345123451234512345")
+                .build());
+
+        assertThatThrownBy(() -> 
ObjectStorageBlobConfiguration.from(configuration)).isInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
+    void shouldFailForAESCodecWhenPasswordKeyIsEmpty() throws Exception {
+        MapConfiguration configuration = new MapConfiguration(
+            ImmutableMap.<String, Object>builder()
+                .putAll(CONFIGURATION_WITHOUT_CODEC)
+                .put("objectstorage.payload.codec", 
PayloadCodecFactory.AES256.name())
+                .put("objectstorage.aes256.hexsalt", "12345123451234512345")
+                .put("objectstorage.aes256.password", "")
+                .build());
+
+        assertThatThrownBy(() -> 
ObjectStorageBlobConfiguration.from(configuration)).isInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
+    void tempAuthPropertiesProvider() throws ConfigurationException {
+        ObjectStorageBlobConfiguration configuration = 
ObjectStorageBlobConfiguration.from(
+            new MapConfigurationBuilder()
+                .put("objectstorage.payload.codec", 
PayloadCodecFactory.DEFAULT.name())
+                .put("objectstorage.provider", "swift")
+                .put("objectstorage.namespace", "foo")
+                .put("objectstorage.swift.authapi", "tmpauth")
+                .put("objectstorage.swift.endpoint", "http://swift/endpoint";)
+                .put("objectstorage.swift.credentials", "testing")
+                .put("objectstorage.swift.tempauth.username", "tester")
+                .put("objectstorage.swift.tempauth.tenantname", "test")
+                .put("objectstorage.swift.tempauth.passheadername", 
"X-Storage-Pass")
+                .put("objectstorage.swift.tempauth.userheadername", 
"X-Storage-User")
+                .build());
+        assertThat(configuration)
+            .isEqualTo(
+                ObjectStorageBlobConfiguration.builder()
+                    .codec(PayloadCodecFactory.DEFAULT)
+                    .swift()
+                    .container(ContainerName.of("foo"))
+                    .tempAuth(SwiftTempAuthObjectStorage.configBuilder()
+                            .endpoint(URI.create("http://swift/endpoint";))
+                            .credentials(Credentials.of("testing"))
+                            .userName(UserName.of("tester"))
+                            .tenantName(TenantName.of("test"))
+                            
.tempAuthHeaderUserName(UserHeaderName.of("X-Storage-User"))
+                            
.tempAuthHeaderPassName(PassHeaderName.of("X-Storage-Pass"))
+                            .build())
+                    .build());
+    }
+
+    @Test
+    void keystone2PropertiesProvider() throws ConfigurationException {
+        ObjectStorageBlobConfiguration configuration = 
ObjectStorageBlobConfiguration.from(
+            new MapConfigurationBuilder()
+                .put("objectstorage.payload.codec", 
PayloadCodecFactory.DEFAULT.name())
+                .put("objectstorage.provider", "swift")
+                .put("objectstorage.namespace", "foo")
+                .put("objectstorage.swift.authapi", "keystone2")
+                .put("objectstorage.swift.endpoint", "http://swift/endpoint";)
+                .put("objectstorage.swift.credentials", "creds")
+                .put("objectstorage.swift.keystone2.username", "demo")
+                .put("objectstorage.swift.keystone2.tenantname", "test")
+                .build());
+        assertThat(configuration)
+            .isEqualTo(
+                ObjectStorageBlobConfiguration.builder()
+                    .codec(PayloadCodecFactory.DEFAULT)
+                    .swift()
+                    .container(ContainerName.of("foo"))
+                    .keystone2(SwiftKeystone2ObjectStorage.configBuilder()
+                        .endpoint(URI.create("http://swift/endpoint";))
+                        .credentials(Credentials.of("creds"))
+                        .userName(UserName.of("demo"))
+                        .tenantName(TenantName.of("test"))
+                        .build())
+                    .build());
+    }
+
+    @Test
+    void keystone3PropertiesProvider() throws ConfigurationException {
+        ObjectStorageBlobConfiguration configuration = 
ObjectStorageBlobConfiguration.from(
+            new MapConfigurationBuilder()
+                .put("objectstorage.payload.codec", 
PayloadCodecFactory.DEFAULT.name())
+                .put("objectstorage.provider", "swift")
+                .put("objectstorage.namespace", "foo")
+                .put("objectstorage.swift.authapi", "keystone3")
+                .put("objectstorage.swift.endpoint", "http://swift/endpoint";)
+                .put("objectstorage.swift.credentials", "creds")
+                .put("objectstorage.swift.keystone3.user.name", "demo")
+                .put("objectstorage.swift.keystone3.user.domain", "Default")
+                .put("objectstorage.swift.keystone3.scope.project.name", 
"test")
+                .build());
+        assertThat(configuration)
+            .isEqualTo(
+                ObjectStorageBlobConfiguration.builder()
+                    .codec(PayloadCodecFactory.DEFAULT)
+                    .swift()
+                    .container(ContainerName.of("foo"))
+                    .keystone3(SwiftKeystone3ObjectStorage.configBuilder()
+                        .endpoint(URI.create("http://swift/endpoint";))
+                        .credentials(Credentials.of("creds"))
+                        .project(Project.of(ProjectName.of("test")))
+                        .identity(IdentityV3.of(DomainName.of("Default"), 
UserName.of("demo")))
+                        .build())
+                    .build());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/4d07616f/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/ObjectStorageBlobStoreModuleTest.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/ObjectStorageBlobStoreModuleTest.java
 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/ObjectStorageBlobStoreModuleTest.java
new file mode 100644
index 0000000..3c8e679
--- /dev/null
+++ 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/ObjectStorageBlobStoreModuleTest.java
@@ -0,0 +1,130 @@
+/****************************************************************
+ * 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.modules.objectstorage;
+
+import static org.assertj.core.api.Assertions.assertThatCode;
+
+import java.util.UUID;
+import java.util.stream.Stream;
+
+import org.apache.james.blob.api.BlobStore;
+import org.apache.james.blob.objectstorage.ContainerName;
+import org.apache.james.blob.objectstorage.DockerSwift;
+import org.apache.james.blob.objectstorage.DockerSwiftExtension;
+import org.apache.james.blob.objectstorage.ObjectStorageBlobsDAO;
+import org.apache.james.blob.objectstorage.swift.Credentials;
+import org.apache.james.blob.objectstorage.swift.DomainName;
+import org.apache.james.blob.objectstorage.swift.IdentityV3;
+import org.apache.james.blob.objectstorage.swift.PassHeaderName;
+import org.apache.james.blob.objectstorage.swift.Project;
+import org.apache.james.blob.objectstorage.swift.ProjectName;
+import org.apache.james.blob.objectstorage.swift.SwiftKeystone2ObjectStorage;
+import org.apache.james.blob.objectstorage.swift.SwiftKeystone3ObjectStorage;
+import org.apache.james.blob.objectstorage.swift.SwiftTempAuthObjectStorage;
+import org.apache.james.blob.objectstorage.swift.TenantName;
+import org.apache.james.blob.objectstorage.swift.UserHeaderName;
+import org.apache.james.blob.objectstorage.swift.UserName;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.ArgumentsProvider;
+import org.junit.jupiter.params.provider.ArgumentsSource;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.util.Modules;
+
+@ExtendWith(DockerSwiftExtension.class)
+class ObjectStorageBlobStoreModuleTest {
+
+    private static DockerSwift dockerSwift;
+
+    @BeforeAll
+    static void setUp(DockerSwift dockerSwift) throws Exception {
+        ObjectStorageBlobStoreModuleTest.dockerSwift = dockerSwift;
+    }
+
+    static class BlobStorageBlobConfigurationProvider implements 
ArgumentsProvider {
+
+        @Override
+        public Stream<? extends Arguments> provideArguments(ExtensionContext 
context) throws Exception {
+
+            ObjectStorageBlobConfiguration tmpAuth = 
ObjectStorageBlobConfiguration.builder()
+                .codec(PayloadCodecFactory.DEFAULT)
+                .swift()
+                .container(generateContainerName())
+                .tempAuth(SwiftTempAuthObjectStorage.configBuilder()
+                    .endpoint(dockerSwift.swiftEndpoint())
+                    .credentials(Credentials.of("testing"))
+                    .userName(UserName.of("tester"))
+                    .tenantName(TenantName.of("test"))
+                    
.tempAuthHeaderUserName(UserHeaderName.of("X-Storage-User"))
+                    
.tempAuthHeaderPassName(PassHeaderName.of("X-Storage-Pass"))
+                    .build())
+                .build();
+            ObjectStorageBlobConfiguration keystone2 = 
ObjectStorageBlobConfiguration.builder()
+                .codec(PayloadCodecFactory.DEFAULT)
+                .swift()
+                .container(generateContainerName())
+                .keystone2(SwiftKeystone2ObjectStorage.configBuilder()
+                    .endpoint(dockerSwift.keystoneV2Endpoint())
+                    .credentials(Credentials.of("demo"))
+                    .userName(UserName.of("demo"))
+                    .tenantName(TenantName.of("test"))
+                    .build())
+                .build();
+            ObjectStorageBlobConfiguration keystone3 = 
ObjectStorageBlobConfiguration.builder()
+                .codec(PayloadCodecFactory.DEFAULT)
+                .swift()
+                .container(generateContainerName())
+                .keystone3(SwiftKeystone3ObjectStorage.configBuilder()
+                    .endpoint(dockerSwift.keystoneV3Endpoint())
+                    .credentials(Credentials.of("demo"))
+                    .project(Project.of(ProjectName.of("test")))
+                    .identity(IdentityV3.of(DomainName.of("Default"), 
UserName.of("demo")))
+                    .build())
+                .build();
+            return Stream.of(tmpAuth, keystone2, keystone3).map(Arguments::of);
+        }
+    }
+
+    private static ContainerName generateContainerName() {
+        return ContainerName.of(UUID.randomUUID().toString());
+    }
+
+    @ParameterizedTest
+    @ArgumentsSource(BlobStorageBlobConfigurationProvider.class)
+    void shouldSetupBlobStore(ObjectStorageBlobConfiguration configuration) {
+        Injector injector = Guice.createInjector(
+            Modules
+                .override(new ObjectStorageBlobStoreModule())
+                .with(binder -> 
binder.bind(ObjectStorageBlobConfiguration.class).toInstance(configuration)));
+
+        ObjectStorageBlobsDAO dao = 
injector.getInstance(ObjectStorageBlobsDAO.class);
+        dao.createContainer(configuration.getNamespace());
+
+        BlobStore blobStore = injector.getInstance(BlobStore.class);
+
+        assertThatCode(() -> blobStore.save(new byte[] 
{0x00})).doesNotThrowAnyException();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4d07616f/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/ObjectStorageBlobsDAOProviderTest.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/ObjectStorageBlobsDAOProviderTest.java
 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/ObjectStorageBlobsDAOProviderTest.java
deleted file mode 100644
index b57fc2f..0000000
--- 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/ObjectStorageBlobsDAOProviderTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/****************************************************************
- * 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.modules.objectstorage;
-
-import static 
org.apache.james.modules.objectstorage.ObjectStorageBlobsDAOProvider.OBJECTSTORAGE_CONFIGURATION_NAME;
-import static 
org.apache.james.modules.objectstorage.ObjectStorageBlobsDAOProvider.OBJECTSTORAGE_NAMESPACE;
-import static 
org.apache.james.modules.objectstorage.ObjectStorageBlobsDAOProvider.OBJECTSTORAGE_PROVIDER;
-import static 
org.apache.james.modules.objectstorage.ObjectStorageBlobsDAOProvider.OBJECTSTORAGE_PROVIDER_SWIFT;
-import static 
org.apache.james.modules.objectstorage.ObjectStorageBlobsDAOProvider.OBJECTSTORAGE_SWIFT_AUTH_API;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.util.UUID;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.james.blob.api.HashBlobId;
-import org.apache.james.blob.objectstorage.ContainerName;
-import org.apache.james.blob.objectstorage.DockerSwift;
-import org.apache.james.blob.objectstorage.DockerSwiftExtension;
-import org.apache.james.blob.objectstorage.ObjectStorageBlobsDAO;
-import org.apache.james.blob.objectstorage.swift.SwiftKeystone2ObjectStorage;
-import org.apache.james.blob.objectstorage.swift.SwiftKeystone3ObjectStorage;
-import org.apache.james.blob.objectstorage.swift.SwiftTempAuthObjectStorage;
-import org.apache.james.utils.PropertiesProvider;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-
-@ExtendWith(DockerSwiftExtension.class)
-class ObjectStorageBlobsDAOProviderTest {
-
-    private ContainerName containerName;
-    private DockerSwift dockerSwift;
-
-    @BeforeEach
-    void setUp(DockerSwift dockerSwift) throws Exception {
-        this.dockerSwift = dockerSwift;
-        containerName = ContainerName.of(UUID.randomUUID().toString());
-    }
-
-    public static final HashBlobId.Factory BLOB_ID_FACTORY = new 
HashBlobId.Factory();
-
-
-    private PropertiesProvider tempAuthPropertiesProvider() {
-        return FakePropertiesProvider.builder()
-            .register(OBJECTSTORAGE_CONFIGURATION_NAME,
-                swiftConfigBuilder()
-                    .put(OBJECTSTORAGE_SWIFT_AUTH_API, 
SwiftTempAuthObjectStorage.AUTH_API_NAME)
-                    
.put(SwiftConfigurationReader.OBJECTSTORAGE_SWIFT_ENDPOINT, 
dockerSwift.swiftEndpoint().toString())
-                    
.put(SwiftConfigurationReader.OBJECTSTORAGE_SWIFT_CREDENTIALS, "testing")
-                    
.put(SwiftTmpAuthConfigurationReader.OBJECTSTORAGE_SWIFT_TEMPAUTH_USERNAME, 
"tester")
-                    
.put(SwiftTmpAuthConfigurationReader.OBJECTSTORAGE_SWIFT_TEMPAUTH_TENANTNAME, 
"test")
-                    
.put(SwiftTmpAuthConfigurationReader.OBJECTSTORAGE_SWIFT_TEMPAUTH_PASS_HEADER_NAME,
 "X-Storage-Pass")
-                    
.put(SwiftTmpAuthConfigurationReader.OBJECTSTORAGE_SWIFT_TEMPAUTH_USER_HEADER_NAME,
 "X-Storage-User")
-                    .build())
-            .build();
-    }
-
-    private PropertiesProvider keystone2PropertiesProvider() {
-        return FakePropertiesProvider.builder()
-            .register(OBJECTSTORAGE_CONFIGURATION_NAME,
-                swiftConfigBuilder()
-                    .put(OBJECTSTORAGE_SWIFT_AUTH_API, 
SwiftKeystone2ObjectStorage.AUTH_API_NAME)
-                    
.put(SwiftConfigurationReader.OBJECTSTORAGE_SWIFT_ENDPOINT, 
dockerSwift.keystoneV2Endpoint().toString())
-                    
.put(SwiftConfigurationReader.OBJECTSTORAGE_SWIFT_CREDENTIALS, "demo")
-                    
.put(SwiftKeystone2ConfigurationReader.OBJECTSTORAGE_SWIFT_KEYSTONE_2_USERNAME, 
"demo")
-                    
.put(SwiftKeystone2ConfigurationReader.OBJECTSTORAGE_SWIFT_KEYSTONE_2_TENANTNAME,
 "test")
-                    .build())
-            .build();
-    }
-
-    private final PropertiesProvider keystone3PropertiesProvider() {
-        return FakePropertiesProvider.builder()
-            .register(OBJECTSTORAGE_CONFIGURATION_NAME,
-                swiftConfigBuilder()
-                    .put(OBJECTSTORAGE_SWIFT_AUTH_API, 
SwiftKeystone3ObjectStorage.AUTH_API_NAME)
-                    
.put(SwiftConfigurationReader.OBJECTSTORAGE_SWIFT_ENDPOINT, 
dockerSwift.keystoneV3Endpoint().toString())
-                    
.put(SwiftConfigurationReader.OBJECTSTORAGE_SWIFT_CREDENTIALS, "demo")
-                    
.put(SwiftKeystone3ConfigurationReader.OBJECTSTORAGE_SWIFT_KEYSTONE_3_USER_NAME,
 "demo")
-                    
.put(SwiftKeystone3ConfigurationReader.OBJECTSTORAGE_SWIFT_KEYSTONE_3_USER_DOMAIN,
 "Default")
-                    
.put(SwiftKeystone3ConfigurationReader.OBJECTSTORAGE_SWIFT_KEYSTONE_3_PROJECT_NAME,
 "test")
-                    .build())
-            .build();
-    }
-
-    @Test
-    void providesTempauthBackedBlobstoreDao() throws ConfigurationException {
-        ObjectStorageBlobsDAOProvider objectStorageBlobsDAOProvider =
-            new ObjectStorageBlobsDAOProvider(tempAuthPropertiesProvider(), 
BLOB_ID_FACTORY);
-        ObjectStorageBlobsDAO objectStorageBlobsDAO = 
objectStorageBlobsDAOProvider.get();
-        assertThat(objectStorageBlobsDAO).isNotNull();
-    }
-
-    @Test
-    void providesKeystone2BackedBlobstoreDao() throws ConfigurationException {
-        ObjectStorageBlobsDAOProvider objectStorageBlobsDAOProvider =
-            new ObjectStorageBlobsDAOProvider(keystone2PropertiesProvider(),
-                BLOB_ID_FACTORY);
-        ObjectStorageBlobsDAO objectStorageBlobsDAO = 
objectStorageBlobsDAOProvider.get();
-        assertThat(objectStorageBlobsDAO).isNotNull();
-    }
-
-    @Test
-    void providesKeystone3BackedBlobstoreDao() throws ConfigurationException {
-        ObjectStorageBlobsDAOProvider objectStorageBlobsDAOProvider =
-            new ObjectStorageBlobsDAOProvider(keystone3PropertiesProvider(),
-                BLOB_ID_FACTORY);
-        ObjectStorageBlobsDAO objectStorageBlobsDAO = 
objectStorageBlobsDAOProvider.get();
-        assertThat(objectStorageBlobsDAO).isNotNull();
-    }
-
-    private static MapConfigurationBuilder swiftConfigBuilder() {
-        return newConfigBuilder()
-            .put(PayloadCodecProvider.OBJECTSTORAGE_PAYLOAD_CODEC, 
PayloadCodecs.DEFAULT.name())
-            .put(OBJECTSTORAGE_PROVIDER, OBJECTSTORAGE_PROVIDER_SWIFT)
-            .put(OBJECTSTORAGE_NAMESPACE, "foo");
-    }
-
-    private static MapConfigurationBuilder newConfigBuilder() {
-        return new MapConfigurationBuilder();
-    }
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4d07616f/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/PayloadCodecProviderTest.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/PayloadCodecProviderTest.java
 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/PayloadCodecProviderTest.java
deleted file mode 100644
index b09ebf1..0000000
--- 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/PayloadCodecProviderTest.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/****************************************************************
- * 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.modules.objectstorage;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import org.apache.commons.configuration.MapConfiguration;
-import org.apache.james.blob.objectstorage.AESPayloadCodec;
-import org.apache.james.blob.objectstorage.DefaultPayloadCodec;
-import org.apache.james.blob.objectstorage.PayloadCodec;
-import org.junit.jupiter.api.Test;
-
-import com.google.common.collect.ImmutableMap;
-
-class PayloadCodecProviderTest {
-
-    private static final FakePropertiesProvider DEFAULT_PROPERTIES_PROVIDER =
-        FakePropertiesProvider.builder()
-            .register("objectstorage",
-                newConfigBuilder()
-                    .put("objectstorage.payload.codec", 
PayloadCodecs.DEFAULT.name())
-                    .build())
-            .build();
-
-    private static final FakePropertiesProvider EMPTY_PROPERTIES_PROVIDER =
-        FakePropertiesProvider.builder()
-            .register("objectstorage",
-                newConfigBuilder().build())
-            .build();
-
-    private static final FakePropertiesProvider AES_PROPERTIES_PROVIDER =
-        FakePropertiesProvider.builder()
-            .register("objectstorage",
-                newConfigBuilder()
-                    .put("objectstorage.payload.codec", 
PayloadCodecs.AES256.name())
-                    .put("objectstorage.aes256.hexsalt", 
"12345123451234512345")
-                    .put("objectstorage.aes256.password", "james is great")
-                    .build())
-            .build();
-
-    private static final FakePropertiesProvider 
MISSING_SALT_PROPERTIES_PROVIDER =
-        FakePropertiesProvider.builder()
-            .register("objectstorage",
-                newConfigBuilder()
-                    .put("objectstorage.payload.codec", 
PayloadCodecs.AES256.name())
-                    .put("objectstorage.aes256.password", "james is great")
-                    .build())
-            .build();
-
-    private static final FakePropertiesProvider EMPTY_SALT_PROPERTIES_PROVIDER 
=
-        FakePropertiesProvider.builder()
-            .register("objectstorage",
-                newConfigBuilder()
-                    .put("objectstorage.payload.codec", 
PayloadCodecs.AES256.name())
-                    .put("objectstorage.aes256.hexsalt", "")
-                    .put("objectstorage.aes256.password", "james is great")
-                    .build())
-            .build();
-
-    private static final FakePropertiesProvider 
MISSING_PASSWORD_PROPERTIES_PROVIDER =
-        FakePropertiesProvider.builder()
-            .register("objectstorage",
-                newConfigBuilder()
-                    .put("objectstorage.payload.codec", 
PayloadCodecs.AES256.name())
-                    .put("objectstorage.aes256.hexsalt", 
"12345123451234512345")
-                    .build())
-            .build();
-
-    private static final FakePropertiesProvider 
EMPTY_PASSWORD_PROPERTIES_PROVIDER =
-        FakePropertiesProvider.builder()
-            .register("objectstorage",
-                newConfigBuilder()
-                    .put("objectstorage.payload.codec", 
PayloadCodecs.AES256.name())
-                    .put("objectstorage.aes256.hexsalt", 
"12345123451234512345")
-                    .put("objectstorage.aes256.password", "")
-                    .build())
-            .build();
-
-    @Test
-    void shouldBuildADefaultPayloadCodecForDefaultConfig() throws Exception {
-        PayloadCodec payloadCodec = new 
PayloadCodecProvider(DEFAULT_PROPERTIES_PROVIDER).get();
-        assertThat(payloadCodec).isInstanceOf(DefaultPayloadCodec.class);
-    }
-
-    @Test
-    void shouldBuildAnAESPayloadCodecForAESConfig() throws Exception {
-        PayloadCodec payloadCodec = new 
PayloadCodecProvider(AES_PROPERTIES_PROVIDER).get();
-        assertThat(payloadCodec).isInstanceOf(AESPayloadCodec.class);
-    }
-
-    @Test
-    void shouldFailIfCodecKeyIsMissing() throws Exception {
-        assertThatThrownBy(() -> new 
PayloadCodecProvider(EMPTY_PROPERTIES_PROVIDER).get()).isInstanceOf(IllegalArgumentException.class);
-    }
-
-    @Test
-    void shouldFailIfCodecKeyIsIncorrect() throws Exception {
-        FakePropertiesProvider propertiesWithTypo = 
FakePropertiesProvider.builder()
-            .register("objectstorage",
-                newConfigBuilder()
-                    .put("objectstorage.payload.codec", "aes255")
-                    .put("objectstorage.aes256.password", "james is great")
-                    .build())
-            .build();
-        assertThatThrownBy(() -> new 
PayloadCodecProvider(propertiesWithTypo).get()).isInstanceOf(IllegalArgumentException.class);
-    }
-
-    @Test
-    void shouldFailForAESCodecWhenSaltKeyIsMissing() throws Exception {
-        assertThatThrownBy(() -> new 
PayloadCodecProvider(MISSING_SALT_PROPERTIES_PROVIDER).get()).isInstanceOf(IllegalArgumentException.class);
-    }
-
-    @Test
-    void shouldFailForAESCodecWhenSaltKeyIsEmpty() throws Exception {
-        assertThatThrownBy(() -> new 
PayloadCodecProvider(EMPTY_SALT_PROPERTIES_PROVIDER).get()).isInstanceOf(IllegalArgumentException.class);
-    }
-
-    @Test
-    void shouldFailForAESCodecWhenPasswordKeyIsMissing() throws Exception {
-
-        assertThatThrownBy(() -> new 
PayloadCodecProvider(MISSING_PASSWORD_PROPERTIES_PROVIDER).get()).isInstanceOf(IllegalArgumentException.class);
-    }
-
-    @Test
-    void shouldFailForAESCodecWhenPasswordKeyIsEmpty() throws Exception {
-
-        assertThatThrownBy(() -> new 
PayloadCodecProvider(EMPTY_PASSWORD_PROPERTIES_PROVIDER).get()).isInstanceOf(IllegalArgumentException.class);
-    }
-
-    private static MapConfigurationBuilder newConfigBuilder() {
-        return new MapConfigurationBuilder();
-    }
-
-    private static class MapConfigurationBuilder {
-        private ImmutableMap.Builder<String, Object> config;
-
-        public MapConfigurationBuilder() {
-            this.config = new ImmutableMap.Builder<>();
-        }
-
-        public MapConfigurationBuilder put(String key, Object value) {
-            config.put(key, value);
-            return this;
-        }
-
-        public MapConfiguration build() {
-            return new MapConfiguration(config.build());
-        }
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/james-project/blob/4d07616f/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/guice/DockerSwiftTestRule.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/guice/DockerSwiftTestRule.java
 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/guice/DockerSwiftTestRule.java
index 905a6b6..82c56af 100644
--- 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/guice/DockerSwiftTestRule.java
+++ 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/guice/DockerSwiftTestRule.java
@@ -19,22 +19,24 @@
 
 package org.apache.james.modules.objectstorage.guice;
 
-import java.util.HashMap;
-import java.util.Map;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.UUID;
 
-import org.apache.commons.configuration.MapConfiguration;
 import org.apache.james.GuiceModuleTestRule;
 import org.apache.james.blob.api.BlobStore;
 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.PayloadCodec;
+import org.apache.james.modules.objectstorage.ObjectStorageBlobConfiguration;
 import org.apache.james.blob.objectstorage.swift.Credentials;
 import org.apache.james.blob.objectstorage.swift.SwiftKeystone2ObjectStorage;
+import org.apache.james.blob.objectstorage.swift.SwiftTempAuthObjectStorage;
+import 
org.apache.james.blob.objectstorage.swift.SwiftTempAuthObjectStorage.Configuration;
 import org.apache.james.blob.objectstorage.swift.TenantName;
 import org.apache.james.blob.objectstorage.swift.UserName;
-import org.apache.james.modules.objectstorage.PayloadCodecs;
+import org.apache.james.modules.objectstorage.PayloadCodecFactory;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 import org.testcontainers.containers.GenericContainer;
@@ -47,17 +49,14 @@ public class DockerSwiftTestRule implements 
GuiceModuleTestRule {
 
     private org.apache.james.blob.objectstorage.DockerSwiftRule swiftContainer 
=
         new org.apache.james.blob.objectstorage.DockerSwiftRule();
-    private final PayloadCodec payloadCodec;
+    private PayloadCodec payloadCodec;
 
     public DockerSwiftTestRule() {
-        this(PayloadCodecs.DEFAULT);
+        this(PayloadCodecFactory.DEFAULT);
     }
 
-    public DockerSwiftTestRule(PayloadCodecs payloadCodec) {
-        Map<String, Object> payloadCodecConfig = new HashMap<>();
-        payloadCodecConfig.put(PayloadCodecs.OBJECTSTORAGE_AES256_HEXSALT, 
"c603a7327ee3dcbc031d8d34b1096c605feca5e1");
-        payloadCodecConfig.put(PayloadCodecs.OBJECTSTORAGE_AES256_PASSWORD, 
"dockerSwiftEncryption");
-        this.payloadCodec = payloadCodec.codec(new 
MapConfiguration(payloadCodecConfig));
+    public DockerSwiftTestRule(PayloadCodecFactory payloadCodecFactory) {
+        //Will be fixed in next commit
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/4d07616f/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/objectstore/BlobStoreChoosingModule.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/objectstore/BlobStoreChoosingModule.java
 
b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/objectstore/BlobStoreChoosingModule.java
index 2acd8c1..510cee1 100644
--- 
a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/objectstore/BlobStoreChoosingModule.java
+++ 
b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/objectstore/BlobStoreChoosingModule.java
@@ -31,8 +31,7 @@ import org.apache.james.blob.api.BlobStore;
 import org.apache.james.blob.cassandra.CassandraBlobModule;
 import org.apache.james.blob.cassandra.CassandraBlobsDAO;
 import org.apache.james.blob.objectstorage.ObjectStorageBlobsDAO;
-import org.apache.james.blob.objectstorage.PayloadCodec;
-import org.apache.james.modules.objectstorage.PayloadCodecProvider;
+import org.apache.james.modules.objectstorage.ObjectStorageDependenciesModule;
 import org.apache.james.utils.PropertiesProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -40,7 +39,6 @@ import org.slf4j.LoggerFactory;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
-import com.google.inject.Scopes;
 import com.google.inject.multibindings.Multibinder;
 
 public class BlobStoreChoosingModule extends AbstractModule {
@@ -51,7 +49,7 @@ public class BlobStoreChoosingModule extends AbstractModule {
 
     @Override
     protected void configure() {
-        
bind(PayloadCodec.class).toProvider(PayloadCodecProvider.class).in(Scopes.SINGLETON);
+        install(new ObjectStorageDependenciesModule());
 
         Multibinder<CassandraModule> cassandraDataDefinitions = 
Multibinder.newSetBinder(binder(), CassandraModule.class);
         
cassandraDataDefinitions.addBinding().toInstance(CassandraBlobModule.MODULE);
@@ -80,4 +78,5 @@ public class BlobStoreChoosingModule extends AbstractModule {
             return cassandraBlobStoreProvider.get();
         }
     }
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4d07616f/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CucumberSwiftSingleton.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CucumberSwiftSingleton.java
 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CucumberSwiftSingleton.java
index 6a4eb04..09200cd 100644
--- 
a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CucumberSwiftSingleton.java
+++ 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CucumberSwiftSingleton.java
@@ -18,11 +18,11 @@
  ****************************************************************/
 package org.apache.james.jmap.cassandra.cucumber;
 
-import org.apache.james.modules.objectstorage.PayloadCodecs;
+import org.apache.james.modules.objectstorage.PayloadCodecFactory;
 import org.apache.james.modules.objectstorage.guice.DockerSwiftTestRule;
 
 public class CucumberSwiftSingleton {
 
     public static DockerSwiftTestRule swiftServer = new DockerSwiftTestRule();
-    public static DockerSwiftTestRule encryptedSwiftServer = new 
DockerSwiftTestRule(PayloadCodecs.AES256);
+    public static DockerSwiftTestRule encryptedSwiftServer = new 
DockerSwiftTestRule(PayloadCodecFactory.AES256);
 }


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

Reply via email to