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 44e376390b227684b45c27dc539dff010ab78d4e
Author: Antoine Duprat <adup...@linagora.com>
AuthorDate: Tue Feb 26 11:24:50 2019 +0100

    JAMES-2669 Extract Swift as a specific object storage implementation
---
 .../ObjectStorageBlobConfiguration.java            | 140 +++++-------------
 .../ObjectStorageDependenciesModule.java           |  18 +--
 .../objectstorage/SpecificAuthConfiguration.java   |  24 +++
 .../objectstorage/SwiftConfigurationReader.java    |  26 ----
 .../swift/SwiftAuthConfiguration.java              | 128 ++++++++++++++++
 .../objectstorage/swift/SwiftConfiguration.java    |  26 ++++
 .../SwiftKeystone2ConfigurationReader.java         |  40 ++---
 .../SwiftKeystone3ConfigurationReader.java         |  42 +++---
 .../objectstorage/swift/SwiftObjectStorage.java    |  66 +++++++++
 .../SwiftTmpAuthConfigurationReader.java           |  42 +++---
 .../objectstorage/MapConfigurationBuilder.java     |   2 +-
 .../ObjectStorageBlobConfigurationTest.java        |  89 ------------
 .../SwiftKeystone2ConfigurationReaderTest.java     |   1 +
 .../SwiftKeystone3ConfigurationReaderTest.java     |   1 +
 .../SwiftTmpAuthConfigurationReaderTest.java       |   1 +
 .../{guice => swift}/DockerSwiftTestRule.java      |  49 ++++---
 .../ObjectStorageBlobConfigurationTest.java        | 161 ++++++---------------
 .../ObjectStorageBlobStoreModuleTest.java          |  94 +++++++-----
 .../swift/SwiftObjectStorageTest.java              | 127 ++++++++++++++++
 .../james/CassandraRabbitMQJamesServerTest.java    |   2 +-
 .../james/modules/SwiftBlobStoreExtension.java     |   2 +-
 .../james/modules/TestSwiftBlobStoreModule.java    |   2 +-
 .../cassandra/cucumber/CucumberSwiftSingleton.java |   2 +-
 .../rabbitmq/cucumber/CucumberSwiftSingleton.java  |   2 +-
 .../jmap/rabbitmq/cucumber/RabbitMQStepdefs.java   |   2 +-
 25 files changed, 607 insertions(+), 482 deletions(-)

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
index 01903e0..b36576f 100644
--- 
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
@@ -27,9 +27,7 @@ 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.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.modules.objectstorage.swift.SwiftAuthConfiguration;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.MoreObjects;
@@ -37,10 +35,9 @@ import com.google.common.base.Strings;
 
 public class ObjectStorageBlobConfiguration {
 
-    private static final String OBJECTSTORAGE_CONFIGURATION_NAME = "blobstore";
+    public static final String OBJECTSTORAGE_CONFIGURATION_NAME = "blobstore";
     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";
@@ -48,7 +45,6 @@ public class ObjectStorageBlobConfiguration {
     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))
@@ -57,9 +53,6 @@ public class ObjectStorageBlobConfiguration {
         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");
         }
