JAMES-2287 Cassandra blobId should implement the blobId interface & move in the 
blob-cassandra project


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

Branch: refs/heads/master
Commit: 68e099ce99243c8b58f82267910eb7a856d9014a
Parents: 1815212
Author: Antoine Duprat <[email protected]>
Authored: Tue Jan 16 13:59:35 2018 +0100
Committer: benwa <[email protected]>
Committed: Fri Jan 19 09:07:27 2018 +0700

----------------------------------------------------------------------
 mailbox/cassandra/pom.xml                       |   4 +
 .../james/mailbox/cassandra/ids/BlobId.java     |  73 ---------------
 .../mail/CassandraAttachmentDAOV2.java          |  14 +--
 .../cassandra/mail/CassandraBlobsDAO.java       |  30 +++---
 .../cassandra/mail/CassandraMessageDAO.java     |  12 +--
 .../james/mailbox/cassandra/ids/BlobIdTest.java |  93 -------------------
 .../mail/CassandraAttachmentDAOV2Test.java      |   4 +-
 .../mail/CassandraAttachmentFallbackTest.java   |   8 +-
 .../cassandra/mail/CassandraBlobsDAOTest.java   |  18 ++--
 .../migration/AttachmentV2MigrationTest.java    |  20 ++--
 pom.xml                                         |   5 +
 server/blob/blob-cassandra/pom.xml              |  74 +++++++++++++++
 .../james/blob/cassandra/CassandraBlobId.java   |  76 +++++++++++++++
 .../blob/cassandra/CassandraBlobIdTest.java     |  86 +++++++++++++++++
 .../src/test/resources/shattered-1.pdf          | Bin 0 -> 422435 bytes
 .../src/test/resources/shattered-2.pdf          | Bin 0 -> 422435 bytes
 server/blob/pom.xml                             |   1 +
 17 files changed, 299 insertions(+), 219 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/mailbox/cassandra/pom.xml
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/pom.xml b/mailbox/cassandra/pom.xml
index 5bffe2b..4377f83 100644
--- a/mailbox/cassandra/pom.xml
+++ b/mailbox/cassandra/pom.xml
@@ -64,6 +64,10 @@
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>blob-cassandra</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>james-server-task</artifactId>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/ids/BlobId.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/ids/BlobId.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/ids/BlobId.java
deleted file mode 100644
index 3824003..0000000
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/ids/BlobId.java
+++ /dev/null
@@ -1,73 +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.mailbox.cassandra.ids;
-
-import org.apache.commons.codec.digest.DigestUtils;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-
-public class BlobId {
-    public static BlobId forPayload(byte[] payload) {
-        Preconditions.checkArgument(payload != null);
-        return new BlobId(DigestUtils.sha256Hex(payload));
-    }
-
-    public static BlobId from(String id) {
-        Preconditions.checkArgument(!Strings.isNullOrEmpty(id));
-        return new BlobId(id);
-    }
-
-    private final String id;
-
-    @VisibleForTesting
-    BlobId(String id) {
-        this.id = id;
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    @Override
-    public final boolean equals(Object obj) {
-        if (obj instanceof BlobId) {
-            BlobId other = (BlobId) obj;
-            return Objects.equal(id, other.id);
-        }
-        return false;
-    }
-
-    @Override
-    public final int hashCode() {
-        return Objects.hashCode(id);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects
-            .toStringHelper(this)
-            .add("id", id)
-            .toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
index 34a654c..5a9727a 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
@@ -38,7 +38,7 @@ import java.util.concurrent.CompletableFuture;
 import javax.inject.Inject;
 
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
-import org.apache.james.mailbox.cassandra.ids.BlobId;
+import org.apache.james.blob.cassandra.CassandraBlobId;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
 
@@ -50,11 +50,11 @@ import com.google.common.base.Preconditions;
 public class CassandraAttachmentDAOV2 {
     public static class DAOAttachment {
         private final AttachmentId attachmentId;
-        private final BlobId blobId;
+        private final CassandraBlobId blobId;
         private final String type;
         private final long size;
 
-        private DAOAttachment(AttachmentId attachmentId, BlobId blobId, String 
type, long size) {
+        private DAOAttachment(AttachmentId attachmentId, CassandraBlobId 
blobId, String type, long size) {
             this.attachmentId = attachmentId;
             this.blobId = blobId;
             this.type = type;
@@ -65,7 +65,7 @@ public class CassandraAttachmentDAOV2 {
             return attachmentId;
         }
 
-        public BlobId getBlobId() {
+        public CassandraBlobId getBlobId() {
             return blobId;
         }
 
@@ -104,7 +104,7 @@ public class CassandraAttachmentDAOV2 {
         }
     }
 
-    public static DAOAttachment from(Attachment attachment, BlobId blobId) {
+    public static DAOAttachment from(Attachment attachment, CassandraBlobId 
blobId) {
         return new DAOAttachment(
             attachment.getAttachmentId(),
             blobId,
@@ -115,7 +115,7 @@ public class CassandraAttachmentDAOV2 {
     private static DAOAttachment fromRow(Row row) {
         return new DAOAttachment(
             AttachmentId.from(row.getString(ID)),
-            BlobId.from(row.getString(BLOB_ID)),
+            CassandraBlobId.from(row.getString(BLOB_ID)),
             row.getString(TYPE),
             row.getLong(SIZE));
     }
@@ -163,7 +163,7 @@ public class CassandraAttachmentDAOV2 {
                 .setString(ID, attachment.getAttachmentId().getId())
                 .setLong(SIZE, attachment.getSize())
                 .setString(TYPE, attachment.getType())
-                .setString(BLOB_ID, attachment.getBlobId().getId()));
+                .setString(BLOB_ID, attachment.getBlobId().asString()));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraBlobsDAO.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraBlobsDAO.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraBlobsDAO.java
index c7eabf7..5fc09aa 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraBlobsDAO.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraBlobsDAO.java
@@ -35,7 +35,7 @@ import javax.inject.Inject;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.james.backends.cassandra.init.CassandraConfiguration;
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
-import org.apache.james.mailbox.cassandra.ids.BlobId;
+import org.apache.james.blob.cassandra.CassandraBlobId;
 import org.apache.james.mailbox.cassandra.mail.utils.DataChunker;
 import org.apache.james.mailbox.cassandra.table.BlobTable;
 import org.apache.james.mailbox.cassandra.table.BlobTable.BlobParts;
@@ -106,16 +106,16 @@ public class CassandraBlobsDAO {
             .value(BlobParts.DATA, bindMarker(BlobParts.DATA)));
     }
 
-    public CompletableFuture<BlobId> save(byte[] data) {
+    public CompletableFuture<CassandraBlobId> save(byte[] data) {
         Preconditions.checkNotNull(data);
 
-        BlobId blobId = BlobId.forPayload(data);
+        CassandraBlobId blobId = CassandraBlobId.forPayload(data);
         return saveBlobParts(data, blobId)
             .thenCompose(numberOfChunk -> saveBlobPartsReferences(blobId, 
numberOfChunk))
             .thenApply(any -> blobId);
     }
 
-    private CompletableFuture<Integer> saveBlobParts(byte[] data, BlobId 
blobId) {
+    private CompletableFuture<Integer> saveBlobParts(byte[] data, 
CassandraBlobId blobId) {
         return FluentFutureStream.of(
             dataChunker.chunk(data, configuration.getBlobPartSize())
                 .map(pair -> writePart(pair.getRight(), blobId, pair.getKey())
@@ -131,29 +131,29 @@ public class CassandraBlobsDAO {
         return stream.reduce((first, second) -> second);
     }
 
-    private CompletableFuture<Void> writePart(ByteBuffer data, BlobId blobId, 
int position) {
+    private CompletableFuture<Void> writePart(ByteBuffer data, CassandraBlobId 
blobId, int position) {
         return cassandraAsyncExecutor.executeVoid(
             insertPart.bind()
-                .setString(BlobTable.ID, blobId.getId())
+                .setString(BlobTable.ID, blobId.asString())
                 .setInt(BlobParts.CHUNK_NUMBER, position)
                 .setBytes(BlobParts.DATA, data));
     }
 
-    private CompletableFuture<Void> saveBlobPartsReferences(BlobId blobId, int 
numberOfChunk) {
+    private CompletableFuture<Void> saveBlobPartsReferences(CassandraBlobId 
blobId, int numberOfChunk) {
         return cassandraAsyncExecutor.executeVoid(insert.bind()
-            .setString(BlobTable.ID, blobId.getId())
+            .setString(BlobTable.ID, blobId.asString())
             .setInt(BlobTable.NUMBER_OF_CHUNK, numberOfChunk));
     }
 
-    public CompletableFuture<byte[]> read(BlobId blobId) {
+    public CompletableFuture<byte[]> read(CassandraBlobId blobId) {
         return cassandraAsyncExecutor.executeSingleRow(
             select.bind()
-                .setString(BlobTable.ID, blobId.getId()))
+                .setString(BlobTable.ID, blobId.asString()))
             .thenCompose(row -> toDataParts(row, blobId))
             .thenApply(this::concatenateDataParts);
     }
 
-    private CompletableFuture<Stream<BlobPart>> toDataParts(Optional<Row> 
blobRowOptional, BlobId blobId) {
+    private CompletableFuture<Stream<BlobPart>> toDataParts(Optional<Row> 
blobRowOptional, CassandraBlobId blobId) {
         return blobRowOptional.map(blobRow -> {
             int numOfChunk = blobRow.getInt(BlobTable.NUMBER_OF_CHUNK);
             return FluentFutureStream.of(
@@ -184,20 +184,20 @@ public class CassandraBlobsDAO {
         return data;
     }
 
-    private CompletableFuture<BlobPart> readPart(BlobId blobId, int position) {
+    private CompletableFuture<BlobPart> readPart(CassandraBlobId blobId, int 
position) {
         return cassandraAsyncExecutor.executeSingleRow(
             selectPart.bind()
-                .setString(BlobTable.ID, blobId.getId())
+                .setString(BlobTable.ID, blobId.asString())
                 .setInt(BlobParts.CHUNK_NUMBER, position))
             .thenApply(row -> new BlobPart(blobId, position, row));
     }
 
     private static class BlobPart {
-        private final BlobId blobId;
+        private final CassandraBlobId blobId;
         private final int position;
         private final Optional<Row> row;
 
-        public BlobPart(BlobId blobId, int position, Optional<Row> row) {
+        public BlobPart(CassandraBlobId blobId, int position, Optional<Row> 
row) {
             Preconditions.checkNotNull(blobId);
             Preconditions.checkArgument(position >= 0, "position need to be 
positive");
             this.blobId = blobId;

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
index 83477fb..c80f982 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
@@ -59,7 +59,7 @@ import 
org.apache.james.backends.cassandra.init.CassandraConfiguration;
 import org.apache.james.backends.cassandra.init.CassandraTypesProvider;
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
-import org.apache.james.mailbox.cassandra.ids.BlobId;
+import org.apache.james.blob.cassandra.CassandraBlobId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.mail.utils.Limit;
 import org.apache.james.mailbox.cassandra.table.CassandraMessageV2Table;
@@ -176,7 +176,7 @@ public class CassandraMessageDAO {
             cassandraAsyncExecutor.executeVoid(boundWriteStatement(message, 
pair)));
     }
 
-    private CompletableFuture<Pair<BlobId, BlobId>> saveContent(MailboxMessage 
message) throws MailboxException {
+    private CompletableFuture<Pair<CassandraBlobId, CassandraBlobId>> 
saveContent(MailboxMessage message) throws MailboxException {
         try {
             return CompletableFutureUtil.combine(
                 blobsDAO.save(
@@ -191,7 +191,7 @@ public class CassandraMessageDAO {
         }
     }
 
-    private BoundStatement boundWriteStatement(MailboxMessage message, 
Pair<BlobId, BlobId> pair) {
+    private BoundStatement boundWriteStatement(MailboxMessage message, 
Pair<CassandraBlobId, CassandraBlobId> pair) {
         CassandraMessageId messageId = (CassandraMessageId) 
message.getMessageId();
         return insert.bind()
             .setUUID(MESSAGE_ID, messageId.get())
@@ -199,8 +199,8 @@ public class CassandraMessageDAO {
             .setInt(BODY_START_OCTET, (int) (message.getHeaderOctets()))
             .setLong(FULL_CONTENT_OCTETS, message.getFullContentOctets())
             .setLong(BODY_OCTECTS, message.getBodyOctets())
-            .setString(BODY_CONTENT, pair.getRight().getId())
-            .setString(HEADER_CONTENT, pair.getLeft().getId())
+            .setString(BODY_CONTENT, pair.getRight().asString())
+            .setString(HEADER_CONTENT, pair.getLeft().asString())
             .setLong(TEXTUAL_LINE_COUNT, 
Optional.ofNullable(message.getTextualLineCount()).orElse(DEFAULT_LONG_VALUE))
             .setList(PROPERTIES, buildPropertiesUdt(message))
             .setList(ATTACHMENTS, buildAttachmentUdt(message));
@@ -370,7 +370,7 @@ public class CassandraMessageDAO {
     }
 
     private CompletableFuture<byte[]> getFieldContent(String field, Row row) {
-        return blobsDAO.read(BlobId.from(row.getString(field)));
+        return blobsDAO.read(CassandraBlobId.from(row.getString(field)));
     }
 
     public static MessageResult notFound(ComposedMessageIdWithMetaData id) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/ids/BlobIdTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/ids/BlobIdTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/ids/BlobIdTest.java
deleted file mode 100644
index e8e3f13..0000000
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/ids/BlobIdTest.java
+++ /dev/null
@@ -1,93 +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.mailbox.cassandra.ids;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.nio.charset.StandardCharsets;
-
-import org.apache.james.util.ClassLoaderUtils;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-public class BlobIdTest {
-
-    @Rule
-    public ExpectedException expectedException = ExpectedException.none();
-
-    @Test
-    public void shouldRespectBeanContract() {
-        EqualsVerifier.forClass(BlobId.class).verify();
-    }
-
-    @Test
-    public void fromShouldConstructBlobId() {
-        String id = "111";
-        assertThat(BlobId.from(id))
-            .isEqualTo(new BlobId(id));
-    }
-
-    @Test
-    public void fromShouldThrowOnNull() {
-        expectedException.expect(IllegalArgumentException.class);
-
-        BlobId.from(null);
-    }
-
-    @Test
-    public void fromShouldThrowOnEmpty() {
-        expectedException.expect(IllegalArgumentException.class);
-
-        BlobId.from("");
-    }
-
-    @Test
-    public void forPayloadShouldThrowOnNull() {
-        expectedException.expect(IllegalArgumentException.class);
-
-        BlobId.forPayload(null);
-    }
-
-    @Test
-    public void forPayloadShouldHashEmptyArray() {
-        BlobId blobId = BlobId.forPayload(new byte[0]);
-
-        
assertThat(blobId.getId()).isEqualTo("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
-    }
-
-    @Test
-    public void forPayloadShouldHashArray() {
-        BlobId blobId = 
BlobId.forPayload("content".getBytes(StandardCharsets.UTF_8));
-
-        
assertThat(blobId.getId()).isEqualTo("ed7002b439e9ac845f22357d822bac1444730fbdb6016d3ec9432297b9ec9f73");
-    }
-
-    @Test
-    public void 
forPayloadShouldCalculateDifferentHashesWhenCraftedSha1Collision() throws 
Exception {
-        byte[] payload1 = 
ClassLoaderUtils.getSystemResourceAsByteArray("shattered-1.pdf");
-        byte[] payload2 = 
ClassLoaderUtils.getSystemResourceAsByteArray("shattered-2.pdf");
-        BlobId blobId1 = BlobId.forPayload(payload1);
-        BlobId blobId2 = BlobId.forPayload(payload2);
-        assertThat(blobId1).isNotEqualTo(blobId2);
-    }
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2Test.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2Test.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2Test.java
index 84e19bc..f5a8285 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2Test.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2Test.java
@@ -26,7 +26,7 @@ import java.util.Optional;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
-import org.apache.james.mailbox.cassandra.ids.BlobId;
+import org.apache.james.blob.cassandra.CassandraBlobId;
 import 
org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAOV2.DAOAttachment;
 import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
 import org.apache.james.mailbox.model.Attachment;
@@ -75,7 +75,7 @@ public class CassandraAttachmentDAOV2Test {
             .type("application/json")
             
.bytes("{\"property\":`\"value\"}".getBytes(StandardCharsets.UTF_8))
             .build();
-        BlobId blobId = BlobId.from("blobId");
+        CassandraBlobId blobId = CassandraBlobId.from("blobId");
         DAOAttachment daoAttachment = 
CassandraAttachmentDAOV2.from(attachment, blobId);
         testee.storeAttachment(daoAttachment).join();
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
index 6ac6409..4c42a2d 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentFallbackTest.java
@@ -29,7 +29,7 @@ import 
org.apache.james.backends.cassandra.DockerCassandraRule;
 import org.apache.james.backends.cassandra.init.CassandraConfiguration;
 import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
-import org.apache.james.mailbox.cassandra.ids.BlobId;
+import org.apache.james.blob.cassandra.CassandraBlobId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraBlobModule;
@@ -108,7 +108,7 @@ public class CassandraAttachmentFallbackTest {
             
.bytes("{\"property\":`\"different\"}".getBytes(StandardCharsets.UTF_8))
             .build();
 
-        BlobId blobId = blobsDAO.save(attachment.getBytes()).join();
+        CassandraBlobId blobId = blobsDAO.save(attachment.getBytes()).join();
         
attachmentDAOV2.storeAttachment(CassandraAttachmentDAOV2.from(attachment, 
blobId)).join();
         attachmentDAO.storeAttachment(otherAttachment).join();
 
@@ -143,7 +143,7 @@ public class CassandraAttachmentFallbackTest {
             
.bytes("{\"property\":`\"different\"}".getBytes(StandardCharsets.UTF_8))
             .build();
 
-        BlobId blobId = blobsDAO.save(attachment.getBytes()).join();
+        CassandraBlobId blobId = blobsDAO.save(attachment.getBytes()).join();
         
attachmentDAOV2.storeAttachment(CassandraAttachmentDAOV2.from(attachment, 
blobId)).join();
         attachmentDAO.storeAttachment(otherAttachment).join();
 
@@ -178,7 +178,7 @@ public class CassandraAttachmentFallbackTest {
             
.bytes("{\"property\":`\"different\"}".getBytes(StandardCharsets.UTF_8))
             .build();
 
-        BlobId blobId = blobsDAO.save(attachment.getBytes()).join();
+        CassandraBlobId blobId = blobsDAO.save(attachment.getBytes()).join();
         
attachmentDAOV2.storeAttachment(CassandraAttachmentDAOV2.from(attachment, 
blobId)).join();
         attachmentDAO.storeAttachment(otherAttachment).join();
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraBlobsDAOTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraBlobsDAOTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraBlobsDAOTest.java
index 9709bb4..e92316a 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraBlobsDAOTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraBlobsDAOTest.java
@@ -28,7 +28,7 @@ import java.nio.charset.StandardCharsets;
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
 import org.apache.james.backends.cassandra.init.CassandraConfiguration;
-import org.apache.james.mailbox.cassandra.ids.BlobId;
+import org.apache.james.blob.cassandra.CassandraBlobId;
 import org.apache.james.mailbox.cassandra.modules.CassandraBlobModule;
 import org.junit.After;
 import org.junit.Before;
@@ -70,7 +70,7 @@ public class CassandraBlobsDAOTest {
 
     @Test
     public void saveShouldSaveEmptyData() throws Exception {
-        BlobId blobId = testee.save(new byte[]{}).join();
+        CassandraBlobId blobId = testee.save(new byte[]{}).join();
 
         byte[] bytes = testee.read(blobId).join();
 
@@ -79,7 +79,7 @@ public class CassandraBlobsDAOTest {
 
     @Test
     public void saveShouldSaveBlankData() throws Exception {
-        BlobId blobId = 
testee.save("".getBytes(StandardCharsets.UTF_8)).join();
+        CassandraBlobId blobId = 
testee.save("".getBytes(StandardCharsets.UTF_8)).join();
 
         byte[] bytes = testee.read(blobId).join();
 
@@ -88,21 +88,21 @@ public class CassandraBlobsDAOTest {
 
     @Test
     public void saveShouldReturnBlobId() throws Exception {
-        BlobId blobId = 
testee.save("toto".getBytes(StandardCharsets.UTF_8)).join();
+        CassandraBlobId blobId = 
testee.save("toto".getBytes(StandardCharsets.UTF_8)).join();
 
-        
assertThat(blobId).isEqualTo(BlobId.from("31f7a65e315586ac198bd798b6629ce4903d0899476d5741a9f32e2e521b6a66"));
+        
assertThat(blobId).isEqualTo(CassandraBlobId.from("31f7a65e315586ac198bd798b6629ce4903d0899476d5741a9f32e2e521b6a66"));
     }
 
     @Test
     public void readShouldBeEmptyWhenNoExisting() throws IOException {
-        byte[] bytes = testee.read(BlobId.from("unknown")).join();
+        byte[] bytes = testee.read(CassandraBlobId.from("unknown")).join();
 
         assertThat(bytes).isEmpty();
     }
 
     @Test
     public void readShouldReturnSavedData() throws IOException {
-        BlobId blobId = 
testee.save("toto".getBytes(StandardCharsets.UTF_8)).join();
+        CassandraBlobId blobId = 
testee.save("toto".getBytes(StandardCharsets.UTF_8)).join();
 
         byte[] bytes = testee.read(blobId).join();
 
@@ -112,7 +112,7 @@ public class CassandraBlobsDAOTest {
     @Test
     public void readShouldReturnLongSavedData() throws IOException {
         String longString = Strings.repeat("0123456789\n", 1000);
-        BlobId blobId = 
testee.save(longString.getBytes(StandardCharsets.UTF_8)).join();
+        CassandraBlobId blobId = 
testee.save(longString.getBytes(StandardCharsets.UTF_8)).join();
 
         byte[] bytes = testee.read(blobId).join();
 
@@ -122,7 +122,7 @@ public class CassandraBlobsDAOTest {
     @Test
     public void readShouldReturnSplitSavedDataByChunk() throws IOException {
         String longString = Strings.repeat("0123456789\n", 
MULTIPLE_CHUNK_SIZE);
-        BlobId blobId = 
testee.save(longString.getBytes(StandardCharsets.UTF_8)).join();
+        CassandraBlobId blobId = 
testee.save(longString.getBytes(StandardCharsets.UTF_8)).join();
 
         byte[] bytes = testee.read(blobId).join();
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2MigrationTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2MigrationTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2MigrationTest.java
index 0f456ac..b53205e 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2MigrationTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2MigrationTest.java
@@ -34,7 +34,7 @@ import 
org.apache.james.backends.cassandra.init.CassandraConfiguration;
 import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
 import org.apache.james.backends.cassandra.migration.Migration;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
-import org.apache.james.mailbox.cassandra.ids.BlobId;
+import org.apache.james.blob.cassandra.CassandraBlobId;
 import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAOV2;
 import org.apache.james.mailbox.cassandra.mail.CassandraBlobsDAO;
@@ -112,12 +112,12 @@ public class AttachmentV2MigrationTest {
         migration.run();
 
         assertThat(attachmentDAOV2.getAttachment(ATTACHMENT_ID).join())
-            .contains(CassandraAttachmentDAOV2.from(attachment1, 
BlobId.forPayload(attachment1.getBytes())));
+            .contains(CassandraAttachmentDAOV2.from(attachment1, 
CassandraBlobId.forPayload(attachment1.getBytes())));
         assertThat(attachmentDAOV2.getAttachment(ATTACHMENT_ID_2).join())
-            .contains(CassandraAttachmentDAOV2.from(attachment2, 
BlobId.forPayload(attachment2.getBytes())));
-        
assertThat(blobsDAO.read(BlobId.forPayload(attachment1.getBytes())).join())
+            .contains(CassandraAttachmentDAOV2.from(attachment2, 
CassandraBlobId.forPayload(attachment2.getBytes())));
+        
assertThat(blobsDAO.read(CassandraBlobId.forPayload(attachment1.getBytes())).join())
             .isEqualTo(attachment1.getBytes());
-        
assertThat(blobsDAO.read(BlobId.forPayload(attachment2.getBytes())).join())
+        
assertThat(blobsDAO.read(CassandraBlobId.forPayload(attachment2.getBytes())).join())
             .isEqualTo(attachment2.getBytes());
     }
 
@@ -172,9 +172,9 @@ public class AttachmentV2MigrationTest {
             attachment1,
             attachment2));
         when(blobsDAO.save(attachment1.getBytes()))
-            
.thenReturn(CompletableFuture.completedFuture(BlobId.forPayload(attachment1.getBytes())));
+            
.thenReturn(CompletableFuture.completedFuture(CassandraBlobId.forPayload(attachment1.getBytes())));
         when(blobsDAO.save(attachment2.getBytes()))
-            
.thenReturn(CompletableFuture.completedFuture(BlobId.forPayload(attachment2.getBytes())));
+            
.thenReturn(CompletableFuture.completedFuture(CassandraBlobId.forPayload(attachment2.getBytes())));
         when(attachmentDAOV2.storeAttachment(any())).thenThrow(new 
RuntimeException());
 
         assertThat(migration.run()).isEqualTo(Migration.Result.PARTIAL);
@@ -191,9 +191,9 @@ public class AttachmentV2MigrationTest {
             attachment1,
             attachment2));
         when(blobsDAO.save(attachment1.getBytes()))
-            
.thenReturn(CompletableFuture.completedFuture(BlobId.forPayload(attachment1.getBytes())));
+            
.thenReturn(CompletableFuture.completedFuture(CassandraBlobId.forPayload(attachment1.getBytes())));
         when(blobsDAO.save(attachment2.getBytes()))
-            
.thenReturn(CompletableFuture.completedFuture(BlobId.forPayload(attachment2.getBytes())));
+            
.thenReturn(CompletableFuture.completedFuture(CassandraBlobId.forPayload(attachment2.getBytes())));
         
when(attachmentDAOV2.storeAttachment(any())).thenReturn(CompletableFuture.completedFuture(null));
         when(attachmentDAO.deleteAttachment(any())).thenThrow(new 
RuntimeException());
 
@@ -211,7 +211,7 @@ public class AttachmentV2MigrationTest {
             attachment1,
             attachment2));
         when(blobsDAO.save(attachment1.getBytes()))
-            
.thenReturn(CompletableFuture.completedFuture(BlobId.forPayload(attachment1.getBytes())));
+            
.thenReturn(CompletableFuture.completedFuture(CassandraBlobId.forPayload(attachment1.getBytes())));
         when(blobsDAO.save(attachment2.getBytes()))
             .thenThrow(new RuntimeException());
         
when(attachmentDAOV2.storeAttachment(any())).thenReturn(CompletableFuture.completedFuture(null));

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 420ffaa..edf90d3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -975,6 +975,11 @@
             </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
+                <artifactId>blob-cassandra</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
                 <artifactId>james-server-cassandra-guice</artifactId>
                 <version>${project.version}</version>
             </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/server/blob/blob-cassandra/pom.xml
----------------------------------------------------------------------
diff --git a/server/blob/blob-cassandra/pom.xml 
b/server/blob/blob-cassandra/pom.xml
new file mode 100644
index 0000000..387d222
--- /dev/null
+++ b/server/blob/blob-cassandra/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>james-server-blob</artifactId>
+        <groupId>org.apache.james</groupId>
+        <version>3.1.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>blob-cassandra</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Apache James :: Server :: Blob :: Cassandra</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>blob-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-util-java8</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>nl.jqno.equalsverifier</groupId>
+            <artifactId>equalsverifier</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-launcher</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    
+</project>

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/server/blob/blob-cassandra/src/main/java/org/apache/james/blob/cassandra/CassandraBlobId.java
----------------------------------------------------------------------
diff --git 
a/server/blob/blob-cassandra/src/main/java/org/apache/james/blob/cassandra/CassandraBlobId.java
 
b/server/blob/blob-cassandra/src/main/java/org/apache/james/blob/cassandra/CassandraBlobId.java
new file mode 100644
index 0000000..5dba57e
--- /dev/null
+++ 
b/server/blob/blob-cassandra/src/main/java/org/apache/james/blob/cassandra/CassandraBlobId.java
@@ -0,0 +1,76 @@
+/****************************************************************
+ * 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.cassandra;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.james.blob.api.BlobId;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+
+public class CassandraBlobId implements BlobId {
+
+    public static CassandraBlobId forPayload(byte[] payload) {
+        Preconditions.checkArgument(payload != null);
+        return new CassandraBlobId(DigestUtils.sha256Hex(payload));
+    }
+
+    public static CassandraBlobId from(String id) {
+        Preconditions.checkArgument(!Strings.isNullOrEmpty(id));
+        return new CassandraBlobId(id);
+    }
+
+    private final String id;
+
+    @VisibleForTesting
+    CassandraBlobId(String id) {
+        this.id = id;
+    }
+
+    @Override
+    public String asString() {
+        return id;
+    }
+
+    @Override
+    public final boolean equals(Object obj) {
+        if (obj instanceof CassandraBlobId) {
+            CassandraBlobId other = (CassandraBlobId) obj;
+            return Objects.equal(id, other.id);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hashCode(id);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects
+            .toStringHelper(this)
+            .add("id", id)
+            .toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobIdTest.java
----------------------------------------------------------------------
diff --git 
a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobIdTest.java
 
b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobIdTest.java
new file mode 100644
index 0000000..2fe0db2
--- /dev/null
+++ 
b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobIdTest.java
@@ -0,0 +1,86 @@
+/****************************************************************
+ * 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.cassandra;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.nio.charset.StandardCharsets;
+
+import org.apache.james.util.ClassLoaderUtils;
+import org.junit.jupiter.api.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class CassandraBlobIdTest {
+
+    @Test
+    public void shouldRespectBeanContract() {
+        EqualsVerifier.forClass(CassandraBlobId.class).verify();
+    }
+
+    @Test
+    public void fromShouldConstructBlobId() {
+        String id = "111";
+        assertThat(CassandraBlobId.from(id))
+            .isEqualTo(new CassandraBlobId(id));
+    }
+
+    @Test
+    public void fromShouldThrowOnNull() {
+        assertThatThrownBy(() -> CassandraBlobId.from(null))
+            .isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    public void fromShouldThrowOnEmpty() {
+        assertThatThrownBy(() -> CassandraBlobId.from(""))
+            .isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    public void forPayloadShouldThrowOnNull() {
+        assertThatThrownBy(() -> CassandraBlobId.forPayload(null))
+            .isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    public void forPayloadShouldHashEmptyArray() {
+        CassandraBlobId blobId = CassandraBlobId.forPayload(new byte[0]);
+
+        
assertThat(blobId.asString()).isEqualTo("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
+    }
+
+    @Test
+    public void forPayloadShouldHashArray() {
+        CassandraBlobId blobId = 
CassandraBlobId.forPayload("content".getBytes(StandardCharsets.UTF_8));
+
+        
assertThat(blobId.asString()).isEqualTo("ed7002b439e9ac845f22357d822bac1444730fbdb6016d3ec9432297b9ec9f73");
+    }
+
+    @Test
+    public void 
forPayloadShouldCalculateDifferentHashesWhenCraftedSha1Collision() throws 
Exception {
+        byte[] payload1 = 
ClassLoaderUtils.getSystemResourceAsByteArray("shattered-1.pdf");
+        byte[] payload2 = 
ClassLoaderUtils.getSystemResourceAsByteArray("shattered-2.pdf");
+        CassandraBlobId blobId1 = CassandraBlobId.forPayload(payload1);
+        CassandraBlobId blobId2 = CassandraBlobId.forPayload(payload2);
+        assertThat(blobId1).isNotEqualTo(blobId2);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/server/blob/blob-cassandra/src/test/resources/shattered-1.pdf
----------------------------------------------------------------------
diff --git a/server/blob/blob-cassandra/src/test/resources/shattered-1.pdf 
b/server/blob/blob-cassandra/src/test/resources/shattered-1.pdf
new file mode 100644
index 0000000..ba9aaa1
Binary files /dev/null and 
b/server/blob/blob-cassandra/src/test/resources/shattered-1.pdf differ

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/server/blob/blob-cassandra/src/test/resources/shattered-2.pdf
----------------------------------------------------------------------
diff --git a/server/blob/blob-cassandra/src/test/resources/shattered-2.pdf 
b/server/blob/blob-cassandra/src/test/resources/shattered-2.pdf
new file mode 100644
index 0000000..b621eec
Binary files /dev/null and 
b/server/blob/blob-cassandra/src/test/resources/shattered-2.pdf differ

http://git-wip-us.apache.org/repos/asf/james-project/blob/68e099ce/server/blob/pom.xml
----------------------------------------------------------------------
diff --git a/server/blob/pom.xml b/server/blob/pom.xml
index d86a2bd..21cfffb 100644
--- a/server/blob/pom.xml
+++ b/server/blob/pom.xml
@@ -34,6 +34,7 @@
 
     <modules>
         <module>blob-api</module>
+        <module>blob-cassandra</module>
     </modules>
 
 </project>


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to