Author: btellier
Date: Wed Jun 17 09:07:58 2015
New Revision: 1685960
URL: http://svn.apache.org/r1685960
Log:
MAILBOX-239 LIST related operations should be MPT compliant for the Cassandra
mailbox
Modified:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTableManager.java
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxTable.java
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMailboxMapperTest.java
Modified:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTableManager.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTableManager.java?rev=1685960&r1=1685959&r2=1685960&view=diff
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTableManager.java
(original)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTableManager.java
Wed Jun 17 09:07:58 2015
@@ -45,8 +45,7 @@ public class CassandraTableManager {
SchemaBuilder.createTable(CassandraMailboxTable.TABLE_NAME)
.ifNotExists()
.addPartitionKey(CassandraMailboxTable.ID, timeuuid())
- .addColumn(CassandraMailboxTable.NAMESPACE, text())
- .addColumn(CassandraMailboxTable.USER, text())
+ .addUDTColumn(CassandraMailboxTable.MAILBOX_BASE,
SchemaBuilder.frozen(CassandraTypesProvider.TYPE.MailboxBase.getName()))
.addColumn(CassandraMailboxTable.NAME, text())
.addColumn(CassandraMailboxTable.PATH, text())
.addColumn(CassandraMailboxTable.UIDVALIDITY, bigint())),
@@ -112,7 +111,14 @@ public class CassandraTableManager {
MailboxPath(SchemaBuilder.createIndex(CassandraMailboxTable.TABLE_NAME)
.ifNotExists()
.onTable(CassandraMailboxTable.TABLE_NAME)
- .andColumn(CassandraMailboxTable.PATH));
+ .andColumn(CassandraMailboxTable.PATH)),
+ AggregateNamespaceUser(
+ SchemaBuilder.createIndex(CassandraMailboxTable.MAILBOX_BASE)
+ .ifNotExists()
+ .onTable(CassandraMailboxTable.TABLE_NAME)
+ .andColumn(CassandraMailboxTable.MAILBOX_BASE)
+ ),
+ ;
private SchemaStatement createIndexStatement;
INDEX(SchemaStatement createIndexStatement) {
Modified:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java?rev=1685960&r1=1685959&r2=1685960&view=diff
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
(original)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
Wed Jun 17 09:07:58 2015
@@ -22,13 +22,21 @@ package org.apache.james.mailbox.cassand
import static com.datastax.driver.core.querybuilder.QueryBuilder.*;
import static org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.*;
+import java.util.Collections;
import java.util.List;
+import java.util.Optional;
+import java.util.StringTokenizer;
import java.util.UUID;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
import com.datastax.driver.core.utils.UUIDs;
import com.google.common.base.Preconditions;
import org.apache.james.mailbox.cassandra.CassandraTypesProvider;
import org.apache.james.mailbox.cassandra.CassandraTypesProvider.TYPE;
+import org.apache.james.mailbox.cassandra.table.CassandraMailboxTable;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.exception.MailboxNotFoundException;
import org.apache.james.mailbox.model.MailboxACL;
@@ -76,7 +84,12 @@ public class CassandraMailboxMapper impl
}
private SimpleMailbox<UUID> mailbox(Row row) {
- SimpleMailbox<UUID> mailbox = new SimpleMailbox<UUID>(new
MailboxPath(row.getString(NAMESPACE), row.getString(USER),
row.getString(NAME)), row.getLong(UIDVALIDITY));
+ SimpleMailbox<UUID> mailbox = new SimpleMailbox<>(
+ new MailboxPath(
+ row.getUDTValue(MAILBOX_BASE).getString(MailboxBase.NAMESPACE),
+ row.getUDTValue(MAILBOX_BASE).getString(MailboxBase.USER),
+ row.getString(NAME)),
+ row.getLong(UIDVALIDITY));
mailbox.setMailboxId(row.getUUID(ID));
mailbox.setACL(new CassandraACLMapper(mailbox, session,
maxRetry).getACL());
return mailbox;
@@ -84,15 +97,25 @@ public class CassandraMailboxMapper impl
@Override
public List<Mailbox<UUID>> findMailboxWithPathLike(MailboxPath path)
throws MailboxException {
- final String regexWithUser = ".*" + path.getNamespace() + ".*" +
path.getUser() + ".*" + path.getName() + ".*";
- final String regexWithoutUser = ".*" + path.getNamespace() +
".*null.*" + path.getName() + ".*";
- Builder<Mailbox<UUID>> result = ImmutableList.<Mailbox<UUID>>
builder();
- for (Row row : session.execute(select(FIELDS).from(TABLE_NAME))) {
- if (row.getString(PATH).matches(regexWithUser) ||
row.getString(PATH).matches(regexWithoutUser)) {
- result.add(mailbox(row));
- }
- }
- return result.build();
+ Pattern regex =
Pattern.compile(constructEscapedRegexForMailboxNameMatching(path));
+ return getMailboxFilteredByNamespaceAndUserStream(path.getNamespace(),
path.getUser())
+ .filter((row) -> regex.matcher(row.getString(NAME)).matches())
+ .map(this::mailbox)
+ .collect(Collectors.toList());
+ }
+
+ private String constructEscapedRegexForMailboxNameMatching(MailboxPath
path) {
+ return Collections
+ .list(new StringTokenizer(path.getName(), WILDCARD, true))
+ .stream()
+ .map((token) -> {
+ if (token.equals(WILDCARD)) {
+ return ".*";
+ } else {
+ return Pattern.quote((String) token);
+ }
+ }
+ ).collect(Collectors.joining());
}
@Override
@@ -110,9 +133,11 @@ public class CassandraMailboxMapper impl
insertInto(TABLE_NAME)
.value(ID, mailbox.getMailboxId())
.value(NAME, mailbox.getName())
- .value(NAMESPACE, mailbox.getNamespace())
.value(UIDVALIDITY, mailbox.getUidValidity())
- .value(USER, mailbox.getUser())
+ .value(MAILBOX_BASE,
typesProvider.getDefinedUserType(TYPE.MailboxBase)
+ .newValue()
+ .setString(MailboxBase.NAMESPACE, mailbox.getNamespace())
+ .setString(MailboxBase.USER, mailbox.getUser()))
.value(PATH, path(mailbox).toString())
);
}
@@ -128,14 +153,21 @@ public class CassandraMailboxMapper impl
@Override
public boolean hasChildren(Mailbox<UUID> mailbox, char delimiter) {
- final String regexWithUser = ".*" + mailbox.getNamespace() + ".*" +
mailbox.getUser() + ".*" + mailbox.getName() + delimiter + ".*";
- final String regexWithoutUser = ".*" + mailbox.getNamespace() +
".*null.*" + mailbox.getName() + delimiter + ".*";
- for (Row row : session.execute(select(PATH).from(TABLE_NAME))) {
- if (row.getString(PATH).matches(regexWithUser) ||
row.getString(PATH).matches(regexWithoutUser)) {
- return true;
- }
- }
- return false;
+ final Pattern regex = Pattern.compile(Pattern.quote( mailbox.getName()
+ String.valueOf(delimiter)) + ".*");
+ return
getMailboxFilteredByNamespaceAndUserStream(mailbox.getNamespace(),
mailbox.getUser())
+ .anyMatch((row) -> regex.matcher(row.getString(NAME)).matches());
+ }
+
+ private Stream<Row> getMailboxFilteredByNamespaceAndUserStream (String
namespace, String user) {
+ return StreamSupport.stream(session.execute(
+ select(FIELDS)
+ .from(TABLE_NAME)
+ .where(eq(MAILBOX_BASE,
typesProvider.getDefinedUserType(TYPE.MailboxBase)
+ .newValue()
+ .setString(MailboxBase.NAMESPACE, namespace)
+ .setString(MailboxBase.USER, user))))
+ .spliterator(),
+ true);
}
@Override
Modified:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxTable.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxTable.java?rev=1685960&r1=1685959&r2=1685960&view=diff
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxTable.java
(original)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxTable.java
Wed Jun 17 09:07:58 2015
@@ -19,13 +19,18 @@
package org.apache.james.mailbox.cassandra.table;
+
public interface CassandraMailboxTable {
String TABLE_NAME = "mailbox";
String ID = "id";
- String USER = "user";
String PATH = "path";
- String NAMESPACE = "namespace";
+ String MAILBOX_BASE = "mailboxbase";
String UIDVALIDITY = "uidvalidity";
String NAME = "name";
- String[] FIELDS = { ID, USER, NAMESPACE, UIDVALIDITY, NAME, PATH };
+ String[] FIELDS = { ID, MAILBOX_BASE, UIDVALIDITY, NAME, PATH };
+
+ interface MailboxBase {
+ String USER = "user";
+ String NAMESPACE = "namespace";
+ }
}
Modified:
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMailboxMapperTest.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMailboxMapperTest.java?rev=1685960&r1=1685959&r2=1685960&view=diff
==============================================================================
---
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMailboxMapperTest.java
(original)
+++
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMailboxMapperTest.java
Wed Jun 17 09:07:58 2015
@@ -26,7 +26,6 @@ import org.apache.james.mailbox.store.ma
import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import java.util.List;
@@ -172,14 +171,12 @@ public abstract class AbstractMailboxMap
assertThat(mailboxMapper.hasChildren(esnDevGroupInboxMailbox,
DELIMITER)).isTrue();
}
- @Ignore("See MAILBOX-11 and JWC-125")
@Test
public void hasChildrenShouldNotBeAcrossUsersAndNamespace() throws
MailboxException {
saveAll();
assertThat(mailboxMapper.hasChildren(bobInboxMailbox, '.')).isFalse();
}
- @Ignore("See MAILBOX-11 and JWC-125")
@Test
public void findMailboxWithPathLikeShouldBeLimitedToUserAndNamespace()
throws MailboxException {
saveAll();
@@ -209,10 +206,6 @@ public abstract class AbstractMailboxMap
mailboxMapper.findMailboxByPath(esnDevGroupJamesPath);
}
- // findMailboxWithPathLike does not behave as intended in Cassandra
Mailbox implementation
- // It matches .*namespace.*:.*user.*:.*name%.* instead of
namespace:user:name.*
- // For instance see this method in use line 436 of StoreMailboxManager
- @Ignore
@Test
public void findMailboxWithPathLikeWithChildRegexShouldRetrieveChildren()
throws MailboxException {
saveAll();
@@ -220,8 +213,6 @@ public abstract class AbstractMailboxMap
assertThat(mailboxMapper.findMailboxWithPathLike(regexPath)).containsOnly(benwaWorkMailbox,
benwaWorkTodoMailbox, benwaWorkDoneMailbox);
}
- // Same thing
- @Ignore
@Test
public void
findMailboxWithPathLikeWithNullUserWithChildRegexShouldRetrieveChildren()
throws MailboxException {
saveAll();
@@ -229,8 +220,6 @@ public abstract class AbstractMailboxMap
assertThat(mailboxMapper.findMailboxWithPathLike(regexPath)).contains(obmTeamGroupInboxMailbox,
obmTeamGroupOPushMailbox, obmTeamGroupRoundCubeMailbox);
}
- // Same thing
- @Ignore
@Test
public void
findMailboxWithPathLikeWithRegexShouldRetrieveCorrespondingMailbox() throws
MailboxException {
saveAll();
@@ -238,8 +227,6 @@ public abstract class AbstractMailboxMap
assertThat(mailboxMapper.findMailboxWithPathLike(regexPath)).containsOnly(benwaInboxMailbox);
}
- // Same thing
- @Ignore
@Test
public void
findMailboxWithPathLikeWithNullUserWithRegexShouldRetrieveCorrespondingMailbox()
throws MailboxException {
saveAll();
@@ -247,7 +234,6 @@ public abstract class AbstractMailboxMap
assertThat(mailboxMapper.findMailboxWithPathLike(regexPath)).contains(esnDevGroupInboxMailbox);
}
- @Ignore("Mailbox name is not escaped")
@Test
public void findMailboxWithPathLikeShouldEscapeMailboxName() throws
MailboxException {
saveAll();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]