MAILBOX-322 Add logging upon mailbox read
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/eeca3b56 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/eeca3b56 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/eeca3b56 Branch: refs/heads/master Commit: eeca3b563e32136bcffd05cab67bfcd1b32d17f2 Parents: dd2ef3a Author: benwa <btell...@linagora.com> Authored: Fri Dec 15 09:52:14 2017 +0700 Committer: Antoine Duprat <adup...@linagora.com> Committed: Fri Dec 15 16:45:43 2017 +0100 ---------------------------------------------------------------------- .../cassandra/mail/CassandraMailboxPathDAO.java | 44 ++++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/eeca3b56/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 f6eb674..8a06811 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 @@ -23,6 +23,7 @@ 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; @@ -38,6 +39,7 @@ 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; @@ -144,16 +146,50 @@ public class CassandraMailboxPathDAO { .setUDTValue(NAMESPACE_AND_USER, mailboxBaseTupleUtil.createMailboxBaseUDT(mailboxPath.getNamespace(), mailboxPath.getUser())) .setString(MAILBOX_NAME, mailboxPath.getName())) .thenApply(rowOptional -> - rowOptional.map(row -> new CassandraIdAndPath( - CassandraId.of(row.getUUID(MAILBOX_ID)), - mailboxPath))); + 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)); + .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. + */ + 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) { --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org