MAILBOX-339 Introduce CassandraMailboxPathDAO interface

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

Branch: refs/heads/master
Commit: 2fae24a82c9d453bdb2556257cd9afbb96e56afd
Parents: f8b587a
Author: Antoine Duprat <adup...@linagora.com>
Authored: Mon May 14 15:18:07 2018 +0200
Committer: Matthieu Baechler <matth...@apache.org>
Committed: Mon May 28 17:38:00 2018 +0200

----------------------------------------------------------------------
 .../CassandraMailboxSessionMapperFactory.java   |   6 +-
 .../cassandra/mail/CassandraIdAndPath.java      |  58 ++++++
 .../cassandra/mail/CassandraMailboxMapper.java  |   8 +-
 .../cassandra/mail/CassandraMailboxPathDAO.java | 187 +------------------
 .../mail/CassandraMailboxPathDAOImpl.java       | 185 ++++++++++++++++++
 .../CassandraSubscriptionManagerTest.java       |   4 +-
 ...estCassandraMailboxSessionMapperFactory.java |   4 +-
 .../CassandraMailboxMapperConcurrencyTest.java  |   2 +-
 .../mail/CassandraMailboxMapperTest.java        |   4 +-
 .../mail/CassandraMailboxPathDAOImplTest.java   |  28 +++
 .../mail/CassandraMailboxPathDAOTest.java       |  10 +-
 .../modules/mailbox/CassandraMailboxModule.java |   4 +-
 12 files changed, 298 insertions(+), 202 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/2fae24a8/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
index f25c738..60ee504 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
@@ -39,7 +39,7 @@ import 
org.apache.james.mailbox.cassandra.mail.CassandraIndexTableHandler;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxCounterDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxMapper;
-import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAOImpl;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
@@ -79,7 +79,7 @@ public class CassandraMailboxSessionMapperFactory extends 
MailboxSessionMapperFa
     private final CassandraMailboxRecentsDAO mailboxRecentsDAO;
     private final CassandraIndexTableHandler indexTableHandler;
     private final CassandraMailboxDAO mailboxDAO;
-    private final CassandraMailboxPathDAO mailboxPathDAO;
+    private final CassandraMailboxPathDAOImpl mailboxPathDAO;
     private final CassandraFirstUnseenDAO firstUnseenDAO;
     private final CassandraApplicableFlagDAO applicableFlagDAO;
     private final CassandraAttachmentDAO attachmentDAO;
@@ -98,7 +98,7 @@ public class CassandraMailboxSessionMapperFactory extends 
MailboxSessionMapperFa
                                                 CassandraMessageDAO messageDAO,
                                                 CassandraMessageIdDAO 
messageIdDAO, CassandraMessageIdToImapUidDAO imapUidDAO,
                                                 CassandraMailboxCounterDAO 
mailboxCounterDAO, CassandraMailboxRecentsDAO mailboxRecentsDAO, 
CassandraMailboxDAO mailboxDAO,
-                                                CassandraMailboxPathDAO 
mailboxPathDAO, CassandraFirstUnseenDAO firstUnseenDAO, 
CassandraApplicableFlagDAO applicableFlagDAO,
+                                                CassandraMailboxPathDAOImpl 
mailboxPathDAO, CassandraFirstUnseenDAO firstUnseenDAO, 
CassandraApplicableFlagDAO applicableFlagDAO,
                                                 CassandraAttachmentDAO 
attachmentDAO, CassandraAttachmentDAOV2 attachmentDAOV2, 
CassandraDeletedMessageDAO deletedMessageDAO,
                                                 ObjectStore objectStore, 
CassandraAttachmentMessageIdDAO attachmentMessageIdDAO,
                                                 CassandraAttachmentOwnerDAO 
ownerDAO, CassandraACLMapper aclMapper,

