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 ad...@apache.org on 2017/02/15 13:36:08 UTC

[05/20] james-project git commit: JAMES-1925 Adapt slightly ACLs

JAMES-1925 Adapt slightly ACLs

 - Read should use future
 - Only rely on mailboxId


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

Branch: refs/heads/master
Commit: 7b85c97040ebda3301dc0ef5e38cdf7516a5966a
Parents: 7c223af
Author: Benoit Tellier <bt...@linagora.com>
Authored: Tue Feb 14 11:01:53 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Feb 15 13:12:37 2017 +0100

----------------------------------------------------------------------
 .../cassandra/mail/CassandraACLMapper.java      | 55 ++++++++++----------
 .../cassandra/mail/CassandraMailboxMapper.java  |  8 +--
 .../cassandra/mail/CassandraACLMapperTest.java  | 52 +++++++-----------
 3 files changed, 52 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/7b85c970/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java
index 378b48b..18b406a 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java
@@ -27,7 +27,9 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.update;
 
 import java.io.IOException;
 import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
 
+import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 import org.apache.james.backends.cassandra.utils.CassandraConstants;
 import org.apache.james.backends.cassandra.utils.FunctionRunnerWithRetry;
 import org.apache.james.backends.cassandra.utils.LightweightTransactionException;
@@ -39,7 +41,6 @@ import org.apache.james.mailbox.exception.UnsupportedRightException;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.SimpleMailboxACL;
 import org.apache.james.mailbox.store.json.SimpleMailboxACLJsonConverter;
-import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -57,33 +58,36 @@ public class CassandraACLMapper {
         void inject();
     }
 
-    private final Mailbox mailbox;
+    private final CassandraId cassandraId;
+    private final CassandraAsyncExecutor executor;
     private final Session session;
     private final int maxRetry;
     private final CodeInjector codeInjector;
 
     private static final Logger LOG = LoggerFactory.getLogger(CassandraACLMapper.class);
 
