You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ma...@apache.org on 2017/08/17 11:16:56 UTC

[01/10] james-project git commit: JAMES-2122 Adding a log on swallowed expunge

Repository: james-project
Updated Branches:
  refs/heads/master 67e44d268 -> 6bd459a86


JAMES-2122 Adding a log on swallowed expunge

This makes us aware of some denormalisation issues


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

Branch: refs/heads/master
Commit: a27e73a2e83429bb4203e40e0be7cff96caaeb57
Parents: 67e44d2
Author: benwa <bt...@linagora.com>
Authored: Thu Aug 17 09:42:35 2017 +0700
Committer: Matthieu Baechler <ma...@apache.org>
Committed: Thu Aug 17 13:12:31 2017 +0200

----------------------------------------------------------------------
 .../cassandra/mail/CassandraMessageMapper.java       | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/a27e73a2/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
index e782127..eda305b 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
@@ -39,9 +39,9 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
-import org.apache.james.mailbox.cassandra.mail.utils.Limit;
 import org.apache.james.mailbox.cassandra.mail.migration.V1ToV2Migration;
 import org.apache.james.mailbox.cassandra.mail.utils.FlagsUpdateStageResult;
+import org.apache.james.mailbox.cassandra.mail.utils.Limit;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
@@ -196,8 +196,6 @@ public class CassandraMessageMapper implements MessageMapper {
             .thenCompose(stream -> attachmentLoader.addAttachmentToMessages(stream, fetchType));
     }
 
