You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2019/07/09 07:55:40 UTC

[james-project] branch master updated (225103b -> 9e040a4)

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

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


    from 225103b  JAMES-2809 DeletedMessageVault contract did not include search test filtering
     new cc18f93  JAMES-2806 Make defaultBucketName become optional in the Builder
     new e52e971  JAMES-2806 new ObjectStorageBucketName POJO
     new d451760  JAMES-2806 bucket name resolving logic
     new 69183fa  JAMES-2806 bucketPrefix inside the builder
     new 9f13e43  JAMES-2806 Resolving bucket names in ObjectStorageBlobsDAO
     new 9e040a4  JAMES-2806 apply prefix configuration for the builder

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../james/blob/objectstorage/BlobPutter.java       |   5 +-
 .../blob/objectstorage/ObjectStorageBlobsDAO.java  |  20 ++--
 .../ObjectStorageBlobsDAOBuilder.java              |  48 +++++---
 .../objectstorage/ObjectStorageBucketName.java}    |  20 ++--
 .../ObjectStorageBucketNameResolver.java           | 104 +++++++++++++++++
 .../objectstorage/StreamCompatibleBlobPutter.java  |  11 +-
 .../blob/objectstorage/aws/AwsS3ObjectStorage.java |  14 +--
 .../swift/SwiftKeystone2ObjectStorage.java         |   2 +-
 .../swift/SwiftKeystone3ObjectStorage.java         |   2 +-
 .../swift/SwiftTempAuthObjectStorage.java          |   2 +-
 .../blob/objectstorage/DockerAwsS3Singleton.java   |   2 +-
 .../blob/objectstorage/DockerSwiftSingleton.java   |   2 +-
 .../ObjectStorageBlobsDAOAWSTest.java              |   2 +-
 .../objectstorage/ObjectStorageBlobsDAOTest.java   |   8 +-
 .../ObjectStorageBucketNameResolverTest.java       | 124 +++++++++++++++++++++
 .../ObjectStorageBucketNameTest.java}              |  14 +--
 .../aws/AwsS3ObjectStorageBlobsDAOBuilderTest.java |  16 +--
 ...tKeystone2ObjectStorageBlobsDAOBuilderTest.java |  18 +--
 ...tKeystone3ObjectStorageBlobsDAOBuilderTest.java |  18 +--
 ...ftTempAuthObjectStorageBlobsDAOBuilderTest.java |  18 +--
 .../ObjectStorageBlobConfiguration.java            |  16 ++-
 .../ObjectStorageDependenciesModule.java           |   5 +-
 .../objectstorage/swift/SwiftObjectStorage.java    |   8 +-
 .../ObjectStorageBlobConfigurationTest.java        |  12 +-
 24 files changed, 354 insertions(+), 137 deletions(-)
 copy server/blob/{blob-api/src/main/java/org/apache/james/blob/api/BucketName.java => blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketName.java} (79%)
 create mode 100644 server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameResolver.java
 create mode 100644 server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameResolverTest.java
 copy server/blob/{blob-api/src/test/java/org/apache/james/blob/api/BucketNameTest.java => blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameTest.java} (82%)


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


[james-project] 03/06: JAMES-2806 bucket name resolving logic

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit d45176054fecb771c932a995107696be7027cb21
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Mon Jul 8 13:34:33 2019 +0700

    JAMES-2806 bucket name resolving logic
---
 .../objectstorage/ObjectStorageBucketName.java     |   5 +
 .../ObjectStorageBucketNameResolver.java           | 104 +++++++++++++++++
 .../ObjectStorageBucketNameResolverTest.java       | 124 +++++++++++++++++++++
 3 files changed, 233 insertions(+)

diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketName.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketName.java
index 62bd0c0..2eb90c8 100644
--- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketName.java
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketName.java
@@ -22,12 +22,17 @@ package org.apache.james.blob.objectstorage;
 import java.util.Objects;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.james.blob.api.BucketName;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
 
 class ObjectStorageBucketName {
 
+    static ObjectStorageBucketName of(BucketName bucketName) {
+        return of(bucketName.asString());
+    }
+
     static ObjectStorageBucketName of(String value) {
         return new ObjectStorageBucketName(value);
     }
diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameResolver.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameResolver.java
new file mode 100644
index 0000000..136e9c7
--- /dev/null
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameResolver.java
@@ -0,0 +1,104 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.blob.objectstorage;
+
+import java.util.Optional;
+
+import org.apache.james.blob.api.BucketName;
+
+import com.google.common.base.Preconditions;
+
+class ObjectStorageBucketNameResolver {
+
+    static class Builder {
+
+        @FunctionalInterface
+        interface RequirePrefix {
+            RequireNamespace prefix(Optional<String> prefix);
+
+            default RequireNamespace noPrefix() {
+                return prefix(Optional.empty());
+            }
+
+            default RequireNamespace prefix(String prefix) {
+                return prefix(Optional.ofNullable(prefix));
+            }
+        }
+
+        @FunctionalInterface
+        interface RequireNamespace {
+            ReadyToBuild namespace(Optional<BucketName> namespace);
+
+            default ReadyToBuild namespace(BucketName namespace) {
+                return namespace(Optional.ofNullable(namespace));
+            }
+
+            default ReadyToBuild noNamespace() {
+                return namespace(Optional.empty());
+            }
+        }
+
+        static final class ReadyToBuild {
+            private final Optional<BucketName> namespace;
+            private final Optional<String> prefix;
+
+            ReadyToBuild(Optional<BucketName> namespace, Optional<String> prefix) {
+                this.namespace = namespace;
+                this.prefix = prefix;
+            }
+
+            ObjectStorageBucketNameResolver build() {
+                return new ObjectStorageBucketNameResolver(namespace, prefix);
+            }
+        }
+    }
+
+    static Builder.RequirePrefix builder() {
+        return prefix -> namespace -> new Builder.ReadyToBuild(namespace, prefix);
+    }
+
+    private final Optional<BucketName> namespace;
+    private final Optional<String> prefix;
+
+    private ObjectStorageBucketNameResolver(Optional<BucketName> namespace, Optional<String> prefix) {
+        Preconditions.checkNotNull(namespace);
+        Preconditions.checkNotNull(prefix);
+
+        this.namespace = namespace;
+        this.prefix = prefix;
+    }
+
+    ObjectStorageBucketName resolve(BucketName bucketName) {
+        Preconditions.checkNotNull(bucketName);
+
+        if (isNameSpace(bucketName)) {
+            return ObjectStorageBucketName.of(bucketName);
+        }
+        return prefix
+            .map(bucketPrefix -> ObjectStorageBucketName.of(bucketPrefix + bucketName.asString()))
+            .orElse(ObjectStorageBucketName.of(bucketName));
+    }
+
+    private boolean isNameSpace(BucketName bucketName) {
+        return namespace
+            .map(existingNamespace -> existingNamespace.equals(bucketName))
+            .orElse(false);
+    }
+}
diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameResolverTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameResolverTest.java
new file mode 100644
index 0000000..43119d1
--- /dev/null
+++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameResolverTest.java
@@ -0,0 +1,124 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.blob.objectstorage;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.apache.james.blob.api.BucketName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+class ObjectStorageBucketNameResolverTest {
+
+    @Nested
+    class EmptyPrefix {
+
+        @Test
+        void resolveShouldReturnPassedValue() {
+            ObjectStorageBucketNameResolver resolver = ObjectStorageBucketNameResolver.builder()
+                .noPrefix()
+                .namespace(BucketName.of("namespace"))
+                .build();
+
+            assertThat(resolver.resolve(BucketName.of("bucketName")))
+                .isEqualTo(ObjectStorageBucketName.of("bucketName"));
+        }
+
+        @Test
+        void resolveShouldReturnValueWhenNamespace() {
+            ObjectStorageBucketNameResolver resolver = ObjectStorageBucketNameResolver.builder()
+                .noPrefix()
+                .namespace(BucketName.of("namespace"))
+                .build();
+
+            assertThat(resolver.resolve(BucketName.of("namespace")))
+                .isEqualTo(ObjectStorageBucketName.of("namespace"));
+        }
+    }
+
+    @Nested
+    class EmptyNamespace {
+
+        @Test
+        void resolveShouldReturnPassedValueWithPrefix() {
+            ObjectStorageBucketNameResolver resolver = ObjectStorageBucketNameResolver.builder()
+                .prefix("prefix-")
+                .noNamespace()
+                .build();
+
+            assertThat(resolver.resolve(BucketName.of("bucketName")))
+                .isEqualTo(ObjectStorageBucketName.of("prefix-bucketName"));
+        }
+    }
+
+    @Nested
+    class BothAreEmpty {
+
+        @Test
+        void resolveShouldReturnPassedValue() {
+            ObjectStorageBucketNameResolver resolver = ObjectStorageBucketNameResolver.builder()
+                .noPrefix()
+                .noNamespace()
+                .build();
+
+            assertThat(resolver.resolve(BucketName.of("bucketName")))
+                .isEqualTo(ObjectStorageBucketName.of("bucketName"));
+        }
+    }
+
+    @Nested
+    class BothArePresent {
+
+        @Test
+        void resolveShouldReturnPassedValueWithPrefix() {
+            ObjectStorageBucketNameResolver resolver = ObjectStorageBucketNameResolver.builder()
+                .prefix("prefix-")
+                .namespace(BucketName.of("namespace"))
+                .build();
+
+            assertThat(resolver.resolve(BucketName.of("bucketName")))
+                .isEqualTo(ObjectStorageBucketName.of("prefix-bucketName"));
+        }
+
+        @Test
+        void resolveShouldReturnNamespaceWhenPassingNamespace() {
+            ObjectStorageBucketNameResolver resolver = ObjectStorageBucketNameResolver.builder()
+                .prefix("prefix-")
+                .namespace(BucketName.of("namespace"))
+                .build();
+
+            assertThat(resolver.resolve(BucketName.of("namespace")))
+                .isEqualTo(ObjectStorageBucketName.of("namespace"));
+        }
+    }
+
+
+    @Test
+    void resolveShouldThrowWhenNullBucketName() {
+        ObjectStorageBucketNameResolver resolver = ObjectStorageBucketNameResolver.builder()
+            .noPrefix()
+            .noNamespace()
+            .build();
+
+        assertThatThrownBy(() -> resolver.resolve(null))
+            .isInstanceOf(NullPointerException.class);
+    }
+}
\ No newline at end of file


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


[james-project] 01/06: JAMES-2806 Make defaultBucketName become optional in the Builder

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit cc18f9366acae1280f9cbf614555679367cdfa48
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Mon Jul 8 10:09:17 2019 +0700

    JAMES-2806 Make defaultBucketName become optional in the Builder
    
    And rename it to namespace to be more clear
---
 .../blob/objectstorage/ObjectStorageBlobsDAO.java  |  8 +++----
 .../ObjectStorageBlobsDAOBuilder.java              | 28 ++++++++++++----------
 .../blob/objectstorage/aws/AwsS3ObjectStorage.java |  2 +-
 .../swift/SwiftKeystone2ObjectStorage.java         |  2 +-
 .../swift/SwiftKeystone3ObjectStorage.java         |  2 +-
 .../swift/SwiftTempAuthObjectStorage.java          |  2 +-
 .../blob/objectstorage/DockerAwsS3Singleton.java   |  2 +-
 .../blob/objectstorage/DockerSwiftSingleton.java   |  2 +-
 .../ObjectStorageBlobsDAOAWSTest.java              |  2 +-
 .../objectstorage/ObjectStorageBlobsDAOTest.java   |  8 +++----
 .../aws/AwsS3ObjectStorageBlobsDAOBuilderTest.java | 16 +++----------
 ...tKeystone2ObjectStorageBlobsDAOBuilderTest.java | 18 ++++----------
 ...tKeystone3ObjectStorageBlobsDAOBuilderTest.java | 18 ++++----------
 ...ftTempAuthObjectStorageBlobsDAOBuilderTest.java | 18 ++++----------
 .../ObjectStorageBlobConfiguration.java            |  7 +++---
 .../ObjectStorageDependenciesModule.java           |  4 ++--
 .../objectstorage/swift/SwiftObjectStorage.java    |  8 +++----
 .../ObjectStorageBlobConfigurationTest.java        |  6 ++---
 18 files changed, 58 insertions(+), 95 deletions(-)

diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java
index 3a0bf83..a316ab3 100644
--- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java
@@ -70,19 +70,19 @@ public class ObjectStorageBlobsDAO implements BlobStore {
         this.payloadCodec = payloadCodec;
     }
 
-    public static ObjectStorageBlobsDAOBuilder.RequireDefaultBucketName builder(SwiftTempAuthObjectStorage.Configuration testConfig) {
+    public static ObjectStorageBlobsDAOBuilder.RequireBlobIdFactory builder(SwiftTempAuthObjectStorage.Configuration testConfig) {
         return SwiftTempAuthObjectStorage.daoBuilder(testConfig);
     }
 
-    public static ObjectStorageBlobsDAOBuilder.RequireDefaultBucketName builder(SwiftKeystone2ObjectStorage.Configuration testConfig) {
+    public static ObjectStorageBlobsDAOBuilder.RequireBlobIdFactory builder(SwiftKeystone2ObjectStorage.Configuration testConfig) {
         return SwiftKeystone2ObjectStorage.daoBuilder(testConfig);
     }
 
-    public static ObjectStorageBlobsDAOBuilder.RequireDefaultBucketName builder(SwiftKeystone3ObjectStorage.Configuration testConfig) {
+    public static ObjectStorageBlobsDAOBuilder.RequireBlobIdFactory builder(SwiftKeystone3ObjectStorage.Configuration testConfig) {
         return SwiftKeystone3ObjectStorage.daoBuilder(testConfig);
     }
 
-    public static ObjectStorageBlobsDAOBuilder.RequireDefaultBucketName builder(AwsS3AuthConfiguration testConfig) {
+    public static ObjectStorageBlobsDAOBuilder.RequireBlobIdFactory builder(AwsS3AuthConfiguration testConfig) {
         return AwsS3ObjectStorage.daoBuilder(testConfig);
     }
 
diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java
index 9122c29..b7cb344 100644
--- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java
@@ -31,13 +31,8 @@ import com.google.common.base.Preconditions;
 
 public class ObjectStorageBlobsDAOBuilder {
 
-    public static RequireDefaultBucketName forBlobStore(Supplier<BlobStore> supplier) {
-        return bucketName -> blobIdFactory -> new ReadyToBuild(supplier, blobIdFactory, bucketName);
-    }
-
-    @FunctionalInterface
-    public interface RequireDefaultBucketName {
-        RequireBlobIdFactory defaultBucketName(BucketName bucketName);
+    public static RequireBlobIdFactory forBlobStore(Supplier<BlobStore> supplier) {
+        return blobIdFactory -> new ReadyToBuild(supplier, blobIdFactory);
     }
 
     @FunctionalInterface
@@ -48,17 +43,17 @@ public class ObjectStorageBlobsDAOBuilder {
     public static class ReadyToBuild {
 
         private final Supplier<BlobStore> supplier;
-        private final BucketName defaultBucketName;
         private final BlobId.Factory blobIdFactory;
         private Optional<PayloadCodec> payloadCodec;
         private Optional<BlobPutter> blobPutter;
+        private Optional<BucketName> namespace;
 
-        public ReadyToBuild(Supplier<BlobStore> supplier, BlobId.Factory blobIdFactory, BucketName defaultBucketName) {
+        public ReadyToBuild(Supplier<BlobStore> supplier, BlobId.Factory blobIdFactory) {
             this.blobIdFactory = blobIdFactory;
-            this.defaultBucketName = defaultBucketName;
             this.payloadCodec = Optional.empty();
             this.supplier = supplier;
             this.blobPutter = Optional.empty();
+            this.namespace = Optional.empty();
         }
 
         public ReadyToBuild payloadCodec(PayloadCodec payloadCodec) {
@@ -76,13 +71,22 @@ public class ObjectStorageBlobsDAOBuilder {
             return this;
         }
 
+        public ReadyToBuild namespace(Optional<BucketName> namespace) {
+            this.namespace = namespace;
+            return this;
+        }
+
+        public ReadyToBuild namespace(BucketName namespace) {
+            this.namespace = Optional.ofNullable(namespace);
+            return this;
+        }
+
         public ObjectStorageBlobsDAO build() {
-            Preconditions.checkState(defaultBucketName != null);
             Preconditions.checkState(blobIdFactory != null);
 
             BlobStore blobStore = supplier.get();
 
-            return new ObjectStorageBlobsDAO(defaultBucketName,
+            return new ObjectStorageBlobsDAO(namespace.orElse(BucketName.DEFAULT),
                 blobIdFactory,
                 blobStore,
                 blobPutter.orElseGet(() -> defaultPutBlob(blobStore)),
diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorage.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorage.java
index 4884dd5..517bb19 100644
--- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorage.java
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorage.java
@@ -97,7 +97,7 @@ public class AwsS3ObjectStorage {
         executorService.shutdownNow();
     }
 
-    public static ObjectStorageBlobsDAOBuilder.RequireDefaultBucketName daoBuilder(AwsS3AuthConfiguration configuration) {
+    public static ObjectStorageBlobsDAOBuilder.RequireBlobIdFactory daoBuilder(AwsS3AuthConfiguration configuration) {
         return ObjectStorageBlobsDAOBuilder.forBlobStore(new BlobStoreBuilder(configuration));
     }
 
diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone2ObjectStorage.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone2ObjectStorage.java
index 1b46c3a..e988dcb 100644
--- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone2ObjectStorage.java
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone2ObjectStorage.java
@@ -43,7 +43,7 @@ public class SwiftKeystone2ObjectStorage {
     private static final Iterable<Module> JCLOUDS_MODULES =
         ImmutableSet.of(new SLF4JLoggingModule());
 
-    public static ObjectStorageBlobsDAOBuilder.RequireDefaultBucketName daoBuilder(Configuration testConfig) {
+    public static ObjectStorageBlobsDAOBuilder.RequireBlobIdFactory daoBuilder(Configuration testConfig) {
         return ObjectStorageBlobsDAOBuilder.forBlobStore(new BlobStoreBuilder(testConfig));
     }
 
diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorage.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorage.java
index 5ca8cf3..b8831ff 100644
--- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorage.java
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorage.java
@@ -45,7 +45,7 @@ public class SwiftKeystone3ObjectStorage {
     private static final Iterable<Module> JCLOUDS_MODULES =
         ImmutableSet.of(new SLF4JLoggingModule());
 
-    public static ObjectStorageBlobsDAOBuilder.RequireDefaultBucketName daoBuilder(Configuration testConfig) {
+    public static ObjectStorageBlobsDAOBuilder.RequireBlobIdFactory daoBuilder(Configuration testConfig) {
         return ObjectStorageBlobsDAOBuilder.forBlobStore(new BlobStoreBuilder(testConfig));
     }
 
diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftTempAuthObjectStorage.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftTempAuthObjectStorage.java
index 9481337..9a2709c 100644
--- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftTempAuthObjectStorage.java
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftTempAuthObjectStorage.java
@@ -44,7 +44,7 @@ public class SwiftTempAuthObjectStorage {
     private static final Iterable<Module> JCLOUDS_MODULES =
         ImmutableSet.of(new SLF4JLoggingModule());
 
-    public static ObjectStorageBlobsDAOBuilder.RequireDefaultBucketName daoBuilder(Configuration testConfig) {
+    public static ObjectStorageBlobsDAOBuilder.RequireBlobIdFactory daoBuilder(Configuration testConfig) {
         return ObjectStorageBlobsDAOBuilder.forBlobStore(new BlobStoreBuilder(testConfig));
     }
 
diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerAwsS3Singleton.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerAwsS3Singleton.java
index c5aeb79..c598b73 100644
--- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerAwsS3Singleton.java
+++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerAwsS3Singleton.java
@@ -29,6 +29,6 @@ public class DockerAwsS3Singleton {
         singleton.start();
     }
 
-    // Cleanup will be performed by test defaultBucketName resource reaper
+    // Cleanup will be performed by test namespace resource reaper
 }
 
diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerSwiftSingleton.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerSwiftSingleton.java
index 2c34972..0f04ee3 100644
--- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerSwiftSingleton.java
+++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerSwiftSingleton.java
@@ -27,5 +27,5 @@ public class DockerSwiftSingleton {
         singleton.start();
     }
 
-    // Cleanup will be performed by test defaultBucketName resource reaper
+    // Cleanup will be performed by test namespace resource reaper
 }
diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOAWSTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOAWSTest.java
index 209be69..120dce8 100644
--- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOAWSTest.java
+++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOAWSTest.java
@@ -58,8 +58,8 @@ public class ObjectStorageBlobsDAOAWSTest implements MetricableBlobStoreContract
 
         ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO
             .builder(configuration)
-            .defaultBucketName(defaultBucketName)
             .blobIdFactory(BLOB_ID_FACTORY)
+            .namespace(defaultBucketName)
             .blobPutter(awsS3ObjectStorage.putBlob(configuration));
 
         blobStore = builder.getSupplier().get();
diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOTest.java
index 18c6bf2..c4682e3 100644
--- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOTest.java
+++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOTest.java
@@ -86,8 +86,8 @@ public class ObjectStorageBlobsDAOTest implements MetricableBlobStoreContract, B
         BlobId.Factory blobIdFactory = blobIdFactory();
         ObjectStorageBlobsDAOBuilder.ReadyToBuild daoBuilder = ObjectStorageBlobsDAO
             .builder(testConfig)
-            .defaultBucketName(defaultBucketName)
-            .blobIdFactory(blobIdFactory);
+            .blobIdFactory(blobIdFactory)
+            .namespace(defaultBucketName);
         blobStore = daoBuilder.getSupplier().get();
         objectStorageBlobsDAO = daoBuilder.build();
         testee = new MetricableBlobStore(metricsTestExtension.getMetricFactory(), objectStorageBlobsDAO);
@@ -114,9 +114,9 @@ public class ObjectStorageBlobsDAOTest implements MetricableBlobStoreContract, B
     void supportsEncryptionWithCustomPayloadCodec() throws IOException {
         ObjectStorageBlobsDAO encryptedDao = ObjectStorageBlobsDAO
             .builder(testConfig)
-            .defaultBucketName(defaultBucketName)
             .blobIdFactory(blobIdFactory())
             .payloadCodec(new AESPayloadCodec(CRYPTO_CONFIG))
+            .namespace(defaultBucketName)
             .build();
         String content = "James is the best!";
         BlobId blobId = encryptedDao.save(encryptedDao.getDefaultBucketName(), content).block();
@@ -130,9 +130,9 @@ public class ObjectStorageBlobsDAOTest implements MetricableBlobStoreContract, B
     void encryptionWithCustomPayloadCodeCannotBeReadFromUnencryptedDAO() throws Exception {
         ObjectStorageBlobsDAO encryptedDao = ObjectStorageBlobsDAO
             .builder(testConfig)
-            .defaultBucketName(defaultBucketName)
             .blobIdFactory(blobIdFactory())
             .payloadCodec(new AESPayloadCodec(CRYPTO_CONFIG))
+            .namespace(defaultBucketName)
             .build();
         String content = "James is the best!";
         BlobId blobId = encryptedDao.save(encryptedDao.getDefaultBucketName(), content).block();
diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorageBlobsDAOBuilderTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorageBlobsDAOBuilderTest.java
index a81e930..5c16ebb 100644
--- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorageBlobsDAOBuilderTest.java
+++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorageBlobsDAOBuilderTest.java
@@ -60,21 +60,11 @@ class AwsS3ObjectStorageBlobsDAOBuilderTest implements ObjectStorageBlobsDAOCont
     }
 
     @Test
-    void bucketNameIsMandatoryToBuildBlobsDAO() {
-        ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO
-            .builder(configuration)
-            .defaultBucketName(null)
-            .blobIdFactory(new HashBlobId.Factory());
-
-        assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class);
-    }
-
-    @Test
     void blobIdFactoryIsMandatoryToBuildBlobsDAO() {
         ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO
             .builder(configuration)
-            .defaultBucketName(defaultBucketName)
-            .blobIdFactory(null);
+            .blobIdFactory(null)
+            .namespace(defaultBucketName);
 
         assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class);
     }
@@ -83,8 +73,8 @@ class AwsS3ObjectStorageBlobsDAOBuilderTest implements ObjectStorageBlobsDAOCont
     void builtBlobsDAOCanStoreAndRetrieve() {
         ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO
             .builder(configuration)
-            .defaultBucketName(defaultBucketName)
             .blobIdFactory(new HashBlobId.Factory())
+            .namespace(defaultBucketName)
             .blobPutter(awsS3ObjectStorage.putBlob(configuration));
 
         assertBlobsDAOCanStoreAndRetrieve(builder);
diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone2ObjectStorageBlobsDAOBuilderTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone2ObjectStorageBlobsDAOBuilderTest.java
index 649bb91..39415dd 100644
--- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone2ObjectStorageBlobsDAOBuilderTest.java
+++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone2ObjectStorageBlobsDAOBuilderTest.java
@@ -62,21 +62,11 @@ class SwiftKeystone2ObjectStorageBlobsDAOBuilderTest implements ObjectStorageBlo
     }
 
     @Test
-    void bucketNameIsMandatoryToBuildBlobsDAO() {
-        ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO
-            .builder(testConfig)
-            .defaultBucketName(null)
-            .blobIdFactory(new HashBlobId.Factory());
-
-        assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class);
-    }
-
-    @Test
     void blobIdFactoryIsMandatoryToBuildBlobsDAO() {
         ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO
             .builder(testConfig)
-            .defaultBucketName(defaultBucketName)
-            .blobIdFactory(null);
+            .blobIdFactory(null)
+            .namespace(defaultBucketName);
 
         assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class);
     }
@@ -85,8 +75,8 @@ class SwiftKeystone2ObjectStorageBlobsDAOBuilderTest implements ObjectStorageBlo
     void builtBlobsDAOCanStoreAndRetrieve() {
         ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO
             .builder(testConfig)
-            .defaultBucketName(defaultBucketName)
-            .blobIdFactory(new HashBlobId.Factory());
+            .blobIdFactory(new HashBlobId.Factory())
+            .namespace(defaultBucketName);
 
         assertBlobsDAOCanStoreAndRetrieve(builder);
     }
diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorageBlobsDAOBuilderTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorageBlobsDAOBuilderTest.java
index dd5be4d..893cad1 100644
--- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorageBlobsDAOBuilderTest.java
+++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorageBlobsDAOBuilderTest.java
@@ -95,21 +95,11 @@ class SwiftKeystone3ObjectStorageBlobsDAOBuilderTest implements ObjectStorageBlo
     }
 
     @Test
-    void bucketNameIsMandatoryToBuildBlobsDAO() {
-        ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO
-            .builder(testConfig)
-            .defaultBucketName(null)
-            .blobIdFactory(new HashBlobId.Factory());
-
-        assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class);
-    }
-
-    @Test
     void blobIdFactoryIsMandatoryToBuildBlobsDAO() {
         ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO
             .builder(testConfig)
-            .defaultBucketName(defaultBucketName)
-            .blobIdFactory(null);
+            .blobIdFactory(null)
+            .namespace(defaultBucketName);
 
         assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class);
     }
@@ -121,8 +111,8 @@ class SwiftKeystone3ObjectStorageBlobsDAOBuilderTest implements ObjectStorageBlo
             configBuilders.get(key).endpoint(dockerSwift.keystoneV3Endpoint()).build();
         ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO
             .builder(config)
-            .defaultBucketName(defaultBucketName)
-            .blobIdFactory(new HashBlobId.Factory());
+            .blobIdFactory(new HashBlobId.Factory())
+            .namespace(defaultBucketName);
 
         assertBlobsDAOCanStoreAndRetrieve(builder);
     }
diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftTempAuthObjectStorageBlobsDAOBuilderTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftTempAuthObjectStorageBlobsDAOBuilderTest.java
index ba729a3..ec17bcc 100644
--- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftTempAuthObjectStorageBlobsDAOBuilderTest.java
+++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftTempAuthObjectStorageBlobsDAOBuilderTest.java
@@ -64,21 +64,11 @@ class SwiftTempAuthObjectStorageBlobsDAOBuilderTest implements ObjectStorageBlob
     }
 
     @Test
-    void bucketNameIsMandatoryToBuildBlobsDAO() {
-        ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO
-            .builder(testConfig)
-            .defaultBucketName(null)
-            .blobIdFactory(new HashBlobId.Factory());
-
-        assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class);
-    }
-
-    @Test
     void blobIdFactoryIsMandatoryToBuildBlobsDAO() {
         ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO
             .builder(testConfig)
-            .defaultBucketName(defaultBucketName)
-            .blobIdFactory(null);
+            .blobIdFactory(null)
+            .namespace(defaultBucketName);
 
         assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class);
     }
@@ -87,8 +77,8 @@ class SwiftTempAuthObjectStorageBlobsDAOBuilderTest implements ObjectStorageBlob
     void builtBlobsDAOCanStoreAndRetrieve() {
         ObjectStorageBlobsDAOBuilder.ReadyToBuild builder = ObjectStorageBlobsDAO
             .builder(testConfig)
-            .defaultBucketName(defaultBucketName)
-            .blobIdFactory(new HashBlobId.Factory());
+            .blobIdFactory(new HashBlobId.Factory())
+            .namespace(defaultBucketName);
 
         assertBlobsDAOCanStoreAndRetrieve(builder);
     }
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 cb1d694..58e082b 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
@@ -173,7 +173,6 @@ public class ObjectStorageBlobConfiguration {
                         .orElseThrow(() -> new IllegalStateException("AES code requires an non-empty password parameter"));
                 }
 
-                BucketName defaultBucketName = this.defaultBucketName.orElse(BucketName.DEFAULT);
                 String bucketPrefix = this.bucketPrefix.orElse(DEFAULT_BUCKET_PREFIX);
 
                 return new ObjectStorageBlobConfiguration(payloadCodecFactory, bucketPrefix, provider, defaultBucketName, specificAuthConfiguration, aesSalt, aesPassword);
@@ -184,17 +183,17 @@ public class ObjectStorageBlobConfiguration {
     }
 
     private final PayloadCodecFactory payloadCodec;
-    private final BucketName namespace;
     private final String bucketPrefix;
     private final ObjectStorageProvider provider;
     private final SpecificAuthConfiguration specificAuthConfiguration;
+    private Optional<BucketName> namespace;
     private Optional<String> aesSalt;
     private Optional<char[]> aesPassword;
 
     @VisibleForTesting
     ObjectStorageBlobConfiguration(PayloadCodecFactory payloadCodec, String bucketPrefix,
                                    ObjectStorageProvider provider,
-                                   BucketName namespace,
+                                   Optional<BucketName> namespace,
                                    SpecificAuthConfiguration specificAuthConfiguration,
                                    Optional<String> aesSalt,
                                    Optional<char[]> aesPassword) {
@@ -207,7 +206,7 @@ public class ObjectStorageBlobConfiguration {
         this.aesPassword = aesPassword;
     }
 
-    public BucketName getNamespace() {
+    public Optional<BucketName> getNamespace() {
         return namespace;
     }
 
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 7d92bcd..23def65 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
@@ -66,15 +66,15 @@ public class ObjectStorageDependenciesModule extends AbstractModule {
     @Singleton
     private ObjectStorageBlobsDAO buildObjectStore(ObjectStorageBlobConfiguration configuration, BlobId.Factory blobIdFactory, Provider<AwsS3ObjectStorage> awsS3ObjectStorageProvider) throws InterruptedException, ExecutionException, TimeoutException {
         ObjectStorageBlobsDAO dao = selectDaoBuilder(configuration)
-            .defaultBucketName(configuration.getNamespace())
             .blobIdFactory(blobIdFactory)
             .payloadCodec(configuration.getPayloadCodec())
             .blobPutter(putBlob(blobIdFactory, configuration, awsS3ObjectStorageProvider))
+            .namespace(configuration.getNamespace())
             .build();
         return dao;
     }
 
-    private ObjectStorageBlobsDAOBuilder.RequireDefaultBucketName selectDaoBuilder(ObjectStorageBlobConfiguration configuration) {
+    private ObjectStorageBlobsDAOBuilder.RequireBlobIdFactory selectDaoBuilder(ObjectStorageBlobConfiguration configuration) {
         switch (configuration.getProvider()) {
             case SWIFT:
                 return SwiftObjectStorage.builder(configuration);
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
index 795d66f..409307d 100644
--- 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
@@ -29,7 +29,7 @@ import org.apache.james.modules.objectstorage.ObjectStorageProvider;
 
 public class SwiftObjectStorage {
 
-    public static ObjectStorageBlobsDAOBuilder.RequireDefaultBucketName builder(ObjectStorageBlobConfiguration configuration) {
+    public static ObjectStorageBlobsDAOBuilder.RequireBlobIdFactory builder(ObjectStorageBlobConfiguration configuration) {
         if (configuration.getProvider() != ObjectStorageProvider.SWIFT) {
             throw new IllegalArgumentException("unknown provider " + configuration.getProvider());
         }
@@ -52,15 +52,15 @@ public class SwiftObjectStorage {
         }
     }
 
-    public static ObjectStorageBlobsDAOBuilder.RequireDefaultBucketName builder(SwiftTempAuthObjectStorage.Configuration testConfig) {
+    public static ObjectStorageBlobsDAOBuilder.RequireBlobIdFactory builder(SwiftTempAuthObjectStorage.Configuration testConfig) {
         return SwiftTempAuthObjectStorage.daoBuilder(testConfig);
     }
 
-    public static ObjectStorageBlobsDAOBuilder.RequireDefaultBucketName builder(SwiftKeystone2ObjectStorage.Configuration testConfig) {
+    public static ObjectStorageBlobsDAOBuilder.RequireBlobIdFactory builder(SwiftKeystone2ObjectStorage.Configuration testConfig) {
         return SwiftKeystone2ObjectStorage.daoBuilder(testConfig);
     }
 
-    public static ObjectStorageBlobsDAOBuilder.RequireDefaultBucketName builder(SwiftKeystone3ObjectStorage.Configuration testConfig) {
+    public static ObjectStorageBlobsDAOBuilder.RequireBlobIdFactory builder(SwiftKeystone3ObjectStorage.Configuration testConfig) {
         return SwiftKeystone3ObjectStorage.daoBuilder(testConfig);
     }
 }
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 6bc03b2..a6c1458 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
@@ -167,18 +167,18 @@ class ObjectStorageBlobConfigurationTest {
                 .build());
 
          assertThat(ObjectStorageBlobConfiguration.from(configuration).getNamespace())
-            .isEqualTo(BucketName.of(bucketNameAsString));
+            .contains(BucketName.of(bucketNameAsString));
     }
 
      @Test
-    void fromShouldUseTheDefaultValueWhenDontSpecifyNameSpace() throws Exception {
+    void fromShouldNotContainsNamespaceWhenDontSpecify() throws Exception {
         MapConfiguration configuration = new MapConfiguration(
             ImmutableMap.<String, Object>builder()
                 .putAll(VALID_CONFIGURATION)
                 .build());
 
          assertThat(ObjectStorageBlobConfiguration.from(configuration).getNamespace())
-            .isEqualTo(BucketName.DEFAULT);
+            .isEmpty();
     }
 
     @Test


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


[james-project] 06/06: JAMES-2806 apply prefix configuration for the builder

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 9e040a40872f7a2bd7d4b7b4575a75affb399553
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Mon Jul 8 14:25:32 2019 +0700

    JAMES-2806 apply prefix configuration for the builder
---
 .../james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java   | 5 +++++
 .../modules/objectstorage/ObjectStorageBlobConfiguration.java    | 9 ++++-----
 .../modules/objectstorage/ObjectStorageDependenciesModule.java   | 1 +
 .../objectstorage/ObjectStorageBlobConfigurationTest.java        | 6 +++---
 4 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java
index d085565..21a1bb8 100644
--- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java
@@ -83,6 +83,11 @@ public class ObjectStorageBlobsDAOBuilder {
             return this;
         }
 
+        public ReadyToBuild bucketPrefix(Optional<String> bucketPrefix) {
+            this.bucketPrefix = bucketPrefix;
+            return this;
+        }
+
         public ReadyToBuild bucketPrefix(String prefix) {
             this.bucketPrefix = Optional.ofNullable(prefix);
             return this;
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 58e082b..e6ea529 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
@@ -173,8 +173,6 @@ public class ObjectStorageBlobConfiguration {
                         .orElseThrow(() -> new IllegalStateException("AES code requires an non-empty password parameter"));
                 }
 
-                String bucketPrefix = this.bucketPrefix.orElse(DEFAULT_BUCKET_PREFIX);
-
                 return new ObjectStorageBlobConfiguration(payloadCodecFactory, bucketPrefix, provider, defaultBucketName, specificAuthConfiguration, aesSalt, aesPassword);
             }
 
@@ -183,15 +181,16 @@ public class ObjectStorageBlobConfiguration {
     }
 
     private final PayloadCodecFactory payloadCodec;
-    private final String bucketPrefix;
     private final ObjectStorageProvider provider;
     private final SpecificAuthConfiguration specificAuthConfiguration;
     private Optional<BucketName> namespace;
     private Optional<String> aesSalt;
     private Optional<char[]> aesPassword;
+    private Optional<String> bucketPrefix;
 
     @VisibleForTesting
-    ObjectStorageBlobConfiguration(PayloadCodecFactory payloadCodec, String bucketPrefix,
+    ObjectStorageBlobConfiguration(PayloadCodecFactory payloadCodec,
+                                   Optional<String> bucketPrefix,
                                    ObjectStorageProvider provider,
                                    Optional<BucketName> namespace,
                                    SpecificAuthConfiguration specificAuthConfiguration,
@@ -234,7 +233,7 @@ public class ObjectStorageBlobConfiguration {
         return aesPassword;
     }
 
-    public String getBucketPrefix() {
+    public Optional<String> getBucketPrefix() {
         return bucketPrefix;
     }
 
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 23def65..e7b0c5c 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
@@ -70,6 +70,7 @@ public class ObjectStorageDependenciesModule extends AbstractModule {
             .payloadCodec(configuration.getPayloadCodec())
             .blobPutter(putBlob(blobIdFactory, configuration, awsS3ObjectStorageProvider))
             .namespace(configuration.getNamespace())
+            .bucketPrefix(configuration.getBucketPrefix())
             .build();
         return dao;
     }
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 a6c1458..74228b7 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
@@ -191,17 +191,17 @@ class ObjectStorageBlobConfigurationTest {
                 .build());
 
          assertThat(ObjectStorageBlobConfiguration.from(configuration).getBucketPrefix())
-            .isEqualTo(bucketPrefix);
+            .contains(bucketPrefix);
     }
 
      @Test
-    void fromShouldUseTheDefaultValueWhenDontSpecifyBucketPrefix() throws Exception {
+    void fromShouldReturnEmptyWhenDontSpecifyBucketPrefix() throws Exception {
         MapConfiguration configuration = new MapConfiguration(
             ImmutableMap.<String, Object>builder()
                 .putAll(VALID_CONFIGURATION)
                 .build());
 
          assertThat(ObjectStorageBlobConfiguration.from(configuration).getBucketPrefix())
-            .isEqualTo(ObjectStorageBlobConfiguration.DEFAULT_BUCKET_PREFIX);
+            .isEmpty();
     }
 }
\ No newline at end of file


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


[james-project] 02/06: JAMES-2806 new ObjectStorageBucketName POJO

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit e52e97198d5f3b9d96db5e3d39074c6171a03c30
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Mon Jul 8 11:51:27 2019 +0700

    JAMES-2806 new ObjectStorageBucketName POJO
    
    Because the BucketName passed into ObjectStorageBlobsDAO will be
    re calculated to take care about bucket prefix which is only the matter
    with ObjectStorage concern.
    
    To avoid confusing of return type when resolving BucketName,
    we create another type.
---
 .../objectstorage/ObjectStorageBucketName.java     | 68 ++++++++++++++++++++++
 .../objectstorage/ObjectStorageBucketNameTest.java | 55 +++++++++++++++++
 2 files changed, 123 insertions(+)

diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketName.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketName.java
new file mode 100644
index 0000000..62bd0c0
--- /dev/null
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketName.java
@@ -0,0 +1,68 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.blob.objectstorage;
+
+import java.util.Objects;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+
+class ObjectStorageBucketName {
+
+    static ObjectStorageBucketName of(String value) {
+        return new ObjectStorageBucketName(value);
+    }
+
+    private final String value;
+
+    private ObjectStorageBucketName(String value) {
+        Preconditions.checkNotNull(value);
+        Preconditions.checkArgument(StringUtils.isNotBlank(value), "`value` cannot be blank");
+
+        this.value = value;
+    }
+
+    String asString() {
+        return value;
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof ObjectStorageBucketName) {
+            ObjectStorageBucketName that = (ObjectStorageBucketName) o;
+            return Objects.equals(this.value, that.value);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(value);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("value", value)
+            .toString();
+    }
+}
diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameTest.java
new file mode 100644
index 0000000..58d48d6
--- /dev/null
+++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameTest.java
@@ -0,0 +1,55 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.blob.objectstorage;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.junit.jupiter.api.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+class ObjectStorageBucketNameTest {
+
+    @Test
+    void shouldMatchBeanContract() {
+        EqualsVerifier.forClass(ObjectStorageBucketName.class)
+            .verify();
+    }
+
+    @Test
+    void newBucketNameShouldThrowWhenNullValue() {
+        String nullName = null;
+        assertThatThrownBy(() -> ObjectStorageBucketName.of(nullName))
+            .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    void newBucketNameShouldThrowWhenEmptyValue() {
+        assertThatThrownBy(() -> ObjectStorageBucketName.of(""))
+            .isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    void newBucketNameShouldThrowWhenBlankValue() {
+        assertThatThrownBy(() -> ObjectStorageBucketName.of("   "))
+            .isInstanceOf(IllegalArgumentException.class);
+    }
+
+}
\ No newline at end of file


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


[james-project] 04/06: JAMES-2806 bucketPrefix inside the builder

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 69183fa080e7a3f1db7ef62ff87bcc5f89a4479c
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Mon Jul 8 13:59:39 2019 +0700

    JAMES-2806 bucketPrefix inside the builder
---
 .../james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java |  7 +++++++
 .../objectstorage/ObjectStorageBucketNameResolverTest.java     | 10 +++++-----
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java
index b7cb344..d6c289c 100644
--- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java
@@ -47,6 +47,7 @@ public class ObjectStorageBlobsDAOBuilder {
         private Optional<PayloadCodec> payloadCodec;
         private Optional<BlobPutter> blobPutter;
         private Optional<BucketName> namespace;
+        private Optional<String> bucketPrefix;
 
         public ReadyToBuild(Supplier<BlobStore> supplier, BlobId.Factory blobIdFactory) {
             this.blobIdFactory = blobIdFactory;
@@ -54,6 +55,7 @@ public class ObjectStorageBlobsDAOBuilder {
             this.supplier = supplier;
             this.blobPutter = Optional.empty();
             this.namespace = Optional.empty();
+            this.bucketPrefix = Optional.empty();
         }
 
         public ReadyToBuild payloadCodec(PayloadCodec payloadCodec) {
@@ -81,6 +83,11 @@ public class ObjectStorageBlobsDAOBuilder {
             return this;
         }
 
+        public ReadyToBuild bucketPrefix(String prefix) {
+            this.bucketPrefix = Optional.ofNullable(prefix);
+            return this;
+        }
+
         public ObjectStorageBlobsDAO build() {
             Preconditions.checkState(blobIdFactory != null);
 
diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameResolverTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameResolverTest.java
index 43119d1..3edee3f 100644
--- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameResolverTest.java
+++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBucketNameResolverTest.java
@@ -60,12 +60,12 @@ class ObjectStorageBucketNameResolverTest {
         @Test
         void resolveShouldReturnPassedValueWithPrefix() {
             ObjectStorageBucketNameResolver resolver = ObjectStorageBucketNameResolver.builder()
-                .prefix("prefix-")
+                .prefix("bucketPrefix-")
                 .noNamespace()
                 .build();
 
             assertThat(resolver.resolve(BucketName.of("bucketName")))
-                .isEqualTo(ObjectStorageBucketName.of("prefix-bucketName"));
+                .isEqualTo(ObjectStorageBucketName.of("bucketPrefix-bucketName"));
         }
     }
 
@@ -90,18 +90,18 @@ class ObjectStorageBucketNameResolverTest {
         @Test
         void resolveShouldReturnPassedValueWithPrefix() {
             ObjectStorageBucketNameResolver resolver = ObjectStorageBucketNameResolver.builder()
-                .prefix("prefix-")
+                .prefix("bucketPrefix-")
                 .namespace(BucketName.of("namespace"))
                 .build();
 
             assertThat(resolver.resolve(BucketName.of("bucketName")))
-                .isEqualTo(ObjectStorageBucketName.of("prefix-bucketName"));
+                .isEqualTo(ObjectStorageBucketName.of("bucketPrefix-bucketName"));
         }
 
         @Test
         void resolveShouldReturnNamespaceWhenPassingNamespace() {
             ObjectStorageBucketNameResolver resolver = ObjectStorageBucketNameResolver.builder()
-                .prefix("prefix-")
+                .prefix("bucketPrefix-")
                 .namespace(BucketName.of("namespace"))
                 .build();
 


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


[james-project] 05/06: JAMES-2806 Resolving bucket names in ObjectStorageBlobsDAO

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 9f13e43bb30a43dbb3dded6822be7bacc2dd6bb3
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Mon Jul 8 14:21:40 2019 +0700

    JAMES-2806 Resolving bucket names in ObjectStorageBlobsDAO
---
 .../java/org/apache/james/blob/objectstorage/BlobPutter.java |  5 ++---
 .../james/blob/objectstorage/ObjectStorageBlobsDAO.java      | 12 +++++++++---
 .../blob/objectstorage/ObjectStorageBlobsDAOBuilder.java     |  8 +++++++-
 .../james/blob/objectstorage/ObjectStorageBucketName.java    |  4 ++--
 .../james/blob/objectstorage/StreamCompatibleBlobPutter.java | 11 +++++------
 .../james/blob/objectstorage/aws/AwsS3ObjectStorage.java     | 12 ++++++------
 6 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/BlobPutter.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/BlobPutter.java
index a48c8f2..4a229bf 100644
--- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/BlobPutter.java
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/BlobPutter.java
@@ -22,7 +22,6 @@ package org.apache.james.blob.objectstorage;
 import java.util.function.Supplier;
 
 import org.apache.james.blob.api.BlobId;
-import org.apache.james.blob.api.BucketName;
 import org.jclouds.blobstore.domain.Blob;
 
 /**
@@ -37,7 +36,7 @@ import org.jclouds.blobstore.domain.Blob;
 
 public interface BlobPutter {
 
-    void putDirectly(BucketName bucketName, Blob blob);
+    void putDirectly(ObjectStorageBucketName bucketName, Blob blob);
 
-    BlobId putAndComputeId(BucketName bucketName, Blob initialBlob, Supplier<BlobId> blobIdSupplier);
+    BlobId putAndComputeId(ObjectStorageBucketName bucketName, Blob initialBlob, Supplier<BlobId> blobIdSupplier);
 }
diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java
index a316ab3..4659144 100644
--- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java
@@ -58,16 +58,18 @@ public class ObjectStorageBlobsDAO implements BlobStore {
     private final org.jclouds.blobstore.BlobStore blobStore;
     private final BlobPutter blobPutter;
     private final PayloadCodec payloadCodec;
+    private final ObjectStorageBucketNameResolver bucketNameResolver;
 
     ObjectStorageBlobsDAO(BucketName defaultBucketName, BlobId.Factory blobIdFactory,
                           org.jclouds.blobstore.BlobStore blobStore,
                           BlobPutter blobPutter,
-                          PayloadCodec payloadCodec) {
+                          PayloadCodec payloadCodec, ObjectStorageBucketNameResolver bucketNameResolver) {
         this.blobIdFactory = blobIdFactory;
         this.defaultBucketName = defaultBucketName;
         this.blobStore = blobStore;
         this.blobPutter = blobPutter;
         this.payloadCodec = payloadCodec;
+        this.bucketNameResolver = bucketNameResolver;
     }
 
     public static ObjectStorageBlobsDAOBuilder.RequireBlobIdFactory builder(SwiftTempAuthObjectStorage.Configuration testConfig) {
@@ -89,6 +91,8 @@ public class ObjectStorageBlobsDAO implements BlobStore {
     @Override
     public Mono<BlobId> save(BucketName bucketName, byte[] data) {
         Preconditions.checkNotNull(data);
+        ObjectStorageBucketName resolvedBucketName = bucketNameResolver.resolve(bucketName);
+
         BlobId blobId = blobIdFactory.forPayload(data);
         Payload payload = payloadCodec.write(data);
 
@@ -97,7 +101,7 @@ public class ObjectStorageBlobsDAO implements BlobStore {
             .contentLength(payload.getLength().orElse(new Long(data.length)))
             .build();
 
-        return Mono.fromRunnable(() -> blobPutter.putDirectly(bucketName, blob))
+        return Mono.fromRunnable(() -> blobPutter.putDirectly(resolvedBucketName, blob))
             .thenReturn(blobId);
     }
 
@@ -130,6 +134,8 @@ public class ObjectStorageBlobsDAO implements BlobStore {
     }
 
     private Mono<BlobId> saveBigStream(BucketName bucketName, InputStream data) {
+        ObjectStorageBucketName resolvedBucketName = bucketNameResolver.resolve(bucketName);
+
         BlobId tmpId = blobIdFactory.randomId();
         HashingInputStream hashingInputStream = new HashingInputStream(Hashing.sha256(), data);
         Payload payload = payloadCodec.write(hashingInputStream);
@@ -138,7 +144,7 @@ public class ObjectStorageBlobsDAO implements BlobStore {
                             .build();
 
         Supplier<BlobId> blobIdSupplier = () -> blobIdFactory.from(hashingInputStream.hash().toString());
-        return Mono.fromRunnable(() -> blobPutter.putAndComputeId(bucketName, blob, blobIdSupplier));
+        return Mono.fromRunnable(() -> blobPutter.putAndComputeId(resolvedBucketName, blob, blobIdSupplier));
     }
 
     @Override
diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java
index d6c289c..d085565 100644
--- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOBuilder.java
@@ -93,11 +93,17 @@ public class ObjectStorageBlobsDAOBuilder {
 
             BlobStore blobStore = supplier.get();
 
+            ObjectStorageBucketNameResolver bucketNameResolver = ObjectStorageBucketNameResolver.builder()
+                .prefix(bucketPrefix)
+                .namespace(namespace)
+                .build();
+
             return new ObjectStorageBlobsDAO(namespace.orElse(BucketName.DEFAULT),
                 blobIdFactory,
                 blobStore,
                 blobPutter.orElseGet(() -> defaultPutBlob(blobStore)),
-                payloadCodec.orElse(PayloadCodec.DEFAULT_CODEC));
+                payloadCodec.orElse(PayloadCodec.DEFAULT_CODEC),
+                bucketNameResolver);
         }
 
         private BlobPutter defaultPutBlob(BlobStore blobStore) {
diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketName.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketName.java
index 2eb90c8..1525551 100644
--- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketName.java
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBucketName.java
@@ -27,7 +27,7 @@ import org.apache.james.blob.api.BucketName;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
 
-class ObjectStorageBucketName {
+public class ObjectStorageBucketName {
 
     static ObjectStorageBucketName of(BucketName bucketName) {
         return of(bucketName.asString());
@@ -46,7 +46,7 @@ class ObjectStorageBucketName {
         this.value = value;
     }
 
-    String asString() {
+    public String asString() {
         return value;
     }
 
diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/StreamCompatibleBlobPutter.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/StreamCompatibleBlobPutter.java
index 2375864..30ad89c 100644
--- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/StreamCompatibleBlobPutter.java
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/StreamCompatibleBlobPutter.java
@@ -24,7 +24,6 @@ import java.util.Optional;
 import java.util.function.Supplier;
 
 import org.apache.james.blob.api.BlobId;
-import org.apache.james.blob.api.BucketName;
 import org.jclouds.blobstore.BlobStore;
 import org.jclouds.blobstore.KeyNotFoundException;
 import org.jclouds.blobstore.domain.Blob;
@@ -51,7 +50,7 @@ public class StreamCompatibleBlobPutter implements BlobPutter {
     }
 
     @Override
-    public void putDirectly(BucketName bucketName, Blob blob) {
+    public void putDirectly(ObjectStorageBucketName bucketName, Blob blob) {
         Mono.fromRunnable(() -> blobStore.putBlob(bucketName.asString(), blob))
             .publishOn(Schedulers.elastic())
             .retryWhen(Retry.onlyIf(retryContext -> needToCreateBucket(retryContext.exception(), bucketName))
@@ -67,20 +66,20 @@ public class StreamCompatibleBlobPutter implements BlobPutter {
     }
 
     @Override
-    public BlobId putAndComputeId(BucketName bucketName, Blob initialBlob, Supplier<BlobId> blobIdSupplier) {
+    public BlobId putAndComputeId(ObjectStorageBucketName bucketName, Blob initialBlob, Supplier<BlobId> blobIdSupplier) {
         putDirectly(bucketName, initialBlob);
         BlobId finalId = blobIdSupplier.get();
         updateBlobId(bucketName, initialBlob.getMetadata().getName(), finalId.asString());
         return finalId;
     }
 
-    private void updateBlobId(BucketName bucketName, String from, String to) {
+    private void updateBlobId(ObjectStorageBucketName bucketName, String from, String to) {
         String bucketNameAsString = bucketName.asString();
         blobStore.copyBlob(bucketNameAsString, from, bucketNameAsString, to, CopyOptions.NONE);
         blobStore.removeBlob(bucketNameAsString, from);
     }
 
-    private boolean needToCreateBucket(Throwable throwable, BucketName bucketName) {
+    private boolean needToCreateBucket(Throwable throwable, ObjectStorageBucketName bucketName) {
         return Optional.of(throwable)
             .filter(t -> t instanceof HttpResponseException || t instanceof KeyNotFoundException)
             .flatMap(this::extractHttpException)
@@ -100,7 +99,7 @@ public class StreamCompatibleBlobPutter implements BlobPutter {
             .equals("PUT");
     }
 
-    private boolean bucketExists(BucketName bucketName) {
+    private boolean bucketExists(ObjectStorageBucketName bucketName) {
         return blobStore.containerExists(bucketName.asString());
     }
 
diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorage.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorage.java
index 517bb19..248accf 100644
--- a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorage.java
+++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/aws/AwsS3ObjectStorage.java
@@ -35,9 +35,9 @@ import javax.inject.Inject;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.james.blob.api.BlobId;
-import org.apache.james.blob.api.BucketName;
 import org.apache.james.blob.objectstorage.BlobPutter;
 import org.apache.james.blob.objectstorage.ObjectStorageBlobsDAOBuilder;
+import org.apache.james.blob.objectstorage.ObjectStorageBucketName;
 import org.apache.james.util.Size;
 import org.apache.james.util.concurrent.NamedThreadFactory;
 import org.jclouds.ContextBuilder;
@@ -146,12 +146,12 @@ public class AwsS3ObjectStorage {
         }
 
         @Override
-        public void putDirectly(BucketName bucketName, Blob blob) {
+        public void putDirectly(ObjectStorageBucketName bucketName, Blob blob) {
             writeFileAndAct(blob, (file) -> putWithRetry(bucketName, configuration, blob, file, FIRST_TRY).block());
         }
 
         @Override
-        public BlobId putAndComputeId(BucketName bucketName, Blob initialBlob, Supplier<BlobId> blobIdSupplier) {
+        public BlobId putAndComputeId(ObjectStorageBucketName bucketName, Blob initialBlob, Supplier<BlobId> blobIdSupplier) {
             Consumer<File> putChangedBlob = (file) -> {
                 initialBlob.getMetadata().setName(blobIdSupplier.get().asString());
                 putWithRetry(bucketName, configuration, initialBlob, file, FIRST_TRY).block();
@@ -175,7 +175,7 @@ public class AwsS3ObjectStorage {
             }
         }
 
-        private Mono<Void> putWithRetry(BucketName bucketName, AwsS3AuthConfiguration configuration, Blob blob, File file, int tried) {
+        private Mono<Void> putWithRetry(ObjectStorageBucketName bucketName, AwsS3AuthConfiguration configuration, Blob blob, File file, int tried) {
             return Mono.<Void>fromRunnable(Throwing.runnable(() -> put(bucketName, configuration, blob, file)).sneakyThrow())
                 .publishOn(Schedulers.elastic())
                 .retryWhen(Retry
@@ -186,7 +186,7 @@ public class AwsS3ObjectStorage {
                     .doOnRetry(retryContext -> createBucket(bucketName, configuration)));
         }
 
-        private void put(BucketName bucketName, AwsS3AuthConfiguration configuration, Blob blob, File file) throws InterruptedException {
+        private void put(ObjectStorageBucketName bucketName, AwsS3AuthConfiguration configuration, Blob blob, File file) throws InterruptedException {
             PutObjectRequest request = new PutObjectRequest(bucketName.asString(),
                 blob.getMetadata().getName(),
                 file);
@@ -196,7 +196,7 @@ public class AwsS3ObjectStorage {
                 .waitForUploadResult();
         }
 
-        private void createBucket(BucketName bucketName, AwsS3AuthConfiguration configuration) {
+        private void createBucket(ObjectStorageBucketName bucketName, AwsS3AuthConfiguration configuration) {
             getS3Client(configuration, getClientConfiguration())
                 .createBucket(bucketName.asString());
         }


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