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