-
-
     @Override
     public List<MessageUid> findRecentMessageUidsInMailbox(Mailbox mailbox) throws MailboxException {
         CassandraId mailboxId = (CassandraId) mailbox.getMailboxId();
@@ -228,13 +226,22 @@ public class CassandraMessageMapper implements MessageMapper {
 
     private CompletableFuture<Stream<SimpleMailboxMessage>> expungeUidChunk(CassandraId mailboxId, Collection<MessageUid> uidChunk) {
         return FluentFutureStream.ofOptionals(
-                uidChunk.stream().map(uid -> messageIdDAO.retrieve(mailboxId, uid)))
+                uidChunk.stream().map(uid -> retrieveComposedId(mailboxId, uid)))
             .performOnAll(this::deleteUsingMailboxId)
             .thenFlatCompose(idWithMetadata -> retrieveMessagesAndDoMigrationIfNeeded(ImmutableList.of(idWithMetadata), FetchType.Metadata, Limit.unlimited()))
             .map(pair -> pair.getKey().toMailboxMessage(ImmutableList.of()))
             .completableFuture();
     }
 
+    private CompletableFuture<Optional<ComposedMessageIdWithMetaData>> retrieveComposedId(CassandraId mailboxId, MessageUid uid) {
+        return messageIdDAO.retrieve(mailboxId, uid)
+            .thenApply(value -> Optional.of(value)
+            .orElseGet(() -> {
+                LOGGER.warn("Could not retrieve message {} {}", mailboxId, uid);
+                return Optional.empty();
+            }));
+    }
+
     private CompletableFuture<Stream<Pair<MessageWithoutAttachment, Stream<MessageAttachmentRepresentation>>>> retrieveMessagesAndDoMigrationIfNeeded(
         List<ComposedMessageIdWithMetaData> messageIds, FetchType fetchType, Limit limit) {
 


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


[03/10] james-project git commit: JAMES-2122 Adding a log on users password testing

Posted by ma...@apache.org.
JAMES-2122 Adding a log on users password testing


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

Branch: refs/heads/master
Commit: aa5cefdc27b0d34d19ad91ab6c6171e870f99324
Parents: 8c2eddf
Author: benwa <bt...@linagora.com>
Authored: Thu Aug 17 10:19:58 2017 +0700
Committer: Matthieu Baechler <ma...@apache.org>
Committed: Thu Aug 17 13:13:33 2017 +0200

----------------------------------------------------------------------
 .../james/user/cassandra/CassandraUsersRepository.java       | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/aa5cefdc/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepository.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepository.java b/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepository.java
index 028accb..0a5b025 100644
--- a/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepository.java
+++ b/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepository.java
@@ -45,6 +45,8 @@ import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.user.api.model.User;
 import org.apache.james.user.lib.AbstractUsersRepository;
 import org.apache.james.user.lib.model.DefaultUser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.datastax.driver.core.PreparedStatement;
 import com.datastax.driver.core.ResultSet;
@@ -55,6 +57,7 @@ import com.google.common.primitives.Ints;
 public class CassandraUsersRepository extends AbstractUsersRepository {
 
     private static final String DEFAULT_ALGO_VALUE = "SHA1";
+    private static final Logger LOGGER = LoggerFactory.getLogger(CassandraUsersRepository.class);
 
     private final CassandraAsyncExecutor executor;
     private final CassandraUtils cassandraUtils;
@@ -162,7 +165,10 @@ public class CassandraUsersRepository extends AbstractUsersRepository {
     public boolean test(String name, String password) throws UsersRepositoryException {
         return Optional.ofNullable(getUserByName(name))
                 .map(x -> x.verifyPassword(password))
-                .orElse(false);
+            .orElseGet(() -> {
+                LOGGER.info("Could not retrieve user {}. Authentication failure.");
+                return false;
+            });
     }
 
     @Override


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


[10/10] james-project git commit: Merge branch 'PR-936'

Posted by ma...@apache.org.
Merge branch 'PR-936'


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

Branch: refs/heads/master
Commit: 6bd459a863888929c2c2b02656d76cda95249e1b
Parents: 0624ab2 00a554b
Author: Matthieu Baechler <ma...@apache.org>
Authored: Thu Aug 17 13:14:32 2017 +0200
Committer: Matthieu Baechler <ma...@apache.org>
Committed: Thu Aug 17 13:14:32 2017 +0200

----------------------------------------------------------------------
 .../org/apache/james/user/cassandra/CassandraUsersRepository.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------



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


[07/10] james-project git commit: JAMES-2122 Adding a log on swallowed blobs

Posted by ma...@apache.org.
JAMES-2122 Adding a log on swallowed blobs


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

Branch: refs/heads/master
Commit: 8c2eddf9402de6002d210a37b2333a3a04f79768
Parents: 9507ba7
Author: benwa <bt...@linagora.com>
Authored: Thu Aug 17 10:19:20 2017 +0700
Committer: Matthieu Baechler <ma...@apache.org>
Committed: Thu Aug 17 13:13:33 2017 +0200

----------------------------------------------------------------------
 .../cassandra/mail/CassandraBlobsDAO.java       | 47 +++++++++++++++-----
 1 file changed, 36 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/8c2eddf9/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 f6e3d21..819d427 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
@@ -41,16 +41,20 @@ import org.apache.james.mailbox.cassandra.table.BlobTable;
 import org.apache.james.mailbox.cassandra.table.BlobTable.BlobParts;
 import org.apache.james.util.FluentFutureStream;
 import org.apache.james.util.OptionalConverter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.datastax.driver.core.PreparedStatement;
 import com.datastax.driver.core.Row;
 import com.datastax.driver.core.Session;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.primitives.Bytes;
 
 public class CassandraBlobsDAO {
+    private static final Logger LOGGER = LoggerFactory.getLogger(CassandraBlobsDAO.class);
     private final CassandraAsyncExecutor cassandraAsyncExecutor;
     private final PreparedStatement insert;
     private final PreparedStatement insertPart;
@@ -113,7 +117,7 @@ public class CassandraBlobsDAO {
     }
 
     private CompletableFuture<Integer> saveBlobParts(byte[] data, BlobId blobId) {
-        return FluentFutureStream.<Pair<Integer, Void>> of(
+        return FluentFutureStream.of(
             dataChunker.chunk(data, configuration.getBlobPartSize())
                 .map(pair -> writePart(pair.getRight(), blobId, pair.getKey())
                     .thenApply(partId -> Pair.of(pair.getKey(), partId))))
@@ -146,23 +150,29 @@ public class CassandraBlobsDAO {
         return cassandraAsyncExecutor.executeSingleRow(
             select.bind()
                 .setString(BlobTable.ID, blobId.getId()))
-            .thenCompose(this::toDataParts)
+            .thenCompose(row -> toDataParts(row, blobId))
             .thenApply(this::concatenateDataParts);
     }
 
-    private CompletableFuture<Stream<Optional<Row>>> toDataParts(Optional<Row> blobRowOptional) {
+    private CompletableFuture<Stream<BlobPart>> toDataParts(Optional<Row> blobRowOptional, BlobId blobId) {
         return blobRowOptional.map(blobRow -> {
-            BlobId blobId = BlobId.from(blobRow.getString(BlobTable.ID));
             int numOfChunk = blobRow.getInt(BlobTable.NUMBER_OF_CHUNK);
             return FluentFutureStream.of(
                 IntStream.range(0, numOfChunk)
                     .mapToObj(position -> readPart(blobId, position)))
                 .completableFuture();
-        }).orElse(CompletableFuture.completedFuture(Stream.empty()));
-    }
-
-    private byte[] concatenateDataParts(Stream<Optional<Row>> rows) {
-        ImmutableList<byte[]> parts = rows.flatMap(OptionalConverter::toStream)
+        }).orElseGet(() -> {
+            LOGGER.warn("Could not retrieve blob metadata for {}", blobId);
+            return CompletableFuture.completedFuture(Stream.empty());
+        });
+    }
+
+    private byte[] concatenateDataParts(Stream<BlobPart> blobParts) {
+        ImmutableList<byte[]> parts = blobParts
+            .map(blobPart -> OptionalConverter.ifEmpty(
+                blobPart.row,
+                () -> LOGGER.warn("Missing blob part for blobId {} and position {}", blobPart.blobId, blobPart.position)))
+            .flatMap(OptionalConverter::toStream)
             .map(this::rowToData)
             .collect(Guavate.toImmutableList());
 
@@ -175,10 +185,25 @@ public class CassandraBlobsDAO {
         return data;
     }
 
-    private CompletableFuture<Optional<Row>> readPart(BlobId blobId, int position) {
+    private CompletableFuture<BlobPart> readPart(BlobId blobId, int position) {
         return cassandraAsyncExecutor.executeSingleRow(
             selectPart.bind()
                 .setString(BlobTable.ID, blobId.getId())
-                .setInt(BlobParts.CHUNK_NUMBER, position));
+                .setInt(BlobParts.CHUNK_NUMBER, position))
+            .thenApply(row -> new BlobPart(blobId, position, row));
+    }
+
+    private static class BlobPart {
+        private final BlobId blobId;
+        private final int position;
+        private final Optional<Row> row;
+
+        public BlobPart(BlobId blobId, int position, Optional<Row> row) {
+            Preconditions.checkNotNull(blobId);
+            Preconditions.checkArgument(position >= 0, "position need to be positive");
+            this.blobId = blobId;
+            this.position = position;
+            this.row = row;
+        }
     }
 }


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


[06/10] james-project git commit: JAMES-2122 ElasticSearchSearcher should rely on OptionalConverter

Posted by ma...@apache.org.
JAMES-2122 ElasticSearchSearcher should rely on OptionalConverter


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

Branch: refs/heads/master
Commit: 8061849b564de1919819744da36bfef3dc588097
Parents: bc50d81
Author: benwa <bt...@linagora.com>
Authored: Thu Aug 17 10:27:31 2017 +0700
Committer: Matthieu Baechler <ma...@apache.org>
Committed: Thu Aug 17 13:13:33 2017 +0200

----------------------------------------------------------------------
 .../mailbox/elasticsearch/search/ElasticSearchSearcher.java  | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/8061849b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
----------------------------------------------------------------------
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
index 1599559..726980c 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
@@ -38,6 +38,7 @@ import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MultimailboxesSearchQuery;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
+import org.apache.james.util.OptionalConverter;
 import org.elasticsearch.action.search.SearchRequestBuilder;
 import org.elasticsearch.action.search.SearchResponse;
 import org.elasticsearch.client.Client;
@@ -112,7 +113,8 @@ public class ElasticSearchSearcher {
         if (mailboxId != null && uid != null) {
             Number uidAsNumber = uid.getValue();
             return Optional.of(
-                new MessageSearchIndex.SearchResult(toGuava(id.map(field -> messageIdFactory.fromString(field.getValue()))),
+                new MessageSearchIndex.SearchResult(
+                    OptionalConverter.toGuava(id.map(field -> messageIdFactory.fromString(field.getValue()))),
                     mailboxIdFactory.fromString(mailboxId.getValue()),
                     MessageUid.of(uidAsNumber.longValue())));
         } else {
@@ -129,8 +131,4 @@ public class ElasticSearchSearcher {
         }
     }
 
-    private <T> com.google.common.base.Optional<T> toGuava(Optional<T> optional) {
-        return com.google.common.base.Optional.fromNullable(optional.orElse(null));
-    }
-
 }


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


[02/10] james-project git commit: JAMES-2122 Adding a log on Cassandra cluster fallback

Posted by ma...@apache.org.
JAMES-2122 Adding a log on Cassandra cluster fallback


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

Branch: refs/heads/master
Commit: bc50d81afd4eec1dbd9246060b5b6822005b5340
Parents: aa5cefd
Author: benwa <bt...@linagora.com>
Authored: Thu Aug 17 10:25:55 2017 +0700
Committer: Matthieu Baechler <ma...@apache.org>
Committed: Thu Aug 17 13:13:33 2017 +0200

----------------------------------------------------------------------
 .../james/backends/cassandra/init/ClusterBuilder.java | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/bc50d81a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterBuilder.java
----------------------------------------------------------------------
diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterBuilder.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterBuilder.java
index 4641ac0..18e8749 100644
--- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterBuilder.java
+++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterBuilder.java
@@ -23,6 +23,8 @@ import java.util.Collection;
 import java.util.Optional;
 
 import org.apache.james.util.Host;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.datastax.driver.core.Cluster;
 import com.datastax.driver.core.PoolingOptions;
@@ -32,7 +34,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
 public class ClusterBuilder {
-
+    private static final Logger LOGGER = LoggerFactory.getLogger(ClusterBuilder.class);
     private final static String DEFAULT_CLUSTER_IP = "localhost";
     public static final int DEFAULT_CASSANDRA_PORT = 9042;
 
@@ -189,8 +191,14 @@ public class ClusterBuilder {
     }
 
     private Collection<Host> getServersFromHostAndPort() {
-        String host = this.host.orElse(DEFAULT_CLUSTER_IP);
-        int port = this.port.orElse(DEFAULT_CASSANDRA_PORT);
+        String host = this.host.orElseGet(() -> {
+            LOGGER.info("No cassandra host specified. Falling back to {}", DEFAULT_CLUSTER_IP);
+            return DEFAULT_CLUSTER_IP;
+        });
+        int port = this.port.orElseGet(() -> {
+            LOGGER.info("No cassandra port specified. Falling back to {}", DEFAULT_CASSANDRA_PORT);
+            return DEFAULT_CASSANDRA_PORT;
+        });
 
         return ImmutableList.of(Host.from(host, port));
     }


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


[04/10] james-project git commit: JAMES-2122 Adding a log on swallowed mailboxes

Posted by ma...@apache.org.
JAMES-2122 Adding a log on swallowed mailboxes


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

Branch: refs/heads/master
Commit: 9507ba73787c4092c579e803d8bb609c6e9ead31
Parents: a27e73a
Author: benwa <bt...@linagora.com>
Authored: Thu Aug 17 10:01:25 2017 +0700
Committer: Matthieu Baechler <ma...@apache.org>
Committed: Thu Aug 17 13:13:33 2017 +0200

----------------------------------------------------------------------
 .../cassandra/mail/CassandraMailboxMapper.java  | 13 ++++++--
 .../cassandra/mail/CassandraMessageMapper.java  |  8 ++---
 .../apache/james/util/OptionalConverter.java    | 12 +++++++
 .../james/util/OptionalConverterTest.java       | 34 ++++++++++++++++++++
 4 files changed, 60 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/9507ba73/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 229ce05..13feba8 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
@@ -46,6 +46,9 @@ import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
 import org.apache.james.util.CompletableFutureUtil;
 import org.apache.james.util.FluentFutureStream;
+import org.apache.james.util.OptionalConverter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.datastax.driver.core.Session;
 import com.datastax.driver.core.exceptions.InvalidQueryException;
@@ -57,6 +60,7 @@ public class CassandraMailboxMapper implements MailboxMapper {
     public static final String WILDCARD = "%";
     public static final String VALUES_MAY_NOT_BE_LARGER_THAN_64_K = "Index expression values may not be larger than 64K";
     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 CassandraAsyncExecutor cassandraAsyncExecutor;
     private final CassandraMailboxPathDAO mailboxPathDAO;
@@ -117,12 +121,17 @@ public class CassandraMailboxMapper implements MailboxMapper {
 
         return FluentFutureStream.of(mailboxPathDAO.listUserMailboxes(path.getNamespace(), path.getUser()))
             .filter(idAndPath -> regex.matcher(idAndPath.getMailboxPath().getName()).matches())
-            .map(CassandraMailboxPathDAO.CassandraIdAndPath::getCassandraId)
-            .thenFlatComposeOnOptional(mailboxDAO::retrieveMailbox)
+            .thenFlatComposeOnOptional(this::retrieveMailbox)
             .join()
             .collect(Guavate.toImmutableList());
     }
 
+    private CompletableFuture<Optional<SimpleMailbox>> retrieveMailbox(CassandraMailboxPathDAO.CassandraIdAndPath idAndPath) {
+        return mailboxDAO.retrieveMailbox(idAndPath.getCassandraId())
+            .thenApply(optional -> OptionalConverter.ifEmpty(optional,
+                () -> LOGGER.warn("Could not retrieve mailbox {} with path {} in mailbox table.", idAndPath.getCassandraId(), idAndPath.getMailboxPath())));
+    }
+
     @Override
     public MailboxId save(Mailbox mailbox) throws MailboxException {
         Preconditions.checkArgument(mailbox instanceof SimpleMailbox);

http://git-wip-us.apache.org/repos/asf/james-project/blob/9507ba73/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
index eda305b..7236567 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
@@ -56,6 +56,7 @@ import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
 import org.apache.james.util.FluentFutureStream;
+import org.apache.james.util.OptionalConverter;
 import org.apache.james.util.streams.JamesCollectors;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -235,11 +236,8 @@ public class CassandraMessageMapper implements MessageMapper {
 
     private CompletableFuture<Optional<ComposedMessageIdWithMetaData>> retrieveComposedId(CassandraId mailboxId, MessageUid uid) {
         return messageIdDAO.retrieve(mailboxId, uid)
-            .thenApply(value -> Optional.of(value)
-            .orElseGet(() -> {
-                LOGGER.warn("Could not retrieve message {} {}", mailboxId, uid);
-                return Optional.empty();
-            }));
+            .thenApply(optional -> OptionalConverter.ifEmpty(optional,
+                () -> LOGGER.warn("Could not retrieve message {} {}", mailboxId, uid)));
     }
 
     private CompletableFuture<Stream<Pair<MessageWithoutAttachment, Stream<MessageAttachmentRepresentation>>>> retrieveMessagesAndDoMigrationIfNeeded(

http://git-wip-us.apache.org/repos/asf/james-project/blob/9507ba73/server/container/util-java8/src/main/java/org/apache/james/util/OptionalConverter.java
----------------------------------------------------------------------
diff --git a/server/container/util-java8/src/main/java/org/apache/james/util/OptionalConverter.java b/server/container/util-java8/src/main/java/org/apache/james/util/OptionalConverter.java
index fafec7a..5150be1 100644
--- a/server/container/util-java8/src/main/java/org/apache/james/util/OptionalConverter.java
+++ b/server/container/util-java8/src/main/java/org/apache/james/util/OptionalConverter.java
@@ -23,6 +23,18 @@ import java.util.stream.Stream;
 
 public class OptionalConverter {
 
+    @FunctionalInterface
+    public interface Operation {
+        void perform();
+    }
+
+    public static <T> Optional<T> ifEmpty(Optional<T> optional, Operation operation) {
+        if (!optional.isPresent()) {
+            operation.perform();
+        }
+        return optional;
+    }
+
     public static <T> Optional<T> fromGuava(com.google.common.base.Optional<T> guava) {
         return Optional.ofNullable(guava.orNull());
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/9507ba73/server/container/util-java8/src/test/java/org/apache/james/util/OptionalConverterTest.java
----------------------------------------------------------------------
diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/OptionalConverterTest.java b/server/container/util-java8/src/test/java/org/apache/james/util/OptionalConverterTest.java
index baa3aa0..000ea2c 100644
--- a/server/container/util-java8/src/test/java/org/apache/james/util/OptionalConverterTest.java
+++ b/server/container/util-java8/src/test/java/org/apache/james/util/OptionalConverterTest.java
@@ -21,6 +21,7 @@ package org.apache.james.util;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.util.Optional;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.junit.Rule;
 import org.junit.Test;
@@ -34,6 +35,39 @@ public class OptionalConverterTest {
     public ExpectedException expectedException = ExpectedException.none();
 
     @Test
+    public void ifEmptyShouldPreserveValueOfEmptyOptionals() {
+        Optional<Object> expected = OptionalConverter.ifEmpty(Optional.empty(), () -> { });
+
+        assertThat(expected).isEmpty();
+    }
+
+    @Test
+    public void ifEmptyShouldPreserveValueOfPresentOptionals() {
+        String value = "value";
+        Optional<String> expected = OptionalConverter.ifEmpty(Optional.of(value), () -> { });
+
+        assertThat(expected).contains(value);
+    }
+
+    @Test
+    public void ifEmptyShouldPerformOperationIfEmpty() {
+        AtomicInteger operationCounter = new AtomicInteger(0);
+
+        OptionalConverter.ifEmpty(Optional.empty(), operationCounter::incrementAndGet);
+
+        assertThat(operationCounter.get()).isEqualTo(1);
+    }
+
+    @Test
+    public void ifEmptyShouldNotPerformOperationIfPresent() {
+        AtomicInteger operationCounter = new AtomicInteger(0);
+
+        OptionalConverter.ifEmpty(Optional.of("value"), operationCounter::incrementAndGet);
+
+        assertThat(operationCounter.get()).isEqualTo(0);
+    }
+
+    @Test
     public void toStreamShouldConvertEmptyOptionalToEmptyStream() {
         assertThat(
             OptionalConverter.toStream(Optional.empty())


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


[05/10] james-project git commit: JAMES-2122 Emit warning log on swallowed Cassandra attachment

Posted by ma...@apache.org.
JAMES-2122 Emit warning log on swallowed Cassandra attachment


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

Branch: refs/heads/master
Commit: 40c9816836e5f2eababc887cb16e2c5dbfbcd2b4
Parents: 8061849
Author: benwa <bt...@linagora.com>
Authored: Thu Aug 17 10:38:38 2017 +0700
Committer: Matthieu Baechler <ma...@apache.org>
Committed: Thu Aug 17 13:13:33 2017 +0200

----------------------------------------------------------------------
 .../mailbox/cassandra/mail/CassandraAttachmentMapper.java | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/40c98168/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
index e121cc6..6c15999 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
@@ -39,7 +39,6 @@ import java.util.stream.Stream;
 
 import javax.inject.Inject;
 
-import org.apache.commons.io.IOUtils;
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
@@ -47,6 +46,9 @@ import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.util.FluentFutureStream;
+import org.apache.james.util.OptionalConverter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.datastax.driver.core.Row;
 import com.datastax.driver.core.Session;
@@ -54,10 +56,10 @@ import com.github.fge.lambdas.Throwing;
 import com.github.fge.lambdas.ThrownByLambdaException;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Preconditions;
-import org.apache.james.util.OptionalConverter;
 
 public class CassandraAttachmentMapper implements AttachmentMapper {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(CassandraAttachmentMapper.class);
     private final CassandraAsyncExecutor cassandraAsyncExecutor;
 
     @Inject
@@ -123,7 +125,9 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
                 .from(TABLE_NAME)
                 .where(eq(ID, id)))
             .thenApply(optional ->
-                optional.map(this::attachment));
+                OptionalConverter.ifEmpty(
+                    optional.map(this::attachment),
+                    () -> LOGGER.warn("Failed retrieving attachment {}", attachmentId)));
     }
 
     @Override


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


[08/10] james-project git commit: JAMES-2122 Avoid confusing Optional boxing in JMAP mailboxFactory

Posted by ma...@apache.org.
JAMES-2122 Avoid confusing Optional boxing in JMAP mailboxFactory


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

Branch: refs/heads/master
Commit: 0624ab2e38c6d88432222c5efadbb4de0436bcbd
Parents: 40c9816
Author: benwa <bt...@linagora.com>
Authored: Thu Aug 17 10:39:04 2017 +0700
Committer: Matthieu Baechler <ma...@apache.org>
Committed: Thu Aug 17 13:13:34 2017 +0200

----------------------------------------------------------------------
 .../apache/james/jmap/model/MailboxFactory.java | 22 ++++++++++----------
 1 file changed, 11 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/0624ab2e/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxFactory.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxFactory.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxFactory.java
index 119de23..23d327c 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxFactory.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxFactory.java
@@ -75,7 +75,7 @@ public class MailboxFactory {
 
             try {
                 MessageManager mailbox = mailboxFactory.mailboxManager.getMailbox(id, session);
-                return mailboxFactory.fromMessageManager(mailbox, Optional.ofNullable(userMailboxesMetadata), session);
+                return Optional.of(mailboxFactory.fromMessageManager(mailbox, Optional.ofNullable(userMailboxesMetadata), session));
             } catch (MailboxNotFoundException e) {
                 return Optional.empty();
             } catch (MailboxException e) {
@@ -93,20 +93,20 @@ public class MailboxFactory {
         return new MailboxBuilder(this);
     }
 
-    private Optional<Mailbox> fromMessageManager(MessageManager messageManager, Optional<List<MailboxMetaData>> userMailboxesMetadata,
+    private Mailbox fromMessageManager(MessageManager messageManager, Optional<List<MailboxMetaData>> userMailboxesMetadata,
                                                  MailboxSession mailboxSession) throws MailboxException {
         MailboxPath mailboxPath = messageManager.getMailboxPath();
         Optional<Role> role = Role.from(mailboxPath.getName());
         MailboxCounters mailboxCounters = messageManager.getMailboxCounters(mailboxSession);
-        return Optional.ofNullable(Mailbox.builder()
-                .id(messageManager.getId())
-                .name(getName(mailboxPath, mailboxSession))
-                .parentId(getParentIdFromMailboxPath(mailboxPath, userMailboxesMetadata, mailboxSession).orElse(null))
-                .role(role)
-                .unreadMessages(mailboxCounters.getUnseen())
-                .totalMessages(mailboxCounters.getCount())
-                .sortOrder(SortOrder.getSortOrder(role))
-                .build());
+        return Mailbox.builder()
+            .id(messageManager.getId())
+            .name(getName(mailboxPath, mailboxSession))
+            .parentId(getParentIdFromMailboxPath(mailboxPath, userMailboxesMetadata, mailboxSession).orElse(null))
+            .role(role)
+            .unreadMessages(mailboxCounters.getUnseen())
+            .totalMessages(mailboxCounters.getCount())
+            .sortOrder(SortOrder.getSortOrder(role))
+            .build();
     }
 
     @VisibleForTesting String getName(MailboxPath mailboxPath, MailboxSession mailboxSession) {


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


[09/10] james-project git commit: JAMES-2122 Adding a log on Cassandra cluster fallback

Posted by ma...@apache.org.
JAMES-2122 Adding a log on Cassandra cluster fallback


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

Branch: refs/heads/master
Commit: 00a554bcd5f996ac49853967c389adb1aa52fe6d
Parents: 0624ab2
Author: benwa <bt...@linagora.com>
Authored: Thu Aug 17 15:25:00 2017 +0700
Committer: Matthieu Baechler <ma...@apache.org>
Committed: Thu Aug 17 13:13:34 2017 +0200

----------------------------------------------------------------------
 .../org/apache/james/user/cassandra/CassandraUsersRepository.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/00a554bc/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepository.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepository.java b/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepository.java
index 0a5b025..3f808ce 100644
--- a/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepository.java
+++ b/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepository.java
@@ -166,7 +166,7 @@ public class CassandraUsersRepository extends AbstractUsersRepository {
         return Optional.ofNullable(getUserByName(name))
                 .map(x -> x.verifyPassword(password))
             .orElseGet(() -> {
-                LOGGER.info("Could not retrieve user {}. Authentication failure.");
+                LOGGER.info("Could not retrieve user {}. Password is unverified.");
                 return false;
             });
     }


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