-    public CassandraACLMapper(Mailbox mailbox, Session session, int maxRetry) {
-        this(mailbox, session, maxRetry, () -> {});
+    public CassandraACLMapper(CassandraId cassandraId, Session session, int maxRetry) {
+        this(cassandraId, session, maxRetry, () -> {});
     }
 
-    public CassandraACLMapper(Mailbox mailbox, Session session, int maxRetry, CodeInjector codeInjector) {
+    public CassandraACLMapper(CassandraId cassandraId, Session session, int maxRetry, CodeInjector codeInjector) {
         Preconditions.checkArgument(maxRetry > 0);
-        Preconditions.checkArgument(mailbox.getMailboxId() != null);
-        this.mailbox = mailbox;
+        Preconditions.checkArgument(cassandraId != null);
+        this.cassandraId = cassandraId;
         this.session = session;
+        this.executor = new CassandraAsyncExecutor(session);
         this.maxRetry = maxRetry;
         this.codeInjector = codeInjector;
     }
 
-    public MailboxACL getACL() {
-        ResultSet resultSet = getStoredACLRow();
-        if (resultSet.isExhausted()) {
-            return SimpleMailboxACL.EMPTY;
-        }
-        String serializedACL = resultSet.one().getString(CassandraACLTable.ACL);
-        return deserializeACL(serializedACL);
+    public CompletableFuture<MailboxACL> getACL() {
+        return  getStoredACLRow().thenApply(resultSet -> {
+            if (resultSet.isExhausted()) {
+                return SimpleMailboxACL.EMPTY;
+            }
+            String serializedACL = resultSet.one().getString(CassandraACLTable.ACL);
+            return deserializeACL(serializedACL);
+        });
     }
 
     public void updateACL(MailboxACL.MailboxACLCommand command) throws MailboxException {
@@ -111,23 +115,19 @@ public class CassandraACLMapper {
         }
     }
 
-    private ResultSet getStoredACLRow() {
-        CassandraId mailboxId = (CassandraId) mailbox.getMailboxId();
-        return session.execute(
-            select(CassandraACLTable.ACL, CassandraACLTable.VERSION)
-                .from(CassandraACLTable.TABLE_NAME)
-                .where(eq(CassandraMailboxTable.ID, mailboxId.asUuid()))
-        );
+    private CompletableFuture<ResultSet> getStoredACLRow() {
+        return executor.execute(select(CassandraACLTable.ACL, CassandraACLTable.VERSION)
+            .from(CassandraACLTable.TABLE_NAME)
+            .where(eq(CassandraMailboxTable.ID, cassandraId.asUuid())));
     }
 
     private ResultSet updateStoredACL(ACLWithVersion aclWithVersion) {
         try {
-            CassandraId mailboxId = (CassandraId) mailbox.getMailboxId();
             return session.execute(
                 update(CassandraACLTable.TABLE_NAME)
                     .with(set(CassandraACLTable.ACL, SimpleMailboxACLJsonConverter.toJson(aclWithVersion.mailboxACL)))
                     .and(set(CassandraACLTable.VERSION, aclWithVersion.version + 1))
-                    .where(eq(CassandraACLTable.ID, mailboxId.asUuid()))
+                    .where(eq(CassandraACLTable.ID, cassandraId.asUuid()))
                     .onlyIf(eq(CassandraACLTable.VERSION, aclWithVersion.version))
             );
         } catch (JsonProcessingException exception) {
@@ -137,10 +137,9 @@ public class CassandraACLMapper {
 
     private ResultSet insertACL(MailboxACL acl) {
         try {
-            CassandraId mailboxId = (CassandraId) mailbox.getMailboxId();
             return session.execute(
                 insertInto(CassandraACLTable.TABLE_NAME)
-                    .value(CassandraACLTable.ID, mailboxId.asUuid())
+                    .value(CassandraACLTable.ID, cassandraId.asUuid())
                     .value(CassandraACLTable.ACL, SimpleMailboxACLJsonConverter.toJson(acl))
                     .value(CassandraACLTable.VERSION, 0)
                     .ifNotExists()
@@ -151,7 +150,7 @@ public class CassandraACLMapper {
     }
 
     private Optional<ACLWithVersion> getAclWithVersion() {
-        ResultSet resultSet = getStoredACLRow();
+        ResultSet resultSet = getStoredACLRow().join();
         if (resultSet.isExhausted()) {
             return Optional.empty();
         }
@@ -165,8 +164,8 @@ public class CassandraACLMapper {
         } catch(IOException exception) {
             LOG.error("Unable to read stored ACL. " +
                 "We will use empty ACL instead." +
-                "Mailbox is {}:{}:{} ." +
-                "ACL is {}", mailbox.getNamespace(), mailbox.getUser(), mailbox.getName(), serializedACL, exception);
+                "Mailbox is {} ." +
+                "ACL is {}", cassandraId, serializedACL, exception);
             return SimpleMailboxACL.EMPTY;
         }
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/7b85c970/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 c2f824e..4314148 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
@@ -158,7 +158,8 @@ public class CassandraMailboxMapper implements MailboxMapper {
 
     @Override
     public void updateACL(Mailbox mailbox, MailboxACL.MailboxACLCommand mailboxACLCommand) throws MailboxException {
-        new CassandraACLMapper(mailbox, session, maxRetry).updateACL(mailboxACLCommand);
+        CassandraId cassandraId = (CassandraId) mailbox.getMailboxId();
+        new CassandraACLMapper(cassandraId, session, maxRetry).updateACL(mailboxACLCommand);
     }
 
     @Override
@@ -173,8 +174,9 @@ public class CassandraMailboxMapper implements MailboxMapper {
                 row.getUDTValue(MAILBOX_BASE).getString(MailboxBase.USER),
                 row.getString(NAME)),
             row.getLong(UIDVALIDITY));
-        mailbox.setMailboxId(CassandraId.of(row.getUUID(ID)));
-        mailbox.setACL(new CassandraACLMapper(mailbox, session, maxRetry).getACL());
+        CassandraId mailboxId = CassandraId.of(row.getUUID(ID));
+        mailbox.setMailboxId(mailboxId);
+        mailbox.setACL(new CassandraACLMapper(mailboxId, session, maxRetry).getACL().join());
         return mailbox;
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/7b85c970/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperTest.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperTest.java
index 008bcdf..ebff807 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperTest.java
@@ -36,9 +36,7 @@ import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.table.CassandraACLTable;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxACL;
-import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.SimpleMailboxACL;
-import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -47,22 +45,17 @@ import com.google.common.base.Throwables;
 
 public class CassandraACLMapperTest {
 
+    public static final CassandraId MAILBOX_ID = CassandraId.of(UUID.fromString("464765a0-e4e7-11e4-aba4-710c1de3782b"));
+    public static final int MAX_RETRY = 100;
     private CassandraACLMapper cassandraACLMapper;
     private CassandraCluster cassandra;
-    private SimpleMailbox mailbox;
-    private int uidValidity;
-    private int maxRetry;
     private ExecutorService executor;
 
     @Before
     public void setUp() {
         cassandra = CassandraCluster.create(new CassandraAclModule());
         cassandra.ensureAllTables();
-        uidValidity = 10;
-        mailbox = new SimpleMailbox(new MailboxPath("#private", "benwa@linagora.com", "INBOX"), uidValidity);
-        mailbox.setMailboxId(CassandraId.of(UUID.fromString("464765a0-e4e7-11e4-aba4-710c1de3782b")));
-        maxRetry = 100;
-        cassandraACLMapper = new CassandraACLMapper(mailbox, cassandra.getConf(), maxRetry);
+        cassandraACLMapper = new CassandraACLMapper(MAILBOX_ID, cassandra.getConf(), MAX_RETRY);
         executor = Executors.newFixedThreadPool(2);
     }
 
@@ -74,28 +67,23 @@ public class CassandraACLMapperTest {
 
     @Test(expected = IllegalArgumentException.class)
     public void creatingACLMapperWithNegativeMaxRetryShouldFail() {
-        new CassandraACLMapper(mailbox, cassandra.getConf(), -1);
+        new CassandraACLMapper(MAILBOX_ID, cassandra.getConf(), -1);
     }
 
     @Test(expected = IllegalArgumentException.class)
     public void creatingACLMapperWithNullMaxRetryShouldFail() {
-        new CassandraACLMapper(mailbox, cassandra.getConf(), 0);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void creatingACLMapperWithNoMailboxIdShouldFail() {
-        new CassandraACLMapper(new SimpleMailbox(new MailboxPath("#private", "user", "name"), uidValidity), cassandra.getConf(), maxRetry);
+        new CassandraACLMapper(MAILBOX_ID, cassandra.getConf(), 0);
     }
 
     @Test
     public void retrieveACLWhenPresentInBaseShouldReturnCorrespondingACL() throws Exception {
         cassandra.getConf().execute(
             insertInto(CassandraACLTable.TABLE_NAME)
-                .value(CassandraACLTable.ID, ((CassandraId) mailbox.getMailboxId()).asUuid())
+                .value(CassandraACLTable.ID, MAILBOX_ID.asUuid())
                 .value(CassandraACLTable.ACL, "{\"entries\":{\"bob\":64}}")
                 .value(CassandraACLTable.VERSION, 1)
         );
-        assertThat(cassandraACLMapper.getACL())
+        assertThat(cassandraACLMapper.getACL().join())
             .isEqualTo(
                 SimpleMailboxACL.EMPTY.union(
                     new SimpleMailboxACL.SimpleMailboxACLEntryKey("bob", MailboxACL.NameType.user, false),
@@ -107,16 +95,16 @@ public class CassandraACLMapperTest {
     public void retrieveACLWhenInvalidInBaseShouldReturnEmptyACL() throws Exception {
         cassandra.getConf().execute(
             insertInto(CassandraACLTable.TABLE_NAME)
-                .value(CassandraACLTable.ID, ((CassandraId) mailbox.getMailboxId()).asUuid())
+                .value(CassandraACLTable.ID, MAILBOX_ID.asUuid())
                 .value(CassandraACLTable.ACL, "{\"entries\":{\"bob\":invalid}}")
                 .value(CassandraACLTable.VERSION, 1)
         );
-        assertThat(cassandraACLMapper.getACL()).isEqualTo(SimpleMailboxACL.EMPTY);
+        assertThat(cassandraACLMapper.getACL().join()).isEqualTo(SimpleMailboxACL.EMPTY);
     }
 
     @Test
     public void retrieveACLWhenNoACLStoredShouldReturnEmptyACL() {
-        assertThat(cassandraACLMapper.getACL()).isEqualTo(SimpleMailboxACL.EMPTY);
+        assertThat(cassandraACLMapper.getACL().join()).isEqualTo(SimpleMailboxACL.EMPTY);
     }
 
     @Test
@@ -124,7 +112,7 @@ public class CassandraACLMapperTest {
         SimpleMailboxACL.SimpleMailboxACLEntryKey key = new SimpleMailboxACL.SimpleMailboxACLEntryKey("bob", MailboxACL.NameType.user, false);
         SimpleMailboxACL.Rfc4314Rights rights = new SimpleMailboxACL.Rfc4314Rights(new SimpleMailboxACL.SimpleMailboxACLRight('r'));
         cassandraACLMapper.updateACL(new SimpleMailboxACL.SimpleMailboxACLCommand(key, MailboxACL.EditMode.ADD, rights));
-        assertThat(cassandraACLMapper.getACL()).isEqualTo(new SimpleMailboxACL().union(key, rights));
+        assertThat(cassandraACLMapper.getACL().join()).isEqualTo(new SimpleMailboxACL().union(key, rights));
     }
 
     @Test
@@ -134,7 +122,7 @@ public class CassandraACLMapperTest {
         cassandraACLMapper.updateACL(new SimpleMailboxACL.SimpleMailboxACLCommand(keyBob, MailboxACL.EditMode.ADD, rights));
         SimpleMailboxACL.SimpleMailboxACLEntryKey keyAlice = new SimpleMailboxACL.SimpleMailboxACLEntryKey("alice", MailboxACL.NameType.user, false);
         cassandraACLMapper.updateACL(new SimpleMailboxACL.SimpleMailboxACLCommand(keyAlice, MailboxACL.EditMode.ADD, rights));
-        assertThat(cassandraACLMapper.getACL()).isEqualTo(new SimpleMailboxACL().union(keyBob, rights).union(keyAlice, rights));
+        assertThat(cassandraACLMapper.getACL().join()).isEqualTo(new SimpleMailboxACL().union(keyBob, rights).union(keyAlice, rights));
     }
 
     @Test
@@ -143,7 +131,7 @@ public class CassandraACLMapperTest {
         SimpleMailboxACL.Rfc4314Rights rights = new SimpleMailboxACL.Rfc4314Rights(new SimpleMailboxACL.SimpleMailboxACLRight('r'));
         cassandraACLMapper.updateACL(new SimpleMailboxACL.SimpleMailboxACLCommand(key, MailboxACL.EditMode.ADD, rights));
         cassandraACLMapper.updateACL(new SimpleMailboxACL.SimpleMailboxACLCommand(key, MailboxACL.EditMode.REMOVE, rights));
-        assertThat(cassandraACLMapper.getACL()).isEqualTo(SimpleMailboxACL.EMPTY);
+        assertThat(cassandraACLMapper.getACL().join()).isEqualTo(SimpleMailboxACL.EMPTY);
     }
 
     @Test
@@ -152,7 +140,7 @@ public class CassandraACLMapperTest {
         SimpleMailboxACL.Rfc4314Rights rights = new SimpleMailboxACL.Rfc4314Rights(new SimpleMailboxACL.SimpleMailboxACLRight('r'));
         cassandraACLMapper.updateACL(new SimpleMailboxACL.SimpleMailboxACLCommand(key, MailboxACL.EditMode.ADD, rights));
         cassandraACLMapper.updateACL(new SimpleMailboxACL.SimpleMailboxACLCommand(key, MailboxACL.EditMode.REPLACE, null));
-        assertThat(cassandraACLMapper.getACL()).isEqualTo(SimpleMailboxACL.EMPTY);
+        assertThat(cassandraACLMapper.getACL().join()).isEqualTo(SimpleMailboxACL.EMPTY);
     }
 
     @Test
@@ -160,21 +148,21 @@ public class CassandraACLMapperTest {
         SimpleMailboxACL.SimpleMailboxACLEntryKey key = new SimpleMailboxACL.SimpleMailboxACLEntryKey("bob", MailboxACL.NameType.user, false);
         SimpleMailboxACL.Rfc4314Rights rights = new SimpleMailboxACL.Rfc4314Rights(new SimpleMailboxACL.SimpleMailboxACLRight('r'));
         cassandraACLMapper.updateACL(new SimpleMailboxACL.SimpleMailboxACLCommand(key, MailboxACL.EditMode.REPLACE, rights));
-        assertThat(cassandraACLMapper.getACL()).isEqualTo(new SimpleMailboxACL().union(key, rights));
+        assertThat(cassandraACLMapper.getACL().join()).isEqualTo(new SimpleMailboxACL().union(key, rights));
     }
 
     @Test
     public void updateInvalidACLShouldBeBasedOnEmptyACL() throws Exception {
         cassandra.getConf().execute(
             insertInto(CassandraACLTable.TABLE_NAME)
-                .value(CassandraACLTable.ID, ((CassandraId) mailbox.getMailboxId()).asUuid())
+                .value(CassandraACLTable.ID, MAILBOX_ID.asUuid())
                 .value(CassandraACLTable.ACL, "{\"entries\":{\"bob\":invalid}}")
                 .value(CassandraACLTable.VERSION, 1)
         );
         SimpleMailboxACL.SimpleMailboxACLEntryKey key = new SimpleMailboxACL.SimpleMailboxACLEntryKey("bob", MailboxACL.NameType.user, false);
         SimpleMailboxACL.Rfc4314Rights rights = new SimpleMailboxACL.Rfc4314Rights(new SimpleMailboxACL.SimpleMailboxACLRight('r'));
         cassandraACLMapper.updateACL(new SimpleMailboxACL.SimpleMailboxACLCommand(key, MailboxACL.EditMode.ADD, rights));
-        assertThat(cassandraACLMapper.getACL()).isEqualTo(new SimpleMailboxACL().union(key, rights));
+        assertThat(cassandraACLMapper.getACL().join()).isEqualTo(new SimpleMailboxACL().union(key, rights));
     }
 
     @Test
@@ -186,7 +174,7 @@ public class CassandraACLMapperTest {
         Future<Boolean> future1 = performACLUpdateInExecutor(executor, keyBob, rights, countDownLatch::countDown);
         Future<Boolean> future2 = performACLUpdateInExecutor(executor, keyAlice, rights, countDownLatch::countDown);
         awaitAll(future1, future2);
-        assertThat(cassandraACLMapper.getACL()).isEqualTo(new SimpleMailboxACL().union(keyBob, rights).union(keyAlice, rights));
+        assertThat(cassandraACLMapper.getACL().join()).isEqualTo(new SimpleMailboxACL().union(keyBob, rights).union(keyAlice, rights));
     }
 
     @Test
@@ -200,7 +188,7 @@ public class CassandraACLMapperTest {
         Future<Boolean> future1 = performACLUpdateInExecutor(executor, keyBob, rights, countDownLatch::countDown);
         Future<Boolean> future2 = performACLUpdateInExecutor(executor, keyAlice, rights, countDownLatch::countDown);
         awaitAll(future1, future2);
-        assertThat(cassandraACLMapper.getACL()).isEqualTo(new SimpleMailboxACL().union(keyBob, rights).union(keyAlice, rights).union(keyBenwa, rights));
+        assertThat(cassandraACLMapper.getACL().join()).isEqualTo(new SimpleMailboxACL().union(keyBob, rights).union(keyAlice, rights).union(keyBenwa, rights));
     }
 
     private void awaitAll(Future<?>... futures) 
@@ -212,7 +200,7 @@ public class CassandraACLMapperTest {
 
     private Future<Boolean> performACLUpdateInExecutor(ExecutorService executor, SimpleMailboxACL.SimpleMailboxACLEntryKey key, SimpleMailboxACL.Rfc4314Rights rights, CassandraACLMapper.CodeInjector runnable) {
         return executor.submit(() -> {
-            CassandraACLMapper aclMapper = new CassandraACLMapper(mailbox, cassandra.getConf(), maxRetry, runnable);
+            CassandraACLMapper aclMapper = new CassandraACLMapper(MAILBOX_ID, cassandra.getConf(), MAX_RETRY, runnable);
             try {
                 aclMapper.updateACL(new SimpleMailboxACL.SimpleMailboxACLCommand(key, MailboxACL.EditMode.ADD, rights));
             } catch (MailboxException exception) {


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