Added: james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraClusterSingleton.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraClusterSingleton.java?rev=1617517&view=auto ============================================================================== --- james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraClusterSingleton.java (added) +++ james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraClusterSingleton.java Tue Aug 12 16:08:57 2014 @@ -0,0 +1,131 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ +package org.apache.james.mailbox.cassandra; + +import org.apache.commons.lang.NotImplementedException; +import org.cassandraunit.utils.EmbeddedCassandraServerHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.datastax.driver.core.Session; + +/** + * Class that will creates a single instance of Cassandra session. + */ +public final class CassandraClusterSingleton { + private final static String CLUSTER_IP = "localhost"; + private final static int CLUSTER_PORT_TEST = 9142; + private final static String KEYSPACE_NAME = "apache_james"; + private final static int DEFAULT_REPLICATION_FACTOR = 1; + + private static final Logger LOG = LoggerFactory.getLogger(CassandraClusterSingleton.class); + private static CassandraClusterSingleton cluster = null; + private CassandraSession session; + + /** + * Builds a MiniCluster instance. + * + * @return the {@link CassandraClusterSingleton} instance + * @throws RuntimeException + */ + public static synchronized CassandraClusterSingleton build() throws RuntimeException { + LOG.info("Retrieving cluster instance."); + if (cluster == null) { + cluster = new CassandraClusterSingleton(); + } + return cluster; + } + + private CassandraClusterSingleton() throws RuntimeException { + try { + EmbeddedCassandraServerHelper.startEmbeddedCassandra(); + // Let Cassandra initialization before creating + // the session. Solve very fast computer tests run. + Thread.sleep(2000); + this.session = new CassandraSession(CLUSTER_IP, CLUSTER_PORT_TEST, KEYSPACE_NAME, DEFAULT_REPLICATION_FACTOR); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Return a configuration for the runnning MiniCluster. + * + * @return + */ + public Session getConf() { + return session; + } + + /** + * Create a specific table. + * + * @param tableName + * the table name + */ + public void ensureTable(String tableName) { + if (tableName.equals("mailbox")) { + session.execute("CREATE TABLE IF NOT EXISTS " + session.getLoggedKeyspace() + ".mailbox (" + "id uuid PRIMARY KEY," + "name text, namespace text," + "uidvalidity bigint," + "user text," + "path text" + ");"); + + session.execute("CREATE INDEX IF NOT EXISTS ON " + session.getLoggedKeyspace() + ".mailbox(path);"); + } else if (tableName.equals("messageCounter")) { + session.execute("CREATE TABLE IF NOT EXISTS " + session.getLoggedKeyspace() + ".messageCounter (" + "mailboxId UUID PRIMARY KEY," + "nextUid bigint," + ");"); + } else if (tableName.equals("mailboxCounters")) { + session.execute("CREATE TABLE IF NOT EXISTS " + session.getLoggedKeyspace() + ".mailboxCounters (" + "mailboxId UUID PRIMARY KEY," + "count counter," + "unseen counter," + "nextModSeq counter" + ");"); + } else if (tableName.equals("message")) { + session.execute("CREATE TABLE IF NOT EXISTS " + session.getLoggedKeyspace() + ".message (" + "mailboxId UUID," + "uid bigint," + "internalDate timestamp," + "bodyStartOctet int," + "content blob," + "modSeq bigint," + "mediaType text," + "subType text," + "fullContentOctets int," + + "bodyOctets int," + "textualLineCount bigint," + "bodyContent blob," + "headerContent blob," + "flagAnswered boolean," + "flagDeleted boolean," + "flagDraft boolean," + "flagRecent boolean," + "flagSeen boolean," + "flagFlagged boolean," + "flagUser boolean," + + "PRIMARY KEY (mailboxId, uid)" + ");"); + } else if (tableName.equals("subscription")) { + session.execute("CREATE TABLE IF NOT EXISTS " + session.getLoggedKeyspace() + ".subscription (" + "user text," + "mailbox text," + "PRIMARY KEY (mailbox, user)" + ");"); + } else { + throw new NotImplementedException("We don't support the class " + tableName); + } + } + + /** + * Ensure all tables + */ + public void ensureAllTables() { + ensureTable("mailbox"); + ensureTable("mailboxCounters"); + ensureTable("message"); + ensureTable("subscription"); + } + + /** + * Delete all rows from specified table. + * + * @param tableName + */ + public void clearTable(String tableName) { + session.execute("TRUNCATE " + tableName + ";"); + } + + /** + * Delete all rows for all tables. + */ + public void clearAllTables() { + clearTable("mailbox"); + clearTable("mailboxCounters"); + clearTable("message"); + clearTable("subscription"); + } + +}
Added: james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java?rev=1617517&view=auto ============================================================================== --- james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java (added) +++ james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java Tue Aug 12 16:08:57 2014 @@ -0,0 +1,90 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ +package org.apache.james.mailbox.cassandra; + +import org.apache.james.mailbox.AbstractMailboxManagerTest; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.cassandra.mail.CassandraModSeqProvider; +import org.apache.james.mailbox.cassandra.mail.CassandraUidProvider; +import org.apache.james.mailbox.cassandra.table.CassandraMailboxTable; +import org.apache.james.mailbox.exception.BadCredentialsException; +import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.store.JVMMailboxPathLocker; +import org.junit.After; +import org.junit.Before; +import org.slf4j.LoggerFactory; + +/** + * CassandraMailboxManagerTest that extends the StoreMailboxManagerTest. + * + */ +public class CassandraMailboxManagerTest extends AbstractMailboxManagerTest { + + private static final CassandraClusterSingleton CLUSTER = CassandraClusterSingleton.build(); + + /** + * Setup the mailboxManager. + * + * @throws Exception + */ + @Before + public void setup() throws Exception { + CLUSTER.ensureAllTables(); + CLUSTER.clearAllTables(); + createMailboxManager(); + } + + /** + * Close the system session and entityManagerFactory + * + * @throws MailboxException + * @throws BadCredentialsException + */ + @After + public void tearDown() throws Exception { + deleteAllMailboxes(); + MailboxSession session = getMailboxManager().createSystemSession("test", LoggerFactory.getLogger("Test")); + session.close(); + } + + /* + * (non-Javadoc)i deve + * + * @see org.apache.james.mailbox.MailboxManagerTest#createMailboxManager() + */ + @Override + protected void createMailboxManager() throws MailboxException { + final CassandraUidProvider uidProvider = new CassandraUidProvider(CLUSTER.getConf()); + final CassandraModSeqProvider modSeqProvider = new CassandraModSeqProvider(CLUSTER.getConf()); + final CassandraMailboxSessionMapperFactory mapperFactory = new CassandraMailboxSessionMapperFactory(uidProvider, modSeqProvider, (CassandraSession) CLUSTER.getConf()); + + final CassandraMailboxManager manager = new CassandraMailboxManager(mapperFactory, null, new JVMMailboxPathLocker()); + manager.init(); + + setMailboxManager(manager); + + deleteAllMailboxes(); + } + + private void deleteAllMailboxes() throws BadCredentialsException, MailboxException { + MailboxSession session = getMailboxManager().createSystemSession("test", LoggerFactory.getLogger("Test")); + CLUSTER.clearTable(CassandraMailboxTable.TABLE_NAME); + session.close(); + } +} Added: james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactoryTest.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactoryTest.java?rev=1617517&view=auto ============================================================================== --- james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactoryTest.java (added) +++ james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactoryTest.java Tue Aug 12 16:08:57 2014 @@ -0,0 +1,121 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ +package org.apache.james.mailbox.cassandra; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.UUID; + +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.cassandra.mail.CassandraModSeqProvider; +import org.apache.james.mailbox.cassandra.mail.CassandraUidProvider; +import org.apache.james.mailbox.store.mail.MailboxMapper; +import org.apache.james.mailbox.store.mail.MessageMapper; +import org.apache.james.mailbox.store.mail.ModSeqProvider; +import org.apache.james.mailbox.store.mail.UidProvider; +import org.apache.james.mailbox.store.user.SubscriptionMapper; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The MailboxSessionMapperFactory test. + * + */ +public class CassandraMailboxSessionMapperFactoryTest { + private static final CassandraClusterSingleton CLUSTER = CassandraClusterSingleton.build(); + private final static Logger LOG = LoggerFactory.getLogger(CassandraMailboxSessionMapperFactoryTest.class); + + @Before + public void beforeMethod() { + CLUSTER.ensureAllTables(); + CLUSTER.clearAllTables(); + } + + /** + * Test of createMessageMapper method, of class + * CassandraMailboxSessionMapperFactory. + */ + @Test + public void testCreateMessageMapper() throws Exception { + LOG.info("createMessageMapper"); + MailboxSession session = null; + CassandraMailboxSessionMapperFactory instance = new CassandraMailboxSessionMapperFactory(null, null, null); + MessageMapper<UUID> messageMapper = instance.createMessageMapper(session); + assertNotNull(messageMapper); + assertTrue(messageMapper instanceof MessageMapper); + } + + /** + * Test of createMailboxMapper method, of class + * CassandraMailboxSessionMapperFactory. + */ + @Test + public void testCreateMailboxMapper() throws Exception { + LOG.info("createMailboxMapper"); + MailboxSession session = null; + CassandraMailboxSessionMapperFactory instance = new CassandraMailboxSessionMapperFactory(null, null, null); + MailboxMapper<UUID> mailboxMapper = instance.createMailboxMapper(session); + assertNotNull(mailboxMapper); + assertTrue(mailboxMapper instanceof MailboxMapper); + } + + /** + * Test of createSubscriptionMapper method, of class + * CassandraMailboxSessionMapperFactory. + */ + @Test + public void testCreateSubscriptionMapper() throws Exception { + LOG.info("createSubscriptionMapper"); + MailboxSession session = null; + CassandraMailboxSessionMapperFactory instance = new CassandraMailboxSessionMapperFactory(null, null, null); + SubscriptionMapper subscriptionMapper = instance.createSubscriptionMapper(session); + assertNotNull(subscriptionMapper); + assertTrue(subscriptionMapper instanceof SubscriptionMapper); + } + + /** + * Test of getModSeqProvider method, of class + * CassandraMailboxSessionMapperFactory. + */ + @Test + public void testGetModSeqProvider() { + LOG.info("getModSeqProvider"); + ModSeqProvider<UUID> expResult = new CassandraModSeqProvider(CLUSTER.getConf()); + CassandraMailboxSessionMapperFactory instance = new CassandraMailboxSessionMapperFactory(null, expResult, null); + ModSeqProvider<UUID> result = instance.getModSeqProvider(); + assertEquals(expResult, result); + } + + /** + * Test of getUidProvider method, of class + * CassandraMailboxSessionMapperFactory. + */ + @Test + public void testGetUidProvider() { + LOG.info("getUidProvider"); + UidProvider<UUID> expResult = new CassandraUidProvider(CLUSTER.getConf()); + CassandraMailboxSessionMapperFactory instance = new CassandraMailboxSessionMapperFactory((CassandraUidProvider) expResult, null, null); + UidProvider<UUID> result = instance.getUidProvider(); + assertEquals(expResult, result); + } +} Added: james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java?rev=1617517&view=auto ============================================================================== --- james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java (added) +++ james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java Tue Aug 12 16:08:57 2014 @@ -0,0 +1,240 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ +package org.apache.james.mailbox.cassandra.mail; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.UUID; + +import org.apache.james.mailbox.cassandra.CassandraClusterSingleton; +import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.exception.MailboxNotFoundException; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.store.mail.model.Mailbox; +import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.datastax.driver.core.Session; + +/** + * CassandraMailboxMapper unit tests. + * + */ +public class CassandraMailboxMapperTest { + + private static final Logger LOG = LoggerFactory.getLogger(CassandraMailboxMapperTest.class); + public static final CassandraClusterSingleton CLUSTER = CassandraClusterSingleton.build(); + private static CassandraMailboxMapper mapper; + private static List<SimpleMailbox<UUID>> mailboxList; + private static List<MailboxPath> pathsList; + private static final int NAMESPACES = 5; + private static final int USERS = 5; + private static final int MAILBOX_NO = 5; + private static final char SEPARATOR = '%'; + private Session session; + + @Before + public void setUp() throws Exception { + CLUSTER.ensureAllTables(); + CLUSTER.clearAllTables(); + session = CLUSTER.getConf(); + fillMailboxList(); + mapper = new CassandraMailboxMapper(session); + for (SimpleMailbox<UUID> mailbox : mailboxList) { + mapper.save(mailbox); + } + } + + /** + * Test an ordered scenario with list, delete... methods. + * + * @throws Exception + */ + @Test + public void testMailboxMapperScenario() throws Exception { + testFindMailboxByPath(); + testFindMailboxWithPathLike(); + testList(); + testSave(); + testDelete(); + testHasChildren(); + // testDeleteAllMemberships(); // Ignore this test + } + + /** + * Test of findMailboxByPath method, of class CassandraMailboxMapper. + */ + private void testFindMailboxByPath() throws Exception { + LOG.info("findMailboxByPath"); + SimpleMailbox<UUID> mailbox; + for (MailboxPath path : pathsList) { + LOG.info("Searching for " + path); + mailbox = (SimpleMailbox<UUID>) mapper.findMailboxByPath(path); + assertEquals(path, new MailboxPath(mailbox.getNamespace(), mailbox.getUser(), mailbox.getName())); + } + } + + /** + * Test of findMailboxWithPathLike method, of class CassandraMailboxMapper. + */ + private void testFindMailboxWithPathLike() throws Exception { + LOG.info("findMailboxWithPathLike"); + MailboxPath path = pathsList.get(pathsList.size() / 2); + + List<Mailbox<UUID>> result = mapper.findMailboxWithPathLike(path); + assertEquals(1, result.size()); + + int start = 3; + int end = 7; + MailboxPath newPath; + + for (int i = start; i < end; i++) { + newPath = new MailboxPath(path); + newPath.setName(i + newPath.getName() + " " + i); + // test for paths with null user + if (i % 2 == 0) { + newPath.setUser(null); + } + addMailbox(new SimpleMailbox<UUID>(newPath, 1234)); + } + result = mapper.findMailboxWithPathLike(path); + assertEquals(end - start + 1, result.size()); + } + + /** + * Test of list method, of class CassandraMailboxMapper. + */ + private void testList() throws Exception { + LOG.info("list"); + List<Mailbox<UUID>> result = mapper.list(); + assertEquals(mailboxList.size(), result.size()); + + } + + /** + * Test of save method and list method, of class CassandraMailboxMapper. + */ + private void testSave() throws Exception { + LOG.info("save and mailboxFromResult"); + final List<Mailbox<UUID>> mailboxes = mapper.list(); + final SimpleMailbox<UUID> mlbx = mailboxList.get(mailboxList.size() / 2); + Mailbox<UUID> newValue = mailboxes.get(0); + + for (Mailbox<UUID> mailbox : mailboxes) { + if (mlbx.getMailboxId().equals(mailbox.getMailboxId())) { + newValue = mailbox; + } + } + + assertEquals(mlbx, newValue); + assertEquals(mlbx.getUser(), newValue.getUser()); + assertEquals(mlbx.getName(), newValue.getName()); + assertEquals(mlbx.getNamespace(), newValue.getNamespace()); + assertEquals(mlbx.getMailboxId(), newValue.getMailboxId()); + } + + /** + * Test of delete method, of class CassandraMailboxMapper. + */ + private void testDelete() throws Exception { + LOG.info("delete"); + // delete last 5 mailboxes from mailboxList + int offset = 5; + int notFoundCount = 0; + + Iterator<SimpleMailbox<UUID>> iterator = mailboxList.subList(mailboxList.size() - offset, mailboxList.size()).iterator(); + + while (iterator.hasNext()) { + SimpleMailbox<UUID> mailbox = iterator.next(); + mapper.delete(mailbox); + iterator.remove(); + MailboxPath path = new MailboxPath(mailbox.getNamespace(), mailbox.getUser(), mailbox.getName()); + pathsList.remove(path); + LOG.info("Removing mailbox: {}", path); + try { + mapper.findMailboxByPath(path); + } catch (MailboxNotFoundException e) { + LOG.info("Succesfully removed {}", mailbox); + notFoundCount++; + } + } + assertEquals(offset, notFoundCount); + assertEquals(mailboxList.size(), mapper.list().size()); + } + + /** + * Test of hasChildren method, of class CassandraMailboxMapper. + */ + private void testHasChildren() throws Exception { + LOG.info("hasChildren"); + String oldName; + for (MailboxPath path : pathsList) { + final SimpleMailbox<UUID> mailbox = new SimpleMailbox<UUID>(path, 12455); + oldName = mailbox.getName(); + if (path.getUser().equals("user3")) { + mailbox.setName("test"); + } + boolean result = mapper.hasChildren(mailbox, SEPARATOR); + mailbox.setName(oldName); + if (path.getUser().equals("user3")) { + assertTrue(result); + } else { + assertFalse(result); + } + + } + } + + private static void fillMailboxList() { + mailboxList = new ArrayList<SimpleMailbox<UUID>>(); + pathsList = new ArrayList<MailboxPath>(); + MailboxPath path; + String name; + for (int i = 0; i < NAMESPACES; i++) { + for (int j = 0; j < USERS; j++) { + for (int k = 0; k < MAILBOX_NO; k++) { + if (j == 3) { + name = "test" + SEPARATOR + "subbox" + k; + } else { + name = "mailbox" + k; + } + path = new MailboxPath("namespace" + i, "user" + j, name); + pathsList.add(path); + mailboxList.add(new SimpleMailbox<UUID>(path, 13)); + } + } + } + LOG.info("Created test case with {} mailboxes and {} paths", mailboxList.size(), pathsList.size()); + } + + private void addMailbox(SimpleMailbox<UUID> mailbox) throws MailboxException { + mailboxList.add(mailbox); + pathsList.add(new MailboxPath(mailbox.getNamespace(), mailbox.getUser(), mailbox.getName())); + mapper.save(mailbox); + LOG.info("Added new mailbox: {} paths: {}", mailboxList.size(), pathsList.size()); + } +} Added: james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapperTest.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapperTest.java?rev=1617517&view=auto ============================================================================== --- james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapperTest.java (added) +++ james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapperTest.java Tue Aug 12 16:08:57 2014 @@ -0,0 +1,208 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ +package org.apache.james.mailbox.cassandra.mail; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Random; +import java.util.UUID; + +import javax.mail.Flags; +import javax.mail.internet.SharedInputStream; +import javax.mail.util.SharedByteArrayInputStream; + +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.cassandra.CassandraClusterSingleton; +import org.apache.james.mailbox.mock.MockMailboxSession; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.store.mail.model.Mailbox; +import org.apache.james.mailbox.store.mail.model.Message; +import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder; +import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox; +import org.apache.james.mailbox.store.mail.model.impl.SimpleMessage; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.datastax.driver.core.Session; + +/** + * Unit tests for CassandraMessageMapper. + * + */ +public class CassandraMessageMapperTest { + + private static final Logger LOG = LoggerFactory.getLogger(CassandraMailboxMapperTest.class); + public static final CassandraClusterSingleton CLUSTER = CassandraClusterSingleton.build(); + private static CassandraUidProvider uidProvider; + private static CassandraModSeqProvider modSeqProvider; + private static CassandraMessageMapper messageMapper; + private static final List<MailboxPath> MBOX_PATHS = new ArrayList<MailboxPath>(); + private static final List<Mailbox<UUID>> MBOXES = new ArrayList<Mailbox<UUID>>(); + private static final List<Message<UUID>> MESSAGE_NO = new ArrayList<Message<UUID>>(); + private static final int COUNT = 5; + private static Session session; + /* + * we mock a simple message content + */ + private static final String messageTemplate = "Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)\n" + "From: Fred Foobar <[email protected]>\n" + "Subject: Test 02\n" + "To: [email protected]\n" + "Message-Id: <[email protected]>\n" + "MIME-Version: 1.0\n" + + "Content-Type: TEXT/PLAIN; CHARSET=US-ASCII\n" + "\n" + "Test\n" + "\n."; + + private static SharedInputStream content = new SharedByteArrayInputStream(messageTemplate.getBytes()); + + @Before + public void setUp() throws Exception { + CLUSTER.ensureAllTables(); + CLUSTER.clearAllTables(); + session = CLUSTER.getConf(); + uidProvider = new CassandraUidProvider(session); + modSeqProvider = new CassandraModSeqProvider(session); + generateTestData(); + final MailboxSession mailboxSession = new MockMailboxSession("ieugen"); + messageMapper = new CassandraMessageMapper(session, uidProvider, modSeqProvider, mailboxSession); + for (int i = 0; i < MESSAGE_NO.size(); i++) { + messageMapper.add(MBOXES.get(1), MESSAGE_NO.get(i)); + } + } + + public static void generateTestData() { + final Random random = new Random(); + MailboxPath mboxPath; + final PropertyBuilder propBuilder = new PropertyBuilder(); + SimpleMailbox<UUID> mailbox; + + for (int i = 0; i < COUNT; i++) { + if (i % 2 == 0) { + mboxPath = new MailboxPath("gsoc", "ieugen" + i, "INBOX"); + } else { + mboxPath = new MailboxPath("gsoc", "ieugen" + i, "INBOX.box" + i); + } + MBOX_PATHS.add(mboxPath); + mailbox = new SimpleMailbox<UUID>(MBOX_PATHS.get(i), random.nextLong()); + mailbox.setMailboxId(UUID.randomUUID()); + MBOXES.add(mailbox); + propBuilder.setProperty("gsoc", "prop" + i, "value"); + } + propBuilder.setMediaType("text"); + propBuilder.setSubType("html"); + propBuilder.setTextualLineCount(2L); + + SimpleMessage<UUID> myMsg; + final Flags flags = new Flags(Flags.Flag.RECENT); + final Date today = new Date(); + + for (int i = 0; i < COUNT * 2; i++) { + myMsg = new SimpleMessage<UUID>(today, messageTemplate.getBytes().length, messageTemplate.getBytes().length - 20, content, flags, propBuilder, MBOXES.get(1).getMailboxId()); + if (i == COUNT * 2 - 1) { + flags.add(Flags.Flag.SEEN); + flags.remove(Flags.Flag.RECENT); + myMsg.setFlags(flags); + } + MESSAGE_NO.add(myMsg); + } + } + + /** + * Test an ordered scenario with count, find, add... methods. + * + * @throws Exception + */ + @Test + public void testMessageMapperScenario() throws Exception { + testCountMessagesInMailbox(); + testCountUnseenMessagesInMailbox(); + testFindFirstUnseenMessageUid(); + testFindRecentMessageUidsInMailbox(); + testAdd(); + testGetLastUid(); + testGetHighestModSeq(); + } + + /** + * Test of countMessagesInMailbox method, of class CassandraMessageMapper. + */ + private void testCountMessagesInMailbox() throws Exception { + LOG.info("countMessagesInMailbox"); + long messageCount = messageMapper.countMessagesInMailbox(MBOXES.get(1)); + assertEquals(MESSAGE_NO.size(), messageCount); + } + + /** + * Test of countUnseenMessagesInMailbox method, of class + * CassandraMessageMapper. + */ + private void testCountUnseenMessagesInMailbox() throws Exception { + LOG.info("countUnseenMessagesInMailbox"); + long unseen = messageMapper.countUnseenMessagesInMailbox(MBOXES.get(1)); + assertEquals(MESSAGE_NO.size() - 1, unseen); + } + + /** + * Test of findFirstUnseenMessageUid method, of class + * CassandraMessageMapper. + */ + private void testFindFirstUnseenMessageUid() throws Exception { + LOG.info("findFirstUnseenMessageUid"); + final long uid = messageMapper.findFirstUnseenMessageUid(MBOXES.get(1)); + assertEquals(1, uid); + } + + /** + * Test of findRecentMessageUidsInMailbox method, of class + * CassandraMessageMapper. + */ + private void testFindRecentMessageUidsInMailbox() throws Exception { + LOG.info("findRecentMessageUidsInMailbox"); + List<Long> recentMessages = messageMapper.findRecentMessageUidsInMailbox(MBOXES.get(1)); + assertEquals(MESSAGE_NO.size() - 1, recentMessages.size()); + } + + /** + * Test of add method, of class CassandraMessageMapper. + */ + private void testAdd() throws Exception { + LOG.info("add"); + // The tables should be deleted every time the tests run. + long msgCount = messageMapper.countMessagesInMailbox(MBOXES.get(1)); + LOG.info(msgCount + " " + MESSAGE_NO.size()); + assertEquals(MESSAGE_NO.size(), msgCount); + } + + /** + * Test of getLastUid method, of class CassandraMessageMapper. + */ + private void testGetLastUid() throws Exception { + LOG.info("getLastUid"); + long lastUid = messageMapper.getLastUid(MBOXES.get(1)); + assertEquals(MESSAGE_NO.size(), lastUid); + } + + /** + * Test of getHighestModSeq method, of class CassandraMessageMapper. + */ + private void testGetHighestModSeq() throws Exception { + LOG.info("getHighestModSeq"); + long highestModSeq = messageMapper.getHighestModSeq(MBOXES.get(1)); + assertEquals(MESSAGE_NO.size(), highestModSeq); + } +} Added: james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidAndModSeqProviderTest.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidAndModSeqProviderTest.java?rev=1617517&view=auto ============================================================================== --- james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidAndModSeqProviderTest.java (added) +++ james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidAndModSeqProviderTest.java Tue Aug 12 16:08:57 2014 @@ -0,0 +1,163 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ +package org.apache.james.mailbox.cassandra.mail; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.apache.james.mailbox.cassandra.CassandraClusterSingleton; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.datastax.driver.core.Session; + +/** + * Unit tests for UidProvider and ModSeqProvider. + * + */ +public class CassandraUidAndModSeqProviderTest { + + private static final Logger LOG = LoggerFactory.getLogger(CassandraUidAndModSeqProviderTest.class); + private static final CassandraClusterSingleton CLUSTER = CassandraClusterSingleton.build(); + private static Session session; + private static CassandraUidProvider uidProvider; + private static CassandraModSeqProvider modSeqProvider; + private static CassandraMailboxMapper mapper; + private static List<SimpleMailbox<UUID>> mailboxList; + private static List<MailboxPath> pathsList; + private static final int NAMESPACES = 5; + private static final int USERS = 5; + private static final int MAILBOX_NO = 5; + private static final char SEPARATOR = '%'; + + @Before + public void setUpClass() throws Exception { + CLUSTER.ensureAllTables(); + CLUSTER.ensureAllTables(); + session = CLUSTER.getConf(); + uidProvider = new CassandraUidProvider(session); + modSeqProvider = new CassandraModSeqProvider(session); + mapper = new CassandraMailboxMapper(session); + fillMailboxList(); + for (SimpleMailbox<UUID> mailbox : mailboxList) { + mapper.save(mailbox); + } + } + + private static void fillMailboxList() { + mailboxList = new ArrayList<SimpleMailbox<UUID>>(); + pathsList = new ArrayList<MailboxPath>(); + MailboxPath path; + String name; + for (int i = 0; i < NAMESPACES; i++) { + for (int j = 0; j < USERS; j++) { + for (int k = 0; k < MAILBOX_NO; k++) { + if (j == 3) { + name = "test" + SEPARATOR + "subbox" + k; + } else { + name = "mailbox" + k; + } + path = new MailboxPath("namespace" + i, "user" + j, name); + pathsList.add(path); + mailboxList.add(new SimpleMailbox<UUID>(path, 13)); + } + } + } + + LOG.info("Created test case with {} mailboxes and {} paths", mailboxList.size(), pathsList.size()); + } + + /** + * Test of lastUid method, of class CassandraUidProvider. + */ + @Test + public void testLastUid() throws Exception { + LOG.info("lastUid"); + final MailboxPath path = new MailboxPath("gsoc", "ieugen", "Trash"); + final SimpleMailbox<UUID> newBox = new SimpleMailbox<UUID>(path, 1234); + mapper.save(newBox); + mailboxList.add(newBox); + pathsList.add(path); + + final long result = uidProvider.lastUid(null, newBox); + assertEquals(0, result); + for (int i = 1; i < 10; i++) { + final long uid = uidProvider.nextUid(null, newBox); + assertEquals(uid, uidProvider.lastUid(null, newBox)); + } + } + + /** + * Test of nextUid method, of class CassandraUidProvider. + */ + @Test + public void testNextUid() throws Exception { + LOG.info("nextUid"); + final SimpleMailbox<UUID> mailbox = mailboxList.get(mailboxList.size() / 2); + final long lastUid = uidProvider.lastUid(null, mailbox); + long result; + for (int i = (int) lastUid + 1; i < (lastUid + 10); i++) { + result = uidProvider.nextUid(null, mailbox); + assertEquals(i, result); + } + } + + /** + * Test of highestModSeq method, of class CassandraModSeqProvider. + */ + @Test + public void testHighestModSeq() throws Exception { + LOG.info("highestModSeq"); + LOG.info("lastUid"); + MailboxPath path = new MailboxPath("gsoc", "ieugen", "Trash"); + SimpleMailbox<UUID> newBox = new SimpleMailbox<UUID>(path, 1234); + mapper.save(newBox); + mailboxList.add(newBox); + pathsList.add(path); + + long result = modSeqProvider.highestModSeq(null, newBox); + assertEquals(0, result); + for (int i = 1; i < 10; i++) { + long uid = modSeqProvider.nextModSeq(null, newBox); + assertEquals(uid, modSeqProvider.highestModSeq(null, newBox)); + } + } + + /** + * Test of nextModSeq method, of class CassandraModSeqProvider. + */ + @Test + public void testNextModSeq() throws Exception { + LOG.info("nextModSeq"); + final SimpleMailbox<UUID> mailbox = mailboxList.get(mailboxList.size() / 2); + final long lastUid = modSeqProvider.highestModSeq(null, mailbox); + long result; + for (int i = (int) lastUid + 1; i < (lastUid + 10); i++) { + result = modSeqProvider.nextModSeq(null, mailbox); + assertEquals(i, result); + } + } +} Added: james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapperTest.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapperTest.java?rev=1617517&view=auto ============================================================================== --- james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapperTest.java (added) +++ james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapperTest.java Tue Aug 12 16:08:57 2014 @@ -0,0 +1,178 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ +package org.apache.james.mailbox.cassandra.user; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.james.mailbox.cassandra.CassandraClusterSingleton; +import org.apache.james.mailbox.store.user.model.Subscription; +import org.apache.james.mailbox.store.user.model.impl.SimpleSubscription; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.datastax.driver.core.Session; + +/** + * Runs tests for SubscriptionMapper. + * + */ +public class CassandraSubscriptionMapperTest { + + private static final Logger LOG = LoggerFactory.getLogger(CassandraSubscriptionMapperTest.class); + private static final CassandraClusterSingleton CLUSTER = CassandraClusterSingleton.build(); + private static Session session; + private static CassandraSubscriptionMapper mapper; + private static Map<String, List<SimpleSubscription>> subscriptionList; + private static final int USERS = 5; + private static final int MAILBOX_NO = 5; + + @Before + public void setUp() throws Exception { + CLUSTER.ensureAllTables(); + CLUSTER.clearAllTables(); + session = CLUSTER.getConf(); + mapper = new CassandraSubscriptionMapper(session); + fillSubscriptionList(); + } + + private static void fillSubscriptionList() { + LOG.info("Creating subscription list"); + SimpleSubscription subscription; + String user, mailbox; + subscriptionList = new HashMap<String, List<SimpleSubscription>>(); + for (int i = 0; i < USERS; i++) { + user = "user" + i; + final List<SimpleSubscription> mailboxes = new ArrayList<SimpleSubscription>(); + subscriptionList.put(user, mailboxes); + + for (int j = 0; j < MAILBOX_NO; j++) { + if (j == 0) { + mailbox = "INBOX"; + } else { + mailbox = "BOX" + j; + } + if ((i % 2 == 0) && (j > 0)) { + continue; + } + subscription = new SimpleSubscription(user, mailbox); + mailboxes.add(subscription); + mapper.save(subscription); + LOG.info("Adding subscription " + subscription); + } + } + } + + /** + * Test of findMailboxSubscriptionForUser method, of class + * CassandraSubscriptionMapper. + */ + @Test + public void testFindMailboxSubscriptionForUser() throws Exception { + LOG.info("findMailboxSubscriptionForUser"); + + final SimpleSubscription fake1 = new SimpleSubscription("user1", "FAKEBOX"); + final SimpleSubscription fake2 = new SimpleSubscription("fakeUser", "INBOX"); + + for (String user : subscriptionList.keySet()) { + LOG.info("Searching for all subscriptions for user:{}", user); + for (SimpleSubscription subscription : subscriptionList.get(user)) { + final Subscription result = mapper.findMailboxSubscriptionForUser(user, subscription.getMailbox()); + assertEquals(subscription.getMailbox(), result.getMailbox()); + assertEquals(subscription.getUser(), result.getUser()); + } + } + assertNull(mapper.findMailboxSubscriptionForUser(fake1.getUser(), fake1.getMailbox())); + assertNull(mapper.findMailboxSubscriptionForUser(fake2.getUser(), fake2.getMailbox())); + } + + /** + * Test of save method, of class CassandraSubscriptionMapper. + */ + @Test + public void testSave() throws Exception { + LOG.info("save"); + final List<SimpleSubscription> subscriptions = mapper.list(); + for (String user : subscriptionList.keySet()) { + for (Subscription subscription : subscriptionList.get(user)) { + assertTrue(containSubscription(subscriptions, subscription)); + } + } + } + + /** + * Test of findSubscriptionsForUser method, of class + * CassandraSubscriptionMapper. + */ + @Test + public void testFindSubscriptionsForUser() throws Exception { + LOG.info("findSubscriptionsForUser"); + final SimpleSubscription fake2 = new SimpleSubscription("fakeUser", "INBOX"); + for (String user : subscriptionList.keySet()) { + LOG.info("Searching for all subscriptions for user: " + user); + final List<Subscription> found = mapper.findSubscriptionsForUser(user); + assertEquals(subscriptionList.get(user).size(), found.size()); + // TODO: patch Subscription to implement equals + // assertTrue(subscriptionList.get(user).containsAll(foundSubscriptions)); + // assertTrue(foundSubscriptions.containsAll(subscriptionList.get(user))); + // assertFalse(foundSubscriptions.contains(fake1)); + // assertFalse(foundSubscriptions.contains(fake2)); + } + // TODO: check what value we should return in case of no subscriptions: + // null or empty list + assertEquals(mapper.findSubscriptionsForUser(fake2.getMailbox()).size(), 0); + + } + + /** + * Test of delete method, of class CassandraSubscriptionMapper. + */ + @Test + public void testDelete() throws Exception { + LOG.info("delete"); + for (String user : subscriptionList.keySet()) { + LOG.info("Deleting subscriptions for user: " + user); + for (SimpleSubscription subscription : subscriptionList.get(user)) { + LOG.info("Deleting subscription : " + subscription); + mapper.delete(subscription); + assertFalse(containSubscription(mapper.list(), subscription)); + } + } + fillSubscriptionList(); + } + + private boolean containSubscription(List<SimpleSubscription> subscriptions, Subscription subscription) { + for (SimpleSubscription s : subscriptions) { + if (subscription.getMailbox().equals(s.getMailbox()) && subscription.getUser().equals(s.getUser())) { + return true; + } + } + return false; + } + +} Modified: james/mailbox/trunk/pom.xml URL: http://svn.apache.org/viewvc/james/mailbox/trunk/pom.xml?rev=1617517&r1=1617516&r2=1617517&view=diff ============================================================================== --- james/mailbox/trunk/pom.xml (original) +++ james/mailbox/trunk/pom.xml Tue Aug 12 16:08:57 2014 @@ -52,6 +52,7 @@ <module>api</module> <module>caching</module> <module>hbase</module> + <module>cassandra</module> <module>jcr</module> <module>jpa</module> <module>lucene</module> @@ -114,10 +115,12 @@ <geronimo-activation-spec.version>1.1</geronimo-activation-spec.version> <geronimo-javamail-mail.version>1.8.3</geronimo-javamail-mail.version> <apache-mailet.version>2.5.0</apache-mailet.version> - <slf4j.version>1.7.2</slf4j.version> + <slf4j.version>1.7.7</slf4j.version> <junit.version>4.11</junit.version> <jasypt.version>1.9.0</jasypt.version> <guava.version>13.0</guava.version> + <cassandra-driver-core.version>2.0.1</cassandra-driver-core.version> + <cassandra-unit.version>2.0.2.1</cassandra-unit.version> </properties> <dependencyManagement> @@ -191,7 +194,13 @@ <artifactId>apache-james-mailbox-hbase</artifactId> <version>${project.version}</version> </dependency> - <dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>apache-james-mailbox-cassandra</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> <groupId>org.apache.james</groupId> <artifactId>apache-james-mailbox-tool</artifactId> <version>${project.version}</version> @@ -502,7 +511,6 @@ <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> - <!-- END SPRING --> @@ -514,6 +522,16 @@ <groupId>org.apache.hbase</groupId> <artifactId>hbase</artifactId> <version>${hbase.version}</version> + <exclusions> + <exclusion> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-core-asl</artifactId> + </exclusion> + <exclusion> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-mapper-asl</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>org.apache.hbase</groupId> @@ -536,7 +554,7 @@ <!-- END HBASE/HADOOP --> - </dependencies> + </dependencies> </dependencyManagement> <build> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