http://git-wip-us.apache.org/repos/asf/james-project/blob/2fae24a8/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraIdAndPath.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraIdAndPath.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraIdAndPath.java
new file mode 100644
index 0000000..e476b02
--- /dev/null
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraIdAndPath.java
@@ -0,0 +1,58 @@
+/****************************************************************
+ * 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.mail;
+
+import org.apache.james.mailbox.cassandra.ids.CassandraId;
+import org.apache.james.mailbox.model.MailboxPath;
+
+import com.google.common.base.Objects;
+
+public class CassandraIdAndPath {
+    private final CassandraId cassandraId;
+    private final MailboxPath mailboxPath;
+
+    public CassandraIdAndPath(CassandraId cassandraId, MailboxPath 
mailboxPath) {
+        this.cassandraId = cassandraId;
+        this.mailboxPath = mailboxPath;
+    }
+
+    public CassandraId getCassandraId() {
+        return cassandraId;
+    }
+
+    public MailboxPath getMailboxPath() {
+        return mailboxPath;
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof CassandraIdAndPath) {
+            CassandraIdAndPath that = (CassandraIdAndPath) o;
+
+            return Objects.equal(this.cassandraId, that.cassandraId)
+                && Objects.equal(this.mailboxPath, that.mailboxPath);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hashCode(cassandraId, mailboxPath);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/2fae24a8/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
index 865938b..8fe6f26 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
@@ -65,13 +65,13 @@ public class CassandraMailboxMapper implements 
MailboxMapper {
     public static final String CLUSTERING_COLUMNS_IS_TOO_LONG = "The sum of 
all clustering columns is too long";
     public static final Logger LOGGER = 
LoggerFactory.getLogger(CassandraMailboxMapper.class);
 
-    private final CassandraMailboxPathDAO mailboxPathDAO;
+    private final CassandraMailboxPathDAOImpl mailboxPathDAO;
     private final CassandraMailboxDAO mailboxDAO;
     private final CassandraACLMapper cassandraACLMapper;
     private final CassandraUserMailboxRightsDAO userMailboxRightsDAO;
 
     @Inject
-    public CassandraMailboxMapper(CassandraMailboxDAO mailboxDAO, 
CassandraMailboxPathDAO mailboxPathDAO, CassandraUserMailboxRightsDAO 
userMailboxRightsDAO, CassandraACLMapper aclMapper, CassandraConfiguration 
cassandraConfiguration) {
+    public CassandraMailboxMapper(CassandraMailboxDAO mailboxDAO, 
CassandraMailboxPathDAOImpl mailboxPathDAO, CassandraUserMailboxRightsDAO 
userMailboxRightsDAO, CassandraACLMapper aclMapper, CassandraConfiguration 
cassandraConfiguration) {
         this.mailboxDAO = mailboxDAO;
         this.mailboxPathDAO = mailboxPathDAO;
         this.userMailboxRightsDAO = userMailboxRightsDAO;
@@ -92,7 +92,7 @@ public class CassandraMailboxMapper implements MailboxMapper {
             return mailboxPathDAO.retrieveId(path)
                 .thenCompose(cassandraIdOptional ->
                     cassandraIdOptional
-                        
.map(CassandraMailboxPathDAO.CassandraIdAndPath::getCassandraId)
+                        .map(CassandraIdAndPath::getCassandraId)
                         .map(this::retrieveMailbox)
                         
.orElse(CompletableFuture.completedFuture(Optional.empty())))
                 .join()
@@ -145,7 +145,7 @@ public class CassandraMailboxMapper implements 
MailboxMapper {
             .collect(Guavate.toImmutableList());
     }
 
-    private CompletableFuture<Optional<SimpleMailbox>> 
retrieveMailbox(CassandraMailboxPathDAO.CassandraIdAndPath idAndPath) {
+    private CompletableFuture<Optional<SimpleMailbox>> 
retrieveMailbox(CassandraIdAndPath idAndPath) {
         return retrieveMailbox(idAndPath.getCassandraId())
             .thenApply(optional -> OptionalUtils.executeIfEmpty(optional,
                 () -> LOGGER.warn("Could not retrieve mailbox {} with path {} 
in mailbox table.", idAndPath.getCassandraId(), idAndPath.getMailboxPath())));

http://git-wip-us.apache.org/repos/asf/james-project/blob/2fae24a8/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAO.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAO.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAO.java
index 8a06811..33fac3c 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAO.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAO.java
@@ -19,198 +19,23 @@
 
 package org.apache.james.mailbox.cassandra.mail;
 
-import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
-import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
-import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
-import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
-import static org.apache.james.mailbox.cassandra.GhostMailbox.TYPE;
-import static 
org.apache.james.mailbox.cassandra.table.CassandraMailboxPathTable.FIELDS;
-import static 
org.apache.james.mailbox.cassandra.table.CassandraMailboxPathTable.MAILBOX_ID;
-import static 
org.apache.james.mailbox.cassandra.table.CassandraMailboxPathTable.MAILBOX_NAME;
-import static 
org.apache.james.mailbox.cassandra.table.CassandraMailboxPathTable.NAMESPACE_AND_USER;
-import static 
org.apache.james.mailbox.cassandra.table.CassandraMailboxPathTable.TABLE_NAME;
-
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.stream.Stream;
 
-import javax.inject.Inject;
-
-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.GhostMailbox;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
-import org.apache.james.mailbox.cassandra.mail.utils.MailboxBaseTupleUtil;
-import org.apache.james.mailbox.cassandra.table.CassandraMailboxTable;
 import org.apache.james.mailbox.model.MailboxPath;
 
-import com.datastax.driver.core.PreparedStatement;
-import com.datastax.driver.core.Row;
-import com.datastax.driver.core.Session;
-import com.datastax.driver.core.querybuilder.QueryBuilder;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-
-public class CassandraMailboxPathDAO {
-
-    public static class CassandraIdAndPath {
-        private final CassandraId cassandraId;
-        private final MailboxPath mailboxPath;
-
-        public CassandraIdAndPath(CassandraId cassandraId, MailboxPath 
mailboxPath) {
-            this.cassandraId = cassandraId;
-            this.mailboxPath = mailboxPath;
-        }
-
-        public CassandraId getCassandraId() {
-            return cassandraId;
-        }
-
-        public MailboxPath getMailboxPath() {
-            return mailboxPath;
-        }
-
-        @Override
-        public final boolean equals(Object o) {
-            if (o instanceof CassandraIdAndPath) {
-                CassandraIdAndPath that = (CassandraIdAndPath) o;
-
-                return Objects.equal(this.cassandraId, that.cassandraId)
-                    && Objects.equal(this.mailboxPath, that.mailboxPath);
-            }
-            return false;
-        }
-
-        @Override
-        public final int hashCode() {
-            return Objects.hashCode(cassandraId, mailboxPath);
-        }
-    }
-
-    private final CassandraAsyncExecutor cassandraAsyncExecutor;
-    private final MailboxBaseTupleUtil mailboxBaseTupleUtil;
-    private final CassandraUtils cassandraUtils;
-    private final PreparedStatement delete;
-    private final PreparedStatement insert;
-    private final PreparedStatement select;
-    private final PreparedStatement selectAll;
-
-    @Inject
-    public CassandraMailboxPathDAO(Session session, CassandraTypesProvider 
typesProvider, CassandraUtils cassandraUtils) {
-        this.cassandraAsyncExecutor = new CassandraAsyncExecutor(session);
-        this.mailboxBaseTupleUtil = new MailboxBaseTupleUtil(typesProvider);
-        this.cassandraUtils = cassandraUtils;
-        this.insert = prepareInsert(session);
-        this.delete = prepareDelete(session);
-        this.select = prepareSelect(session);
-        this.selectAll = prepareSelectAll(session);
-    }
-
-    @VisibleForTesting
-    public CassandraMailboxPathDAO(Session session, CassandraTypesProvider 
typesProvider) {
-        this(session, typesProvider, 
CassandraUtils.WITH_DEFAULT_CONFIGURATION);
-    }
-
-    private PreparedStatement prepareDelete(Session session) {
-        return session.prepare(QueryBuilder.delete()
-            .from(TABLE_NAME)
-            .where(eq(NAMESPACE_AND_USER, bindMarker(NAMESPACE_AND_USER)))
-            .and(eq(MAILBOX_NAME, bindMarker(MAILBOX_NAME))));
-    }
-
-    private PreparedStatement prepareInsert(Session session) {
-        return session.prepare(insertInto(TABLE_NAME)
-            .value(NAMESPACE_AND_USER, bindMarker(NAMESPACE_AND_USER))
-            .value(MAILBOX_NAME, bindMarker(MAILBOX_NAME))
-            .value(MAILBOX_ID, bindMarker(MAILBOX_ID))
-            .ifNotExists());
-    }
-
-    private PreparedStatement prepareSelect(Session session) {
-        return session.prepare(select(FIELDS)
-            .from(TABLE_NAME)
-            .where(eq(NAMESPACE_AND_USER, bindMarker(NAMESPACE_AND_USER)))
-            .and(eq(MAILBOX_NAME, bindMarker(MAILBOX_NAME))));
-    }
-
-    private PreparedStatement prepareSelectAll(Session session) {
-        return session.prepare(select(FIELDS)
-            .from(TABLE_NAME)
-            .where(eq(NAMESPACE_AND_USER, bindMarker(NAMESPACE_AND_USER))));
-    }
-
-    public CompletableFuture<Optional<CassandraIdAndPath>> 
retrieveId(MailboxPath mailboxPath) {
-        return cassandraAsyncExecutor.executeSingleRow(
-            select.bind()
-                .setUDTValue(NAMESPACE_AND_USER, 
mailboxBaseTupleUtil.createMailboxBaseUDT(mailboxPath.getNamespace(), 
mailboxPath.getUser()))
-                .setString(MAILBOX_NAME, mailboxPath.getName()))
-            .thenApply(rowOptional ->
-                rowOptional.map(this::fromRowToCassandraIdAndPath))
-            .thenApply(value -> logGhostMailbox(mailboxPath, value));
-    }
-
-    public CompletableFuture<Stream<CassandraIdAndPath>> 
listUserMailboxes(String namespace, String user) {
-        return cassandraAsyncExecutor.execute(
-            selectAll.bind()
-                .setUDTValue(NAMESPACE_AND_USER, 
mailboxBaseTupleUtil.createMailboxBaseUDT(namespace, user)))
-            .thenApply(resultSet -> cassandraUtils.convertToStream(resultSet)
-                .map(this::fromRowToCassandraIdAndPath)
-                .peek(this::logReadSuccess));
-    }
+public interface CassandraMailboxPathDAO {
 
-    /**
-     * See https://issues.apache.org/jira/browse/MAILBOX-322 to read about the 
Ghost mailbox bug.
-     *
-     * A missed read on an existing mailbox is the cause of the ghost mailbox 
bug. Here we log missing reads. Successful
-     * reads and write operations are also added in order to allow audit in 
order to know if the mailbox existed.
-     */
-    public Optional<CassandraIdAndPath> logGhostMailbox(MailboxPath 
mailboxPath, Optional<CassandraIdAndPath> value) {
-        if (value.isPresent()) {
-            CassandraIdAndPath cassandraIdAndPath = value.get();
-            logReadSuccess(cassandraIdAndPath);
-        } else {
-            GhostMailbox.logger()
-                .addField(GhostMailbox.MAILBOX_NAME, mailboxPath)
-                .addField(TYPE, "readMiss")
-                .log(logger -> logger.info("Read mailbox missed"));
-        }
-        return value;
-    }
+    CompletableFuture<Optional<CassandraIdAndPath>> retrieveId(MailboxPath 
mailboxPath);
 