@@ -72,101 +65,61 @@ public class ObjectStorageBlobConfiguration {
             .findAny()
             .orElseThrow(() -> new ConfigurationException("unknown payload 
codec : " + codecName));
 
-        Builder.RequireAuthConfiguration requireAuthConfiguration = builder()
+        return builder()
             .codec(payloadCodecFactory)
             .provider(ObjectStorageProvider.from(provider))
-            .container(ContainerName.of(namespace));
-
-        return defineAuthApi(configuration, authApi, requireAuthConfiguration)
+            .container(ContainerName.of(namespace))
+            
.authConfiguration(SwiftAuthConfiguration.defineAuthApi(configuration))
             .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 -> provider -> container -> new 
Builder.RequireAuthConfiguration(payloadCodec, provider, container);
+        return payloadCodec -> provider -> container -> authConfiguration -> 
new Builder.ReadyToBuild(payloadCodec, provider, container, authConfiguration);
     }
 
     public interface Builder {
         @FunctionalInterface
-        public interface RequirePayloadCodec {
+        interface RequirePayloadCodec {
             RequireProvider codec(PayloadCodecFactory codec);
         }
 
         @FunctionalInterface
-        public interface RequireProvider {
+        interface RequireProvider {
             RequireContainerName provider(ObjectStorageProvider provider);
         }
 
         @FunctionalInterface
-        public interface RequireContainerName {
+        interface RequireContainerName {
             RequireAuthConfiguration container(ContainerName container);
         }
 
-        public static class RequireAuthConfiguration {
-
-            private final PayloadCodecFactory payloadCodec;
-            private final ObjectStorageProvider provider;
-            private final ContainerName container;
-
-            private RequireAuthConfiguration(PayloadCodecFactory payloadCodec, 
ObjectStorageProvider 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));
-            }
+        @FunctionalInterface
+        interface RequireAuthConfiguration {
+            ReadyToBuild authConfiguration(SpecificAuthConfiguration 
authConfiguration);
         }
 
-        public static class ReadyToBuild {
+        class ReadyToBuild {
 
             private final PayloadCodecFactory payloadCodecFactory;
             private final ObjectStorageProvider 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 final SpecificAuthConfiguration specificAuthConfiguration;
             private Optional<String> aesSalt;
             private Optional<char[]> aesPassword;
 
-            public ReadyToBuild(PayloadCodecFactory payloadCodecFactory, 
ObjectStorageProvider provider,
-                                ContainerName container, String authApiName,
-                                
Optional<SwiftTempAuthObjectStorage.Configuration> tempAuth,
-                                
Optional<SwiftKeystone2ObjectStorage.Configuration> keystone2Configuration,
-                                
Optional<SwiftKeystone3ObjectStorage.Configuration> keystone3Configuration) {
+            public ReadyToBuild(PayloadCodecFactory payloadCodecFactory,
+                                ObjectStorageProvider provider,
+                                ContainerName container,
+                                SpecificAuthConfiguration 
specificAuthConfiguration) {
                 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;
+                this.specificAuthConfiguration = specificAuthConfiguration;
             }
 
             public ReadyToBuild aesSalt(String aesSalt) {
@@ -195,8 +148,7 @@ public class ObjectStorageBlobConfiguration {
                         .orElseThrow(() -> new IllegalStateException("AES code 
requires an non-empty password parameter"));
                 }
 
-                return new ObjectStorageBlobConfiguration(payloadCodecFactory, 
provider, container, aesSalt, aesPassword,
-                    authApiName, tempAuth, keystone2Configuration, 
keystone3Configuration);
+                return new ObjectStorageBlobConfiguration(payloadCodecFactory, 
provider, container, specificAuthConfiguration, aesSalt, aesPassword);
             }
 
         }
@@ -204,36 +156,24 @@ public class ObjectStorageBlobConfiguration {
     }
 
     private final PayloadCodecFactory payloadCodec;
-    private final String authApi;
     private final ContainerName namespace;
     private final ObjectStorageProvider provider;
-    private final Optional<SwiftTempAuthObjectStorage.Configuration> tempAuth;
-    private final Optional<SwiftKeystone2ObjectStorage.Configuration> 
keystone2Configuration;
-    private final Optional<SwiftKeystone3ObjectStorage.Configuration> 
keystone3Configuration;
+    private final SpecificAuthConfiguration specificAuthConfiguration;
     private Optional<String> aesSalt;
     private Optional<char[]> aesPassword;
 
     @VisibleForTesting
     ObjectStorageBlobConfiguration(PayloadCodecFactory payloadCodec, 
ObjectStorageProvider provider,
                                    ContainerName namespace,
+                                   SpecificAuthConfiguration 
specificAuthConfiguration,
                                    Optional<String> aesSalt,
-                                   Optional<char[]> aesPassword, String 
authApi,
-                                   
Optional<SwiftTempAuthObjectStorage.Configuration> tempAuth,
-                                   
Optional<SwiftKeystone2ObjectStorage.Configuration> keystone2Configuration,
-                                   
Optional<SwiftKeystone3ObjectStorage.Configuration> keystone3Configuration) {
+                                   Optional<char[]> aesPassword) {
         this.payloadCodec = payloadCodec;
+        this.provider = provider;
+        this.namespace = namespace;
+        this.specificAuthConfiguration = specificAuthConfiguration;
         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() {
@@ -244,18 +184,6 @@ public class ObjectStorageBlobConfiguration {
         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;
     }
@@ -264,6 +192,10 @@ public class ObjectStorageBlobConfiguration {
         return payloadCodec.create(this);
     }
 
+    public SpecificAuthConfiguration getSpecificAuthConfiguration() {
+        return specificAuthConfiguration;
+    }
+
     public Optional<String> getAesSalt() {
         return aesSalt;
     }
@@ -282,31 +214,25 @@ public class ObjectStorageBlobConfiguration {
         }
         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(specificAuthConfiguration, 
that.specificAuthConfiguration) &&
             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);
+        return Objects.hash(payloadCodec, namespace, provider, 
specificAuthConfiguration, 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("specificAuthConfiguration", specificAuthConfiguration)
             .add("aesSalt", aesSalt)
             .add("aesPassword", aesPassword)
             .toString();
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 209ad4b..3d63afd 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,10 +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.swift.SwiftKeystone2ObjectStorage;
-import org.apache.james.blob.objectstorage.swift.SwiftKeystone3ObjectStorage;
-import org.apache.james.blob.objectstorage.swift.SwiftTempAuthObjectStorage;
 import org.apache.james.modules.mailbox.ConfigurationComponent;
+import org.apache.james.modules.objectstorage.swift.SwiftObjectStorage;
 import org.apache.james.utils.PropertiesProvider;
 
 import com.google.inject.AbstractModule;
@@ -73,19 +71,7 @@ public class ObjectStorageDependenciesModule extends 
AbstractModule {
     }
 
     private ObjectStorageBlobsDAOBuilder.RequireContainerName 
selectDaoBuilder(ObjectStorageBlobConfiguration configuration) {
-        if (configuration.getProvider() != ObjectStorageProvider.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());
-        }
+        return SwiftObjectStorage.builder(configuration);
     }
 
 }
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/SpecificAuthConfiguration.java
 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/SpecificAuthConfiguration.java
new file mode 100644
index 0000000..0049288
--- /dev/null
+++ 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/SpecificAuthConfiguration.java
@@ -0,0 +1,24 @@
+/*
+ * 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;
+
+
+public interface SpecificAuthConfiguration {
+}
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/SwiftConfigurationReader.java
 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/SwiftConfigurationReader.java
deleted file mode 100644
index 662a894..0000000
--- 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/SwiftConfigurationReader.java
+++ /dev/null
@@ -1,26 +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;
-
-public interface SwiftConfigurationReader {
-    String OBJECTSTORAGE_SWIFT_ENDPOINT = "objectstorage.swift.endpoint";
-    String OBJECTSTORAGE_SWIFT_CREDENTIALS = "objectstorage.swift.credentials";
-    String OBJECTSTORAGE_SWIFT_REGION = "objectstorage.swift.region";
-}
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftAuthConfiguration.java
 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftAuthConfiguration.java
new file mode 100644
index 0000000..9ded9a5
--- /dev/null
+++ 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftAuthConfiguration.java
@@ -0,0 +1,128 @@
+/*
+ * 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.swift;
+
+import java.util.Optional;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+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.modules.objectstorage.ObjectStorageBlobConfiguration;
+import org.apache.james.modules.objectstorage.SpecificAuthConfiguration;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.base.Strings;
+
+public class SwiftAuthConfiguration implements SpecificAuthConfiguration {
+
+    private static final String OBJECTSTORAGE_SWIFT_AUTH_API = 
"objectstorage.swift.authapi";
+
+    public static SwiftAuthConfiguration defineAuthApi(Configuration 
configuration) throws ConfigurationException {
+        String authApi = configuration.getString(OBJECTSTORAGE_SWIFT_AUTH_API, 
null);
+        if (Strings.isNullOrEmpty(authApi)) {
+            throw new ConfigurationException("Mandatory configuration value " 
+ OBJECTSTORAGE_SWIFT_AUTH_API + " is missing from " + 
ObjectStorageBlobConfiguration.OBJECTSTORAGE_CONFIGURATION_NAME + " 
configuration");
+        }
+
+        switch (authApi) {
+            case SwiftTempAuthObjectStorage.AUTH_API_NAME:
+                return 
tempAuth(SwiftTmpAuthConfigurationReader.readSwiftConfiguration(configuration));
+            case SwiftKeystone2ObjectStorage.AUTH_API_NAME:
+                return 
keystone2(SwiftKeystone2ConfigurationReader.readSwiftConfiguration(configuration));
+            case SwiftKeystone3ObjectStorage.AUTH_API_NAME:
+                return 
keystone3(SwiftKeystone3ConfigurationReader.readSwiftConfiguration(configuration));
+        }
+        throw new IllegalStateException("unexpected auth api " + authApi);
+    }
+
+    private static SwiftAuthConfiguration 
tempAuth(SwiftTempAuthObjectStorage.Configuration authConfig) {
+        return new 
SwiftAuthConfiguration(SwiftTempAuthObjectStorage.AUTH_API_NAME, 
Optional.of(authConfig), Optional.empty(), Optional.empty());
+    }
+
+    private static SwiftAuthConfiguration 
keystone2(SwiftKeystone2ObjectStorage.Configuration authConfig) {
+        return new 
SwiftAuthConfiguration(SwiftKeystone2ObjectStorage.AUTH_API_NAME, 
Optional.empty(), Optional.of(authConfig), Optional.empty());
+    }
+
+    private static SwiftAuthConfiguration 
keystone3(SwiftKeystone3ObjectStorage.Configuration authConfig) {
+        return new 
SwiftAuthConfiguration(SwiftKeystone3ObjectStorage.AUTH_API_NAME, 
Optional.empty(), Optional.empty(), Optional.of(authConfig));
+    }
+
+    private final String authApiName;
+    private final Optional<SwiftTempAuthObjectStorage.Configuration> tempAuth;
+    private final Optional<SwiftKeystone2ObjectStorage.Configuration> 
keystone2Configuration;
+    private final Optional<SwiftKeystone3ObjectStorage.Configuration> 
keystone3Configuration;
+
+    @VisibleForTesting
+    SwiftAuthConfiguration(String authApiName,
+                           Optional<SwiftTempAuthObjectStorage.Configuration> 
tempAuth,
+                           Optional<SwiftKeystone2ObjectStorage.Configuration> 
keystone2Configuration,
+                           Optional<SwiftKeystone3ObjectStorage.Configuration> 
keystone3Configuration) {
+        this.authApiName = authApiName;
+        this.tempAuth = tempAuth;
+        this.keystone2Configuration = keystone2Configuration;
+        this.keystone3Configuration = keystone3Configuration;
+    }
+
+    public String getAuthApiName() {
+        return authApiName;
+    }
+
+    public Optional<SwiftTempAuthObjectStorage.Configuration> getTempAuth() {
+        return tempAuth;
+    }
+
+    public Optional<SwiftKeystone2ObjectStorage.Configuration> 
getKeystone2Configuration() {
+        return keystone2Configuration;
+    }
+
+    public Optional<SwiftKeystone3ObjectStorage.Configuration> 
getKeystone3Configuration() {
+        return keystone3Configuration;
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof SwiftAuthConfiguration) {
+            SwiftAuthConfiguration that = (SwiftAuthConfiguration) o;
+            return Objects.equal(authApiName, that.authApiName) &&
+                Objects.equal(tempAuth, that.tempAuth) &&
+                Objects.equal(keystone2Configuration, 
that.keystone2Configuration) &&
+                Objects.equal(keystone3Configuration, 
that.keystone3Configuration);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hashCode(authApiName, tempAuth, keystone2Configuration, 
keystone3Configuration);
+    }
+
+    @Override
+    public final String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("authApiName", authApiName)
+            .add("tempAuth", tempAuth)
+            .add("keystone2Configuration", keystone2Configuration)
+            .add("keystone3Configuration", keystone3Configuration)
+            .toString();
+    }
+}
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftConfiguration.java
 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftConfiguration.java
new file mode 100644
index 0000000..ab9a10f
--- /dev/null
+++ 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftConfiguration.java
@@ -0,0 +1,26 @@
+/*
+ * 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.swift;
+
+public interface SwiftConfiguration {
+    String OBJECTSTORAGE_SWIFT_ENDPOINT = "objectstorage.swift.endpoint";
+    String OBJECTSTORAGE_SWIFT_CREDENTIALS = "objectstorage.swift.credentials";
+    String OBJECTSTORAGE_SWIFT_REGION = "objectstorage.swift.region";
+}
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/SwiftKeystone2ConfigurationReader.java
 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftKeystone2ConfigurationReader.java
similarity index 67%
rename from 
server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/SwiftKeystone2ConfigurationReader.java
rename to 
server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftKeystone2ConfigurationReader.java
index 26f951f..d69555f 100644
--- 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/SwiftKeystone2ConfigurationReader.java
+++ 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftKeystone2ConfigurationReader.java
@@ -1,23 +1,23 @@
-/****************************************************************
- * 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.                                           *
- ****************************************************************/
+/*
+ * 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;
+package org.apache.james.modules.objectstorage.swift;
 
 import java.net.URI;
 import java.util.Optional;
@@ -32,7 +32,7 @@ import org.apache.james.blob.objectstorage.swift.UserName;
 
 import com.google.common.base.Preconditions;
 
-public class SwiftKeystone2ConfigurationReader implements 
SwiftConfigurationReader {
+public class SwiftKeystone2ConfigurationReader implements SwiftConfiguration {
 
     static final String OBJECTSTORAGE_SWIFT_KEYSTONE_2_USERNAME =
         "objectstorage.swift.keystone2.username";
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/SwiftKeystone3ConfigurationReader.java
 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftKeystone3ConfigurationReader.java
similarity index 79%
rename from 
server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/SwiftKeystone3ConfigurationReader.java
rename to 
server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftKeystone3ConfigurationReader.java
index 5263e19..46348d3 100644
--- 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/SwiftKeystone3ConfigurationReader.java
+++ 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftKeystone3ConfigurationReader.java
@@ -1,23 +1,23 @@
-/****************************************************************
- * 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;
+/*
+ * 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.swift;
 
 import java.net.URI;
 import java.util.Optional;
@@ -41,7 +41,7 @@ import com.google.common.base.Preconditions;
  *
  * @link 
https://developer.openstack.org/api-ref/identity/v3/#authentication-and-token-management
  */
-public class SwiftKeystone3ConfigurationReader implements 
SwiftConfigurationReader {
+public class SwiftKeystone3ConfigurationReader implements SwiftConfiguration {
 
     static final String OBJECTSTORAGE_SWIFT_KEYSTONE_3_USER_NAME =
         "objectstorage.swift.keystone3.user.name";
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftObjectStorage.java
 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftObjectStorage.java
new file mode 100644
index 0000000..bf5c9da
--- /dev/null
+++ 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftObjectStorage.java
@@ -0,0 +1,66 @@
+/*
+ * 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.swift;
+
+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.modules.objectstorage.ObjectStorageBlobConfiguration;
+import org.apache.james.modules.objectstorage.ObjectStorageProvider;
+
+public class SwiftObjectStorage {
+
+    public static ObjectStorageBlobsDAOBuilder.RequireContainerName 
builder(ObjectStorageBlobConfiguration configuration) {
+        if (configuration.getProvider() != ObjectStorageProvider.SWIFT) {
+            throw new IllegalArgumentException("unknown provider " + 
configuration.getProvider());
+        }
+        SwiftAuthConfiguration authConfiguration = (SwiftAuthConfiguration) 
configuration.getSpecificAuthConfiguration();
+        switch (authConfiguration.getAuthApiName()) {
+            case SwiftTempAuthObjectStorage.AUTH_API_NAME:
+                return authConfiguration.getTempAuth()
+                                    .map(ObjectStorageBlobsDAO::builder)
+                                    .orElseThrow(() -> new 
IllegalArgumentException("No TempAuth configuration found for tmpauth API"));
+            case SwiftKeystone2ObjectStorage.AUTH_API_NAME:
+                return authConfiguration.getKeystone2Configuration()
+                                    .map(ObjectStorageBlobsDAO::builder)
+                                    .orElseThrow(() -> new 
IllegalArgumentException("No Keystone2 configuration found for keystone2 API"));
+            case SwiftKeystone3ObjectStorage.AUTH_API_NAME:
+                return authConfiguration.getKeystone3Configuration()
+                                    .map(ObjectStorageBlobsDAO::builder)
+                                    .orElseThrow(() -> new 
IllegalArgumentException("No Keystone3 configuration found for keystone3 API"));
+            default:
+                throw new IllegalArgumentException("unknown auth api " + 
authConfiguration.getAuthApiName());
+        }
+    }
+
+    public static ObjectStorageBlobsDAOBuilder.RequireContainerName 
builder(SwiftTempAuthObjectStorage.Configuration testConfig) {
+        return SwiftTempAuthObjectStorage.daoBuilder(testConfig);
+    }
+
+    public static ObjectStorageBlobsDAOBuilder.RequireContainerName 
builder(SwiftKeystone2ObjectStorage.Configuration testConfig) {
+        return SwiftKeystone2ObjectStorage.daoBuilder(testConfig);
+    }
+
+    public static ObjectStorageBlobsDAOBuilder.RequireContainerName 
builder(SwiftKeystone3ObjectStorage.Configuration testConfig) {
+        return SwiftKeystone3ObjectStorage.daoBuilder(testConfig);
+    }
+}
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/SwiftTmpAuthConfigurationReader.java
 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftTmpAuthConfigurationReader.java
similarity index 71%
rename from 
server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/SwiftTmpAuthConfigurationReader.java
rename to 
server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftTmpAuthConfigurationReader.java
index 1066849..522da64 100644
--- 
a/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/SwiftTmpAuthConfigurationReader.java
+++ 
b/server/container/guice/blob-objectstorage-guice/src/main/java/org/apache/james/modules/objectstorage/swift/SwiftTmpAuthConfigurationReader.java
@@ -1,23 +1,23 @@
-/****************************************************************
- * 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.                                           *
- ****************************************************************/
+/*
+ * 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;
+package org.apache.james.modules.objectstorage.swift;
 
 import java.net.URI;
 import java.util.Optional;
@@ -34,7 +34,7 @@ import org.apache.james.blob.objectstorage.swift.UserName;
 
 import com.google.common.base.Preconditions;
 
-public class SwiftTmpAuthConfigurationReader implements 
SwiftConfigurationReader {
+public class SwiftTmpAuthConfigurationReader implements SwiftConfiguration {
 
     static final String OBJECTSTORAGE_SWIFT_TEMPAUTH_USERNAME =
         "objectstorage.swift.tempauth.username";
@@ -67,7 +67,7 @@ public class SwiftTmpAuthConfigurationReader implements 
SwiftConfigurationReader
         Identity identity = Identity.of(tenantName, userName);
 
         Optional<Region> region = Optional.ofNullable(
-                
configuration.getString(SwiftConfigurationReader.OBJECTSTORAGE_SWIFT_REGION, 
null))
+                
configuration.getString(SwiftConfiguration.OBJECTSTORAGE_SWIFT_REGION, null))
             .map(Region::of);
 
         Optional<PassHeaderName> passHeaderName = Optional.ofNullable(
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/MapConfigurationBuilder.java
 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/MapConfigurationBuilder.java
index 1753b54..48168d0 100644
--- 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/MapConfigurationBuilder.java
+++ 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/MapConfigurationBuilder.java
@@ -23,7 +23,7 @@ import org.apache.commons.configuration.MapConfiguration;
 
 import com.google.common.collect.ImmutableMap;
 
-class MapConfigurationBuilder {
+public class MapConfigurationBuilder {
     private ImmutableMap.Builder<String, Object> config;
 
     public MapConfigurationBuilder() {
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
index 8dabe90..004b7bf 100644
--- 
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
@@ -157,93 +157,4 @@ class ObjectStorageBlobConfigurationTest {
         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)
-                    .provider(ObjectStorageProvider.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)
-                    .provider(ObjectStorageProvider.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)
-                    .provider(ObjectStorageProvider.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
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/SwiftKeystone2ConfigurationReaderTest.java
 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/SwiftKeystone2ConfigurationReaderTest.java
index 83ed3c9..0fbf3c1 100644
--- 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/SwiftKeystone2ConfigurationReaderTest.java
+++ 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/SwiftKeystone2ConfigurationReaderTest.java
@@ -33,6 +33,7 @@ import org.apache.james.blob.objectstorage.swift.Region;
 import org.apache.james.blob.objectstorage.swift.SwiftKeystone2ObjectStorage;
 import org.apache.james.blob.objectstorage.swift.TenantName;
 import org.apache.james.blob.objectstorage.swift.UserName;
+import 
org.apache.james.modules.objectstorage.swift.SwiftKeystone2ConfigurationReader;
 import org.junit.jupiter.api.Test;
 
 class SwiftKeystone2ConfigurationReaderTest {
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/SwiftKeystone3ConfigurationReaderTest.java
 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/SwiftKeystone3ConfigurationReaderTest.java
index 0d1dbf0..b590ef8 100644
--- 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/SwiftKeystone3ConfigurationReaderTest.java
+++ 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/SwiftKeystone3ConfigurationReaderTest.java
@@ -37,6 +37,7 @@ import org.apache.james.blob.objectstorage.swift.ProjectName;
 import org.apache.james.blob.objectstorage.swift.Region;
 import org.apache.james.blob.objectstorage.swift.SwiftKeystone3ObjectStorage;
 import org.apache.james.blob.objectstorage.swift.UserName;
+import 
org.apache.james.modules.objectstorage.swift.SwiftKeystone3ConfigurationReader;
 import org.junit.jupiter.api.Test;
 
 class SwiftKeystone3ConfigurationReaderTest {
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/SwiftTmpAuthConfigurationReaderTest.java
 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/SwiftTmpAuthConfigurationReaderTest.java
index 5eeb96e..c719a01 100644
--- 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/SwiftTmpAuthConfigurationReaderTest.java
+++ 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/SwiftTmpAuthConfigurationReaderTest.java
@@ -35,6 +35,7 @@ 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.apache.james.modules.objectstorage.swift.SwiftTmpAuthConfigurationReader;
 import org.junit.jupiter.api.Test;
 
 class SwiftTmpAuthConfigurationReaderTest {
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/swift/DockerSwiftTestRule.java
similarity index 75%
rename from 
server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/guice/DockerSwiftTestRule.java
rename to 
server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/swift/DockerSwiftTestRule.java
index f3ad780..76481c3 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/swift/DockerSwiftTestRule.java
@@ -1,24 +1,25 @@
-/****************************************************************
- * 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.guice;
-
+/*
+ * 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.swift;
+
+import java.util.Optional;
 import java.util.UUID;
 
 import javax.inject.Inject;
@@ -35,6 +36,7 @@ import org.apache.james.blob.objectstorage.swift.UserName;
 import org.apache.james.modules.objectstorage.ObjectStorageBlobConfiguration;
 import org.apache.james.modules.objectstorage.ObjectStorageProvider;
 import org.apache.james.modules.objectstorage.PayloadCodecFactory;
+import org.apache.james.modules.objectstorage.swift.SwiftAuthConfiguration;
 import org.apache.james.utils.GuiceProbe;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
@@ -110,7 +112,10 @@ public class DockerSwiftTestRule implements 
GuiceModuleTestRule {
             .codec(payloadCodecFactory)
             .provider(ObjectStorageProvider.SWIFT)
             .container(containerName)
-            .keystone2(authConfiguration)
+            .authConfiguration(new 
SwiftAuthConfiguration(SwiftKeystone2ObjectStorage.AUTH_API_NAME,
+                Optional.empty(),
+                Optional.of(authConfiguration),
+                Optional.empty()))
             .aesSalt("c603a7327ee3dcbc031d8d34b1096c605feca5e1")
             .aesPassword("dockerSwiftEncryption".toCharArray())
             .build();
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/swift/ObjectStorageBlobConfigurationTest.java
similarity index 54%
copy from 
server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/ObjectStorageBlobConfigurationTest.java
copy to 
server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/swift/ObjectStorageBlobConfigurationTest.java
index 8dabe90..631ae4c 100644
--- 
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/swift/ObjectStorageBlobConfigurationTest.java
@@ -1,10 +1,30 @@
-package org.apache.james.modules.objectstorage;
+/*
+ * 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.swift;
 
 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.Optional;
 import java.util.stream.Stream;
 
 import org.apache.commons.configuration.ConfigurationException;
@@ -22,6 +42,10 @@ 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.apache.james.modules.objectstorage.MapConfigurationBuilder;
+import org.apache.james.modules.objectstorage.ObjectStorageBlobConfiguration;
+import org.apache.james.modules.objectstorage.ObjectStorageProvider;
+import org.apache.james.modules.objectstorage.PayloadCodecFactory;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtensionContext;
 import org.junit.jupiter.params.ParameterizedTest;
@@ -59,104 +83,6 @@ class ObjectStorageBlobConfigurationTest {
         }
     }
 
-    @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(
@@ -178,14 +104,17 @@ class ObjectStorageBlobConfigurationTest {
                     .codec(PayloadCodecFactory.DEFAULT)
                     .provider(ObjectStorageProvider.SWIFT)
                     .container(ContainerName.of("foo"))
-                    .tempAuth(SwiftTempAuthObjectStorage.configBuilder()
+                    .authConfiguration(new 
SwiftAuthConfiguration(SwiftTempAuthObjectStorage.AUTH_API_NAME,
+                        Optional.of(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()),
+                        Optional.empty(),
+                        Optional.empty()))
                     .build());
     }
 
@@ -208,12 +137,15 @@ class ObjectStorageBlobConfigurationTest {
                     .codec(PayloadCodecFactory.DEFAULT)
                     .provider(ObjectStorageProvider.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())
+                    .authConfiguration(new 
SwiftAuthConfiguration(SwiftKeystone2ObjectStorage.AUTH_API_NAME,
+                        Optional.empty(),
+                        Optional.of(SwiftKeystone2ObjectStorage.configBuilder()
+                            .endpoint(URI.create("http://swift/endpoint";))
+                            .credentials(Credentials.of("creds"))
+                            .userName(UserName.of("demo"))
+                            .tenantName(TenantName.of("test"))
+                            .build()),
+                        Optional.empty()))
                     .build());
     }
 
@@ -237,12 +169,15 @@ class ObjectStorageBlobConfigurationTest {
                     .codec(PayloadCodecFactory.DEFAULT)
                     .provider(ObjectStorageProvider.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())
+                    .authConfiguration(new 
SwiftAuthConfiguration(SwiftKeystone3ObjectStorage.AUTH_API_NAME,
+                        Optional.empty(),
+                        Optional.empty(),
+                        Optional.of(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());
     }
 
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/swift/ObjectStorageBlobStoreModuleTest.java
similarity index 58%
rename from 
server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/ObjectStorageBlobStoreModuleTest.java
rename to 
server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/swift/ObjectStorageBlobStoreModuleTest.java
index 19b2d87..dcb30ff 100644
--- 
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/swift/ObjectStorageBlobStoreModuleTest.java
@@ -1,26 +1,27 @@
-/****************************************************************
- * 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;
+/*
+ * 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.swift;
 
 import static org.assertj.core.api.Assertions.assertThatCode;
 
+import java.util.Optional;
 import java.util.UUID;
 import java.util.stream.Stream;
 
@@ -42,6 +43,10 @@ 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.apache.james.modules.objectstorage.ObjectStorageBlobConfiguration;
+import org.apache.james.modules.objectstorage.ObjectStorageBlobStoreModule;
+import org.apache.james.modules.objectstorage.ObjectStorageProvider;
+import org.apache.james.modules.objectstorage.PayloadCodecFactory;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.api.extension.ExtensionContext;
@@ -75,36 +80,45 @@ class ObjectStorageBlobStoreModuleTest {
                 .codec(PayloadCodecFactory.DEFAULT)
                 .provider(ObjectStorageProvider.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())
+                .authConfiguration(new 
SwiftAuthConfiguration(SwiftTempAuthObjectStorage.AUTH_API_NAME,
+                    Optional.of(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()),
+                    Optional.empty(),
+                    Optional.empty()))
                 .build();
             ObjectStorageBlobConfiguration keystone2 = 
ObjectStorageBlobConfiguration.builder()
                 .codec(PayloadCodecFactory.DEFAULT)
                 .provider(ObjectStorageProvider.SWIFT)
                 .container(generateContainerName())
-                .keystone2(SwiftKeystone2ObjectStorage.configBuilder()
-                    .endpoint(dockerSwift.keystoneV2Endpoint())
-                    .credentials(Credentials.of("demo"))
-                    .userName(UserName.of("demo"))
-                    .tenantName(TenantName.of("test"))
-                    .build())
+                .authConfiguration(new 
SwiftAuthConfiguration(SwiftKeystone2ObjectStorage.AUTH_API_NAME,
+                    Optional.empty(),
+                    Optional.of(SwiftKeystone2ObjectStorage.configBuilder()
+                        .endpoint(dockerSwift.keystoneV2Endpoint())
+                        .credentials(Credentials.of("demo"))
+                        .userName(UserName.of("demo"))
+                        .tenantName(TenantName.of("test"))
+                        .build()),
+                    Optional.empty()))
                 .build();
             ObjectStorageBlobConfiguration keystone3 = 
ObjectStorageBlobConfiguration.builder()
                 .codec(PayloadCodecFactory.DEFAULT)
                 .provider(ObjectStorageProvider.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())
+                .authConfiguration(new 
SwiftAuthConfiguration(SwiftKeystone3ObjectStorage.AUTH_API_NAME,
+                    Optional.empty(),
+                    Optional.empty(),
+                    Optional.of(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);
         }
diff --git 
a/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/swift/SwiftObjectStorageTest.java
 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/swift/SwiftObjectStorageTest.java
new file mode 100644
index 0000000..262019a
--- /dev/null
+++ 
b/server/container/guice/blob-objectstorage-guice/src/test/java/org/apache/james/modules/objectstorage/swift/SwiftObjectStorageTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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.swift;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.Optional;
+
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.james.blob.objectstorage.ContainerName;
+import org.apache.james.modules.objectstorage.ObjectStorageBlobConfiguration;
+import org.apache.james.modules.objectstorage.ObjectStorageProvider;
+import org.apache.james.modules.objectstorage.PayloadCodecFactory;
+import org.junit.jupiter.api.Test;
+
+class SwiftObjectStorageTest {
+
+    @Test
+    void builderShouldThrowWhenTempAuthAPIAndNoConfiguration() throws 
Exception {
+        ObjectStorageBlobConfiguration objectStorageBlobConfiguration = 
ObjectStorageBlobConfiguration.builder()
+            .codec(PayloadCodecFactory.DEFAULT)
+            .provider(ObjectStorageProvider.SWIFT)
+            .container(ContainerName.of("myContainer"))
+            .authConfiguration(new SwiftAuthConfiguration("tmpauth", 
Optional.empty(), Optional.empty(), Optional.empty()))
+            .build();
+        assertThatThrownBy(() -> 
SwiftObjectStorage.builder(objectStorageBlobConfiguration))
+            .isInstanceOf(IllegalArgumentException.class)
+            .hasMessage("No TempAuth configuration found for tmpauth API");
+    }
+
+    @Test
+    void builderShouldWorkWhenTempAuthAPI() throws Exception {
+        PropertiesConfiguration configuration = new PropertiesConfiguration();
+        configuration.addProperty("objectstorage.swift.endpoint", 
"http://auth.example.com/v2.0";);
+        configuration.addProperty("objectstorage.swift.credentials", 
"this_is_a_secret");
+        configuration.addProperty("objectstorage.swift.tempauth.username", 
"user");
+        configuration.addProperty("objectstorage.swift.tempauth.tenantname", 
"tenant");
+        configuration.addProperty("objectstorage.swift.authapi", "tmpauth");
+
+        ObjectStorageBlobConfiguration objectStorageBlobConfiguration = 
ObjectStorageBlobConfiguration.builder()
+            .codec(PayloadCodecFactory.DEFAULT)
+            .provider(ObjectStorageProvider.SWIFT)
+            .container(ContainerName.of("myContainer"))
+            .authConfiguration(SwiftAuthConfiguration.from(configuration))
+            .build();
+        SwiftObjectStorage.builder(objectStorageBlobConfiguration);
+    }
+
+    @Test
+    void builderShouldThrowWhenKeystone2APIAndNoConfiguration() throws 
Exception {
+        ObjectStorageBlobConfiguration objectStorageBlobConfiguration = 
ObjectStorageBlobConfiguration.builder()
+            .codec(PayloadCodecFactory.DEFAULT)
+            .provider(ObjectStorageProvider.SWIFT)
+            .container(ContainerName.of("myContainer"))
+            .authConfiguration(new SwiftAuthConfiguration("keystone2", 
Optional.empty(), Optional.empty(), Optional.empty()))
+            .build();
+        assertThatThrownBy(() -> 
SwiftObjectStorage.builder(objectStorageBlobConfiguration))
+            .isInstanceOf(IllegalArgumentException.class)
+            .hasMessage("No Keystone2 configuration found for keystone2 API");
+    }
+
+    @Test
+    void builderShouldWorkWhenKeystone2API() throws Exception {
+        PropertiesConfiguration configuration = new PropertiesConfiguration();
+        configuration.addProperty("objectstorage.swift.endpoint", 
"http://auth.example.com/v2.0";);
+        configuration.addProperty("objectstorage.swift.credentials", 
"this_is_a_secret");
+        configuration.addProperty("objectstorage.swift.keystone2.username", 
"user");
+        configuration.addProperty("objectstorage.swift.keystone2.tenantname", 
"tenant");
+        configuration.addProperty("objectstorage.swift.authapi", "keystone2");
+
+        ObjectStorageBlobConfiguration objectStorageBlobConfiguration = 
ObjectStorageBlobConfiguration.builder()
+            .codec(PayloadCodecFactory.DEFAULT)
+            .provider(ObjectStorageProvider.SWIFT)
+            .container(ContainerName.of("myContainer"))
+            .authConfiguration(SwiftAuthConfiguration.from(configuration))
+            .build();
+        SwiftObjectStorage.builder(objectStorageBlobConfiguration);
+    }
+
+    @Test
+    void builderShouldThrowWhenKeystone3APIAndNoConfiguration() throws 
Exception {
+        ObjectStorageBlobConfiguration objectStorageBlobConfiguration = 
ObjectStorageBlobConfiguration.builder()
+            .codec(PayloadCodecFactory.DEFAULT)
+            .provider(ObjectStorageProvider.SWIFT)
+            .container(ContainerName.of("myContainer"))
+            .authConfiguration(new SwiftAuthConfiguration("keystone3", 
Optional.empty(), Optional.empty(), Optional.empty()))
+            .build();
+        assertThatThrownBy(() -> 
SwiftObjectStorage.builder(objectStorageBlobConfiguration))
+            .isInstanceOf(IllegalArgumentException.class)
+            .hasMessage("No Keystone3 configuration found for keystone3 API");
+    }
+
+    @Test
+    void builderShouldWorkWhenKeystone3API() throws Exception {
+        PropertiesConfiguration configuration = new PropertiesConfiguration();
+        configuration.addProperty("objectstorage.swift.endpoint", 
"http://auth.example.com/v2.0";);
+        configuration.addProperty("objectstorage.swift.credentials", 
"this_is_a_secret");
+        configuration.addProperty("objectstorage.swift.keystone3.user.name", 
"user");
+        configuration.addProperty("objectstorage.swift.keystone3.user.domain", 
"domain");
+        configuration.addProperty("objectstorage.swift.authapi", "keystone3");
+
+        ObjectStorageBlobConfiguration objectStorageBlobConfiguration = 
ObjectStorageBlobConfiguration.builder()
+            .codec(PayloadCodecFactory.DEFAULT)
+            .provider(ObjectStorageProvider.SWIFT)
+            .container(ContainerName.of("myContainer"))
+            .authConfiguration(SwiftAuthConfiguration.from(configuration))
+            .build();
+        SwiftObjectStorage.builder(objectStorageBlobConfiguration);
+    }
+}
\ No newline at end of file
diff --git 
a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQJamesServerTest.java
 
b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQJamesServerTest.java
index 46bdb23..b5ddbed 100644
--- 
a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQJamesServerTest.java
+++ 
b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQJamesServerTest.java
@@ -31,7 +31,7 @@ import org.apache.james.modules.RabbitMQExtension;
 import org.apache.james.modules.SwiftBlobStoreExtension;
 import org.apache.james.modules.TestJMAPServerModule;
 import org.apache.james.modules.objectstorage.PayloadCodecFactory;
-import org.apache.james.modules.objectstorage.guice.DockerSwiftTestRule;
+import org.apache.james.modules.objectstorage.swift.DockerSwiftTestRule;
 import org.apache.james.modules.protocols.ImapGuiceProbe;
 import org.apache.james.modules.protocols.SmtpGuiceProbe;
 import org.apache.james.utils.DataProbeImpl;
diff --git 
a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/SwiftBlobStoreExtension.java
 
b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/SwiftBlobStoreExtension.java
index d113f1d..2aee3f8 100644
--- 
a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/SwiftBlobStoreExtension.java
+++ 
b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/SwiftBlobStoreExtension.java
@@ -22,7 +22,7 @@ package org.apache.james.modules;
 import org.apache.james.GuiceModuleTestExtension;
 import org.apache.james.modules.blobstore.BlobStoreChoosingConfiguration;
 import org.apache.james.modules.objectstorage.PayloadCodecFactory;
-import org.apache.james.modules.objectstorage.guice.DockerSwiftTestRule;
+import org.apache.james.modules.objectstorage.swift.DockerSwiftTestRule;
 import org.junit.jupiter.api.extension.ExtensionContext;
 
 import com.google.inject.Module;
diff --git 
a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/TestSwiftBlobStoreModule.java
 
b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/TestSwiftBlobStoreModule.java
index 2f4a052..4638109 100644
--- 
a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/TestSwiftBlobStoreModule.java
+++ 
b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/TestSwiftBlobStoreModule.java
@@ -20,7 +20,7 @@
 package org.apache.james.modules;
 
 import org.apache.james.modules.blobstore.BlobStoreChoosingConfiguration;
-import org.apache.james.modules.objectstorage.guice.DockerSwiftTestRule;
+import org.apache.james.modules.objectstorage.swift.DockerSwiftTestRule;
 
 import com.google.inject.AbstractModule;
 import com.google.inject.Module;
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 09200cd..7af9ec8 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
@@ -19,7 +19,7 @@
 package org.apache.james.jmap.cassandra.cucumber;
 
 import org.apache.james.modules.objectstorage.PayloadCodecFactory;
-import org.apache.james.modules.objectstorage.guice.DockerSwiftTestRule;
+import org.apache.james.modules.objectstorage.swift.DockerSwiftTestRule;
 
 public class CucumberSwiftSingleton {
 
diff --git 
a/server/protocols/jmap-integration-testing/rabbitmq-jmap-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/CucumberSwiftSingleton.java
 
b/server/protocols/jmap-integration-testing/rabbitmq-jmap-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/CucumberSwiftSingleton.java
index 18b58ab..7695ca3 100644
--- 
a/server/protocols/jmap-integration-testing/rabbitmq-jmap-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/CucumberSwiftSingleton.java
+++ 
b/server/protocols/jmap-integration-testing/rabbitmq-jmap-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/CucumberSwiftSingleton.java
@@ -19,7 +19,7 @@
 package org.apache.james.jmap.rabbitmq.cucumber;
 
 import org.apache.james.modules.objectstorage.PayloadCodecFactory;
-import org.apache.james.modules.objectstorage.guice.DockerSwiftTestRule;
+import org.apache.james.modules.objectstorage.swift.DockerSwiftTestRule;
 
 public class CucumberSwiftSingleton {
 
diff --git 
a/server/protocols/jmap-integration-testing/rabbitmq-jmap-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/RabbitMQStepdefs.java
 
b/server/protocols/jmap-integration-testing/rabbitmq-jmap-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/RabbitMQStepdefs.java
index 027f793..b97c96e 100644
--- 
a/server/protocols/jmap-integration-testing/rabbitmq-jmap-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/RabbitMQStepdefs.java
+++ 
b/server/protocols/jmap-integration-testing/rabbitmq-jmap-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/RabbitMQStepdefs.java
@@ -41,7 +41,7 @@ import org.apache.james.modules.TestElasticSearchModule;
 import org.apache.james.modules.TestJMAPServerModule;
 import org.apache.james.modules.TestRabbitMQModule;
 import org.apache.james.modules.TestSwiftBlobStoreModule;
-import org.apache.james.modules.objectstorage.guice.DockerSwiftTestRule;
+import org.apache.james.modules.objectstorage.swift.DockerSwiftTestRule;
 import org.apache.james.server.CassandraTruncateTableTask;
 import org.apache.james.server.core.configuration.Configuration;
 import org.junit.rules.TemporaryFolder;


---------------------------------------------------------------------
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