-    /**
-     * See https://issues.apache.org/jira/browse/MAILBOX-322 to read about the 
Ghost mailbox bug.
-     *
-     * Read success allows to know if a mailbox existed before (mailbox write 
history might be older than this log introduction
-     * or log history might have been dropped)
-     */
-    private void logReadSuccess(CassandraIdAndPath cassandraIdAndPath) {
-        GhostMailbox.logger()
-            .addField(GhostMailbox.MAILBOX_NAME, 
cassandraIdAndPath.getMailboxPath())
-            .addField(TYPE, "readSuccess")
-            .addField(GhostMailbox.MAILBOX_ID, 
cassandraIdAndPath.getCassandraId())
-            .log(logger -> logger.info("Read mailbox succeeded"));
-    }
+    CompletableFuture<Stream<CassandraIdAndPath>> listUserMailboxes(String 
namespace, String user);
 
-    private CassandraIdAndPath fromRowToCassandraIdAndPath(Row row) {
-        return new CassandraIdAndPath(
-            CassandraId.of(row.getUUID(MAILBOX_ID)),
-            new 
MailboxPath(row.getUDTValue(NAMESPACE_AND_USER).getString(CassandraMailboxTable.MailboxBase.NAMESPACE),
-                
row.getUDTValue(NAMESPACE_AND_USER).getString(CassandraMailboxTable.MailboxBase.USER),
-                row.getString(MAILBOX_NAME)));
-    }
+    Optional<CassandraIdAndPath> logGhostMailbox(MailboxPath mailboxPath, 
Optional<CassandraIdAndPath> value);
 
-    public CompletableFuture<Boolean> save(MailboxPath mailboxPath, 
CassandraId mailboxId) {
-        return cassandraAsyncExecutor.executeReturnApplied(insert.bind()
-            .setUDTValue(NAMESPACE_AND_USER, 
mailboxBaseTupleUtil.createMailboxBaseUDT(mailboxPath.getNamespace(), 
mailboxPath.getUser()))
-            .setString(MAILBOX_NAME, mailboxPath.getName())
-            .setUUID(MAILBOX_ID, mailboxId.asUuid()));
-    }
+    CompletableFuture<Boolean> save(MailboxPath mailboxPath, CassandraId 
mailboxId);
 
-    public CompletableFuture<Void> delete(MailboxPath mailboxPath) {
-        return cassandraAsyncExecutor.executeVoid(delete.bind()
-            .setUDTValue(NAMESPACE_AND_USER, 
mailboxBaseTupleUtil.createMailboxBaseUDT(mailboxPath.getNamespace(), 
mailboxPath.getUser()))
-            .setString(MAILBOX_NAME, mailboxPath.getName()));
-    }
+    CompletableFuture<Void> delete(MailboxPath mailboxPath);
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/2fae24a8/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAOImpl.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAOImpl.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAOImpl.java
new file mode 100644
index 0000000..11080e2
--- /dev/null
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAOImpl.java
@@ -0,0 +1,185 @@
+/****************************************************************
+ * 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.mail;
+
+import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+import static org.apache.james.mailbox.cassandra.GhostMailbox.TYPE;
+import static 
org.apache.james.mailbox.cassandra.table.CassandraMailboxPathTable.FIELDS;
+import static 
org.apache.james.mailbox.cassandra.table.CassandraMailboxPathTable.MAILBOX_ID;
+import static 
org.apache.james.mailbox.cassandra.table.CassandraMailboxPathTable.MAILBOX_NAME;
+import static 
org.apache.james.mailbox.cassandra.table.CassandraMailboxPathTable.NAMESPACE_AND_USER;
+import static 
org.apache.james.mailbox.cassandra.table.CassandraMailboxPathTable.TABLE_NAME;
+
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Stream;
+
+import javax.inject.Inject;
+
+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.GhostMailbox;
+import org.apache.james.mailbox.cassandra.ids.CassandraId;
+import org.apache.james.mailbox.cassandra.mail.utils.MailboxBaseTupleUtil;
+import org.apache.james.mailbox.cassandra.table.CassandraMailboxTable;
+import org.apache.james.mailbox.model.MailboxPath;
+
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.querybuilder.QueryBuilder;
+import com.google.common.annotations.VisibleForTesting;
+
+public class CassandraMailboxPathDAOImpl implements CassandraMailboxPathDAO {
+
+    private final CassandraAsyncExecutor cassandraAsyncExecutor;
+    private final MailboxBaseTupleUtil mailboxBaseTupleUtil;
+    private final CassandraUtils cassandraUtils;
+    private final PreparedStatement delete;
+    private final PreparedStatement insert;
+    private final PreparedStatement select;
+    private final PreparedStatement selectAll;
+
+    @Inject
+    public CassandraMailboxPathDAOImpl(Session session, CassandraTypesProvider 
typesProvider, CassandraUtils cassandraUtils) {
+        this.cassandraAsyncExecutor = new CassandraAsyncExecutor(session);
+        this.mailboxBaseTupleUtil = new MailboxBaseTupleUtil(typesProvider);
+        this.cassandraUtils = cassandraUtils;
+        this.insert = prepareInsert(session);
+        this.delete = prepareDelete(session);
+        this.select = prepareSelect(session);
+        this.selectAll = prepareSelectAll(session);
+    }
+
+    @VisibleForTesting
+    public CassandraMailboxPathDAOImpl(Session session, CassandraTypesProvider 
typesProvider) {
+        this(session, typesProvider, 
CassandraUtils.WITH_DEFAULT_CONFIGURATION);
+    }
+
+    private PreparedStatement prepareDelete(Session session) {
+        return session.prepare(QueryBuilder.delete()
+            .from(TABLE_NAME)
+            .where(eq(NAMESPACE_AND_USER, bindMarker(NAMESPACE_AND_USER)))
+            .and(eq(MAILBOX_NAME, bindMarker(MAILBOX_NAME))));
+    }
+
+    private PreparedStatement prepareInsert(Session session) {
+        return session.prepare(insertInto(TABLE_NAME)
+            .value(NAMESPACE_AND_USER, bindMarker(NAMESPACE_AND_USER))
+            .value(MAILBOX_NAME, bindMarker(MAILBOX_NAME))
+            .value(MAILBOX_ID, bindMarker(MAILBOX_ID))
+            .ifNotExists());
+    }
+
+    private PreparedStatement prepareSelect(Session session) {
+        return session.prepare(select(FIELDS)
+            .from(TABLE_NAME)
+            .where(eq(NAMESPACE_AND_USER, bindMarker(NAMESPACE_AND_USER)))
+            .and(eq(MAILBOX_NAME, bindMarker(MAILBOX_NAME))));
+    }
+
+    private PreparedStatement prepareSelectAll(Session session) {
+        return session.prepare(select(FIELDS)
+            .from(TABLE_NAME)
+            .where(eq(NAMESPACE_AND_USER, bindMarker(NAMESPACE_AND_USER))));
+    }
+
+    public CompletableFuture<Optional<CassandraIdAndPath>> 
retrieveId(MailboxPath mailboxPath) {
+        return cassandraAsyncExecutor.executeSingleRow(
+            select.bind()
+                .setUDTValue(NAMESPACE_AND_USER, 
mailboxBaseTupleUtil.createMailboxBaseUDT(mailboxPath.getNamespace(), 
mailboxPath.getUser()))
+                .setString(MAILBOX_NAME, mailboxPath.getName()))
+            .thenApply(rowOptional ->
+                rowOptional.map(this::fromRowToCassandraIdAndPath))
+            .thenApply(value -> logGhostMailbox(mailboxPath, value));
+    }
+
+    @Override
+    public CompletableFuture<Stream<CassandraIdAndPath>> 
listUserMailboxes(String namespace, String user) {
+        return cassandraAsyncExecutor.execute(
+            selectAll.bind()
+                .setUDTValue(NAMESPACE_AND_USER, 
mailboxBaseTupleUtil.createMailboxBaseUDT(namespace, user)))
+            .thenApply(resultSet -> cassandraUtils.convertToStream(resultSet)
+                .map(this::fromRowToCassandraIdAndPath)
+                .peek(this::logReadSuccess));
+    }
+
+    /**
+     * See https://issues.apache.org/jira/browse/MAILBOX-322 to read about the 
Ghost mailbox bug.
+     *
+     * A missed read on an existing mailbox is the cause of the ghost mailbox 
bug. Here we log missing reads. Successful
+     * reads and write operations are also added in order to allow audit in 
order to know if the mailbox existed.
+     */
+    @Override
+    public Optional<CassandraIdAndPath> logGhostMailbox(MailboxPath 
mailboxPath, Optional<CassandraIdAndPath> value) {
+        if (value.isPresent()) {
+            CassandraIdAndPath cassandraIdAndPath = value.get();
+            logReadSuccess(cassandraIdAndPath);
+        } else {
+            GhostMailbox.logger()
+                .addField(GhostMailbox.MAILBOX_NAME, mailboxPath)
+                .addField(TYPE, "readMiss")
+                .log(logger -> logger.info("Read mailbox missed"));
+        }
+        return value;
+    }
+
+    /**
+     * See https://issues.apache.org/jira/browse/MAILBOX-322 to read about the 
Ghost mailbox bug.
+     *
+     * Read success allows to know if a mailbox existed before (mailbox write 
history might be older than this log introduction
+     * or log history might have been dropped)
+     */
+    private void logReadSuccess(CassandraIdAndPath cassandraIdAndPath) {
+        GhostMailbox.logger()
+            .addField(GhostMailbox.MAILBOX_NAME, 
cassandraIdAndPath.getMailboxPath())
+            .addField(TYPE, "readSuccess")
+            .addField(GhostMailbox.MAILBOX_ID, 
cassandraIdAndPath.getCassandraId())
+            .log(logger -> logger.info("Read mailbox succeeded"));
+    }
+
+    private CassandraIdAndPath fromRowToCassandraIdAndPath(Row row) {
+        return new CassandraIdAndPath(
+            CassandraId.of(row.getUUID(MAILBOX_ID)),
+            new 
MailboxPath(row.getUDTValue(NAMESPACE_AND_USER).getString(CassandraMailboxTable.MailboxBase.NAMESPACE),
+                
row.getUDTValue(NAMESPACE_AND_USER).getString(CassandraMailboxTable.MailboxBase.USER),
+                row.getString(MAILBOX_NAME)));
+    }
+
+    @Override
+    public CompletableFuture<Boolean> save(MailboxPath mailboxPath, 
CassandraId mailboxId) {
+        return cassandraAsyncExecutor.executeReturnApplied(insert.bind()
+            .setUDTValue(NAMESPACE_AND_USER, 
mailboxBaseTupleUtil.createMailboxBaseUDT(mailboxPath.getNamespace(), 
mailboxPath.getUser()))
+            .setString(MAILBOX_NAME, mailboxPath.getName())
+            .setUUID(MAILBOX_ID, mailboxId.asUuid()));
+    }
+
+    @Override
+    public CompletableFuture<Void> delete(MailboxPath mailboxPath) {
+        return cassandraAsyncExecutor.executeVoid(delete.bind()
+            .setUDTValue(NAMESPACE_AND_USER, 
mailboxBaseTupleUtil.createMailboxBaseUDT(mailboxPath.getNamespace(), 
mailboxPath.getUser()))
+            .setString(MAILBOX_NAME, mailboxPath.getName()));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/2fae24a8/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManagerTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManagerTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManagerTest.java
index 1222958..29ec40f 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManagerTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManagerTest.java
@@ -37,7 +37,7 @@ import 
org.apache.james.mailbox.cassandra.mail.CassandraDeletedMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraFirstUnseenDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxCounterDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
-import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAOImpl;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
@@ -88,7 +88,7 @@ public class CassandraSubscriptionManagerTest extends 
AbstractSubscriptionManage
         CassandraMailboxCounterDAO mailboxCounterDAO = null;
         CassandraMailboxRecentsDAO mailboxRecentsDAO = null;
         CassandraMailboxDAO mailboxDAO = null;
-        CassandraMailboxPathDAO mailboxPathDAO = null;
+        CassandraMailboxPathDAOImpl mailboxPathDAO = null;
         CassandraFirstUnseenDAO firstUnseenDAO = null;
         CassandraApplicableFlagDAO applicableFlagDAO = null;
         CassandraAttachmentDAO attachmentDAO = null;

http://git-wip-us.apache.org/repos/asf/james-project/blob/2fae24a8/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
index ec7ac05..d26350a 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
@@ -35,7 +35,7 @@ import 
org.apache.james.mailbox.cassandra.mail.CassandraDeletedMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraFirstUnseenDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxCounterDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
-import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAOImpl;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
@@ -70,7 +70,7 @@ public class TestCassandraMailboxSessionMapperFactory {
             new CassandraMailboxCounterDAO(session),
             new CassandraMailboxRecentsDAO(session),
             new CassandraMailboxDAO(session, typesProvider),
-            new CassandraMailboxPathDAO(session, typesProvider),
+            new CassandraMailboxPathDAOImpl(session, typesProvider),
             new CassandraFirstUnseenDAO(session),
             new CassandraApplicableFlagDAO(session),
             new CassandraAttachmentDAO(session, utils, cassandraConfiguration),

http://git-wip-us.apache.org/repos/asf/james-project/blob/2fae24a8/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperConcurrencyTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperConcurrencyTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperConcurrencyTest.java
index 6d7822b..3d2bd73 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperConcurrencyTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperConcurrencyTest.java
@@ -57,7 +57,7 @@ public class CassandraMailboxMapperConcurrencyTest {
         CassandraModuleComposite modules = new CassandraModuleComposite(new 
CassandraMailboxModule(), new CassandraAclModule());
         cassandra = CassandraCluster.create(modules, cassandraServer.getIp(), 
cassandraServer.getBindingPort());
         CassandraMailboxDAO mailboxDAO = new 
CassandraMailboxDAO(cassandra.getConf(), cassandra.getTypesProvider());
-        CassandraMailboxPathDAO mailboxPathDAO = new 
CassandraMailboxPathDAO(cassandra.getConf(), cassandra.getTypesProvider());
+        CassandraMailboxPathDAOImpl mailboxPathDAO = new 
CassandraMailboxPathDAOImpl(cassandra.getConf(), cassandra.getTypesProvider());
         CassandraUserMailboxRightsDAO userMailboxRightsDAO = new 
CassandraUserMailboxRightsDAO(cassandra.getConf(), 
CassandraUtils.WITH_DEFAULT_CONFIGURATION);
         testee = new CassandraMailboxMapper(
             mailboxDAO,

http://git-wip-us.apache.org/repos/asf/james-project/blob/2fae24a8/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
index e761b7e..350c523 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
@@ -47,7 +47,7 @@ public class CassandraMailboxMapperTest {
     @ClassRule public static DockerCassandraRule cassandraServer = new 
DockerCassandraRule();
     
     private CassandraCluster cassandra;
-    private CassandraMailboxPathDAO mailboxPathDAO;
+    private CassandraMailboxPathDAOImpl mailboxPathDAO;
     private CassandraMailboxMapper testee;
 
     @Before
@@ -55,7 +55,7 @@ public class CassandraMailboxMapperTest {
         CassandraModuleComposite modules = new CassandraModuleComposite(new 
CassandraMailboxModule(), new CassandraAclModule());
         cassandra = CassandraCluster.create(modules, cassandraServer.getIp(), 
cassandraServer.getBindingPort());
         CassandraMailboxDAO mailboxDAO = new 
CassandraMailboxDAO(cassandra.getConf(), cassandra.getTypesProvider());
-        mailboxPathDAO = new CassandraMailboxPathDAO(cassandra.getConf(), 
cassandra.getTypesProvider());
+        mailboxPathDAO = new CassandraMailboxPathDAOImpl(cassandra.getConf(), 
cassandra.getTypesProvider());
         CassandraUserMailboxRightsDAO userMailboxRightsDAO = new 
CassandraUserMailboxRightsDAO(cassandra.getConf(), 
CassandraUtils.WITH_DEFAULT_CONFIGURATION);
         testee = new CassandraMailboxMapper(
             mailboxDAO,

http://git-wip-us.apache.org/repos/asf/james-project/blob/2fae24a8/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAOImplTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAOImplTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAOImplTest.java
new file mode 100644
index 0000000..c532bd7
--- /dev/null
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAOImplTest.java
@@ -0,0 +1,28 @@
+/****************************************************************
+ * 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.mail;
+
+public class CassandraMailboxPathDAOImplTest extends 
CassandraMailboxPathDAOTest {
+
+    @Override
+    CassandraMailboxPathDAO testee() {
+        return new CassandraMailboxPathDAOImpl(cassandra.getConf(), 
cassandra.getTypesProvider());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/2fae24a8/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAOTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAOTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAOTest.java
index ce79b44..a88f1d6 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAOTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathDAOTest.java
@@ -26,7 +26,6 @@ import java.util.List;
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
-import 
org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAO.CassandraIdAndPath;
 import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.junit.After;
@@ -38,7 +37,7 @@ import com.github.steveash.guavate.Guavate;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
 
-public class CassandraMailboxPathDAOTest {
+public abstract class CassandraMailboxPathDAOTest {
     private static final String USER = "user";
     private static final String OTHER_USER = "other";
     private static final CassandraId INBOX_ID = CassandraId.timeBased();
@@ -52,14 +51,15 @@ public class CassandraMailboxPathDAOTest {
 
     @ClassRule public static DockerCassandraRule cassandraServer = new 
DockerCassandraRule();
     
-    private CassandraCluster cassandra;
+    protected CassandraCluster cassandra;
 
     private CassandraMailboxPathDAO testee;
+    abstract CassandraMailboxPathDAO testee();
 
     @Before
     public void setUp() throws Exception {
         cassandra = CassandraCluster.create(new CassandraMailboxModule(), 
cassandraServer.getIp(), cassandraServer.getBindingPort());
-        testee = new CassandraMailboxPathDAO(cassandra.getConf(), 
cassandra.getTypesProvider());
+        testee = testee();
 
     }
 
@@ -70,7 +70,7 @@ public class CassandraMailboxPathDAOTest {
 
     @Test
     public void cassandraIdAndPathShouldRespectBeanContract() {
-        
EqualsVerifier.forClass(CassandraMailboxPathDAO.CassandraIdAndPath.class).verify();
+        EqualsVerifier.forClass(CassandraIdAndPath.class).verify();
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/james-project/blob/2fae24a8/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
index 69a44fc..f63ba6d 100644
--- 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
+++ 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
@@ -46,7 +46,7 @@ import 
org.apache.james.mailbox.cassandra.mail.CassandraFirstUnseenDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxCounterDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxMapper;
-import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAO;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAOImpl;
 import org.apache.james.mailbox.cassandra.mail.CassandraMailboxRecentsDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
@@ -103,7 +103,7 @@ public class CassandraMailboxModule extends AbstractModule {
         bind(CassandraFirstUnseenDAO.class).in(Scopes.SINGLETON);
         bind(CassandraMailboxCounterDAO.class).in(Scopes.SINGLETON);
         bind(CassandraMailboxDAO.class).in(Scopes.SINGLETON);
-        bind(CassandraMailboxPathDAO.class).in(Scopes.SINGLETON);
+        bind(CassandraMailboxPathDAOImpl.class).in(Scopes.SINGLETON);
         bind(CassandraMailboxRecentsDAO.class).in(Scopes.SINGLETON);
         bind(CassandraMessageDAO.class).in(Scopes.SINGLETON);
         bind(CassandraMessageIdDAO.class).in(Scopes.SINGLETON);


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

Reply via email to