Author: eric
Date: Tue Aug 12 16:08:57 2014
New Revision: 1617517
URL: http://svn.apache.org/r1617517
Log:
Add a Cassandra Mailbox implementation, contributed by Philippe Benoit
(MAILBOX-12)
Added:
james/mailbox/trunk/cassandra/
james/mailbox/trunk/cassandra/pom.xml
james/mailbox/trunk/cassandra/src/
james/mailbox/trunk/cassandra/src/main/
james/mailbox/trunk/cassandra/src/main/java/
james/mailbox/trunk/cassandra/src/main/java/org/
james/mailbox/trunk/cassandra/src/main/java/org/apache/
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSession.java
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManager.java
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/
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/mail/CassandraMessageMapper.java
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProvider.java
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProvider.java
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxCountersTable.java
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxTable.java
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageTable.java
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageUidTable.java
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraSubscriptionTable.java
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/user/
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapper.java
james/mailbox/trunk/cassandra/src/main/resources/
james/mailbox/trunk/cassandra/src/main/resources/META-INF/
james/mailbox/trunk/cassandra/src/main/resources/META-INF/spring/
james/mailbox/trunk/cassandra/src/main/resources/META-INF/spring/mailbox-cassandra.xml
james/mailbox/trunk/cassandra/src/reporting-site/
james/mailbox/trunk/cassandra/src/reporting-site/site.xml
james/mailbox/trunk/cassandra/src/test/
james/mailbox/trunk/cassandra/src/test/java/
james/mailbox/trunk/cassandra/src/test/java/org/
james/mailbox/trunk/cassandra/src/test/java/org/apache/
james/mailbox/trunk/cassandra/src/test/java/org/apache/james/
james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/
james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/
james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraClusterSingleton.java
james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactoryTest.java
james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/
james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapperTest.java
james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidAndModSeqProviderTest.java
james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/user/
james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapperTest.java
james/mailbox/trunk/cassandra/src/test/resources/
Removed:
james/mailbox/trunk/.gitignore
Modified:
james/mailbox/trunk/pom.xml
Added: james/mailbox/trunk/cassandra/pom.xml
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/pom.xml?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/pom.xml (added)
+++ james/mailbox/trunk/cassandra/pom.xml Tue Aug 12 16:08:57 2014
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>apache-james-mailbox</artifactId>
+ <groupId>org.apache.james</groupId>
+ <version>0.6-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>apache-james-mailbox-cassandra</artifactId>
+ <description>Apache James Mailbox implementation over
Cassandra</description>
+ <name>Apache James :: Mailbox :: Cassandra</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${javax.mail.groupId}</groupId>
+ <artifactId>${javax.mail.artifactId}</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>apache-james-mailbox-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>apache-james-mailbox-store</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>apache-james-mailbox-api</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>com.datastax.cassandra</groupId>
+ <artifactId>cassandra-driver-core</artifactId>
+ <version>${cassandra-driver-core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.cassandraunit</groupId>
+ <artifactId>cassandra-unit</artifactId>
+ <version>${cassandra-unit.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>noTest</id>
+ <activation>
+ <os>
+ <family>windows</family>
+ </os>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <skipTests>true</skipTests>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <mainClass>fully.qualified.MainClass</mainClass>
+ </manifest>
+ </archive>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
Added:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java?rev=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java
(added)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,57 @@
+/****************************************************************
+ * 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 java.util.UUID;
+
+import org.apache.james.mailbox.MailboxPathLocker;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
+import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.store.Authenticator;
+import org.apache.james.mailbox.store.StoreMailboxManager;
+import org.apache.james.mailbox.store.StoreMessageManager;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
+
+/**
+ * Cassandra implementation of {@link StoreMailboxManager}
+ */
+public class CassandraMailboxManager extends StoreMailboxManager<UUID> {
+ private MailboxPathLocker locker;
+
+ public CassandraMailboxManager(CassandraMailboxSessionMapperFactory
mapperFactory, Authenticator authenticator, final MailboxPathLocker locker) {
+ super(mapperFactory, authenticator, locker, new
UnionMailboxACLResolver(), new SimpleGroupMembershipResolver());
+ this.locker = locker;
+ }
+
+ @Override
+ protected Mailbox<UUID> doCreateMailbox(MailboxPath mailboxPath,
MailboxSession session) throws MailboxException {
+ return new SimpleMailbox<UUID>(mailboxPath, randomUidValidity());
+ }
+
+ @Override
+ protected StoreMessageManager<UUID> createMessageManager(Mailbox<UUID>
mailboxRow, MailboxSession session) throws MailboxException {
+ return new CassandraMessageManager(getMapperFactory(),
getMessageSearchIndex(), getEventDispatcher(), this.locker, mailboxRow);
+ }
+
+}
Added:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java?rev=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
(added)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,74 @@
+/****************************************************************
+ * 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 java.util.UUID;
+
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxMapper;
+import org.apache.james.mailbox.cassandra.mail.CassandraMessageMapper;
+import org.apache.james.mailbox.cassandra.mail.CassandraUidProvider;
+import org.apache.james.mailbox.cassandra.user.CassandraSubscriptionMapper;
+import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
+import org.apache.james.mailbox.store.mail.MailboxMapper;
+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 com.datastax.driver.core.Session;
+
+/**
+ * Cassandra implementation of {@link MailboxSessionMapperFactory}
+ *
+ */
+public class CassandraMailboxSessionMapperFactory extends
MailboxSessionMapperFactory<UUID> {
+ private Session session;
+ private CassandraUidProvider uidProvider;
+ private ModSeqProvider<UUID> modSeqProvider;
+
+ public CassandraMailboxSessionMapperFactory(CassandraUidProvider
uidProvider, ModSeqProvider<UUID> modSeqProvider, CassandraSession session) {
+ this.uidProvider = uidProvider;
+ this.modSeqProvider = modSeqProvider;
+ this.session = session;
+ }
+
+ @Override
+ public CassandraMessageMapper createMessageMapper(MailboxSession
mailboxSession) {
+ return new CassandraMessageMapper(session, uidProvider,
modSeqProvider);
+ }
+
+ @Override
+ public MailboxMapper<UUID> createMailboxMapper(MailboxSession
mailboxSession) {
+ return new CassandraMailboxMapper(session);
+ }
+
+ @Override
+ public SubscriptionMapper createSubscriptionMapper(MailboxSession
mailboxSession) {
+ return new CassandraSubscriptionMapper(session);
+ }
+
+ public ModSeqProvider<UUID> getModSeqProvider() {
+ return modSeqProvider;
+ }
+
+ public UidProvider<UUID> getUidProvider() {
+ return uidProvider;
+ }
+}
Added:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java?rev=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
(added)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,57 @@
+/****************************************************************
+ * 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 java.util.UUID;
+
+import javax.mail.Flags;
+
+import org.apache.james.mailbox.MailboxPathLocker;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
+import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.MailboxEventDispatcher;
+import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
+import org.apache.james.mailbox.store.StoreMessageManager;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.search.MessageSearchIndex;
+
+/**
+ * Cassandra implementation of {@link StoreMessageManager}
+ *
+ */
+public class CassandraMessageManager extends StoreMessageManager<UUID> {
+
+ public CassandraMessageManager(MailboxSessionMapperFactory<UUID>
mapperFactory, MessageSearchIndex<UUID> index, MailboxEventDispatcher<UUID>
dispatcher, MailboxPathLocker locker, Mailbox<UUID> mailbox) throws
MailboxException {
+ super(mapperFactory, index, dispatcher, locker, mailbox, new
UnionMailboxACLResolver(), new SimpleGroupMembershipResolver());
+
+ }
+
+ /**
+ * Support user flags
+ */
+ @Override
+ protected Flags getPermanentFlags(MailboxSession session) {
+ Flags flags = super.getPermanentFlags(session);
+ flags.add(Flags.Flag.USER);
+ return flags;
+ }
+}
Added:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSession.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSession.java?rev=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSession.java
(added)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSession.java
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,149 @@
+/****************************************************************
+ * 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 com.datastax.driver.core.CloseFuture;
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.RegularStatement;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.ResultSetFuture;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.Statement;
+import com.google.common.util.concurrent.ListenableFuture;
+
+/**
+ * A Cassandra session with the default keyspace
+ *
+ */
+public class CassandraSession implements Session {
+ private final static String DEFAULT_CLUSTER_IP = "localhost";
+ private final static int DEFAULT_CLUSTER_PORT = 9042;
+ private final static String DEFAULT_KEYSPACE_NAME = "apache_james";
+ private final static int DEFAULT_REPLICATION_FACTOR = 1;
+
+ private Session session;
+
+ public CassandraSession(String ip, int port, String keyspace, int
replicationFactor) {
+ Cluster cluster =
Cluster.builder().addContactPoint(ip).withPort(port).build();
+ if (cluster.getMetadata().getKeyspace(keyspace) == null) {
+ initDatabase(cluster, keyspace, replicationFactor);
+ }
+ session = cluster.connect(keyspace);
+ }
+
+ private void initDatabase(Cluster cluster, String keyspace, int
replicationFactor) {
+ session = cluster.connect();
+ session.execute("CREATE KEYSPACE IF NOT EXISTS " + keyspace + " WITH
replication " + "= {'class':'SimpleStrategy', 'replication_factor':" +
replicationFactor + "};");
+ session.execute("CREATE TABLE IF NOT EXISTS " + keyspace + ".mailbox
(" + "id uuid PRIMARY KEY," + "name text, namespace text," + "uidvalidity
bigint," + "user text," + "path text" + ");");
+ session.execute("CREATE INDEX IF NOT EXISTS ON " + keyspace +
".mailbox(path);");
+ session.execute("CREATE TABLE IF NOT EXISTS " + keyspace +
".messageCounter (" + "mailboxId UUID PRIMARY KEY," + "nextUid bigint," + ");");
+ session.execute("CREATE TABLE IF NOT EXISTS " + keyspace +
".mailboxCounters (" + "mailboxId UUID PRIMARY KEY," + "count counter," +
"unseen counter," + "nextModSeq counter" + ");");
+ session.execute("CREATE TABLE IF NOT EXISTS " + keyspace + ".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)" +
");");
+ session.execute("CREATE TABLE IF NOT EXISTS " + keyspace +
".subscription (" + "user text," + "mailbox text," + "PRIMARY KEY (mailbox,
user)" + ");");
+ session.close();
+ }
+
+ public CassandraSession() {
+ this(DEFAULT_CLUSTER_IP, DEFAULT_CLUSTER_PORT, DEFAULT_KEYSPACE_NAME,
DEFAULT_REPLICATION_FACTOR);
+ }
+
+ @Override
+ public String getLoggedKeyspace() {
+ return session.getLoggedKeyspace();
+ }
+
+ @Override
+ public Session init() {
+ return session.init();
+ }
+
+ @Override
+ public ResultSet execute(String query) {
+ return session.execute(query);
+ }
+
+ @Override
+ public ResultSet execute(String query, Object... values) {
+ return session.execute(query, values);
+ }
+
+ @Override
+ public ResultSet execute(Statement statement) {
+ return session.execute(statement);
+ }
+
+ @Override
+ public ResultSetFuture executeAsync(String query) {
+ return session.executeAsync(query);
+ }
+
+ @Override
+ public ResultSetFuture executeAsync(String query, Object... values) {
+ return session.executeAsync(query, values);
+ }
+
+ @Override
+ public ResultSetFuture executeAsync(Statement statement) {
+ return session.executeAsync(statement);
+ }
+
+ @Override
+ public PreparedStatement prepare(String query) {
+ return session.prepare(query);
+ }
+
+ @Override
+ public PreparedStatement prepare(RegularStatement statement) {
+ return session.prepare(statement);
+ }
+
+ @Override
+ public ListenableFuture<PreparedStatement> prepareAsync(String query) {
+ return session.prepareAsync(query);
+ }
+
+ @Override
+ public ListenableFuture<PreparedStatement> prepareAsync(RegularStatement
statement) {
+ return session.prepareAsync(statement);
+ }
+
+ @Override
+ public CloseFuture closeAsync() {
+ return session.closeAsync();
+ }
+
+ @Override
+ public void close() {
+ session.close();
+ }
+
+ @Override
+ public boolean isClosed() {
+ return session.isClosed();
+ }
+
+ @Override
+ public Cluster getCluster() {
+ return session.getCluster();
+ }
+
+}
Added:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManager.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManager.java?rev=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManager.java
(added)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManager.java
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.MailboxSession;
+import org.apache.james.mailbox.store.StoreSubscriptionManager;
+import org.apache.james.mailbox.store.user.model.Subscription;
+import org.apache.james.mailbox.store.user.model.impl.SimpleSubscription;
+
+/**
+ * Cassandra implementation of {@link StoreSubscriptionManager}
+ *
+ */
+public class CassandraSubscriptionManager extends StoreSubscriptionManager {
+
+ public CassandraSubscriptionManager(CassandraMailboxSessionMapperFactory
mapperFactory) {
+ super(mapperFactory);
+ }
+
+ /**
+ * @see
org.apache.james.mailbox.store.StoreSubscriptionManager#createSubscription(org.apache.james.mailbox.MailboxSession,
+ * java.lang.String)
+ */
+ protected Subscription createSubscription(MailboxSession session, String
mailbox) {
+ return new SimpleSubscription(session.getUser().getUserName(),
mailbox);
+ }
+}
Added:
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=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
(added)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,147 @@
+/****************************************************************
+ * 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 com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+
+import static
org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.FIELDS;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.ID;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.NAME;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.NAMESPACE;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.PATH;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.TABLE_NAME;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.UIDVALIDITY;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.USER;
+
+import java.util.List;
+import java.util.UUID;
+
+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.MailboxMapper;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.querybuilder.QueryBuilder;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+/**
+ * Data access management for mailbox.
+ */
+public class CassandraMailboxMapper implements MailboxMapper<UUID> {
+
+ private Session session;
+
+ public CassandraMailboxMapper(Session session) {
+ this.session = session;
+ }
+
+ @Override
+ public void delete(Mailbox<UUID> mailbox) throws MailboxException {
+ session.execute(QueryBuilder.delete().from(TABLE_NAME).where(eq(ID,
mailbox.getMailboxId())));
+ }
+
+ @Override
+ public Mailbox<UUID> findMailboxByPath(MailboxPath path) throws
MailboxException, MailboxNotFoundException {
+ ResultSet resultSet =
session.execute(select(FIELDS).from(TABLE_NAME).where(eq(PATH,
path.toString())));
+ if (resultSet.isExhausted()) {
+ throw new MailboxNotFoundException(path);
+ } else {
+ return mailbox(resultSet.one());
+ }
+ }
+
+ 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));
+ mailbox.setMailboxId(row.getUUID(ID));
+ return mailbox;
+ }
+
+ @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();
+ }
+
+ @Override
+ public void save(Mailbox<UUID> mailbox) throws MailboxException {
+ Preconditions.checkArgument(mailbox instanceof SimpleMailbox<?>);
+ SimpleMailbox<UUID> simpleMailbox = (SimpleMailbox<UUID>) mailbox;
+ if (simpleMailbox.getMailboxId() == null) {
+ simpleMailbox.setMailboxId(UUID.randomUUID());
+ }
+ upsertMailbox(simpleMailbox);
+ }
+
+ private void upsertMailbox(SimpleMailbox<UUID> mailbox) {
+ session.execute(insertInto(TABLE_NAME).value(ID,
mailbox.getMailboxId()).value(NAME, mailbox.getName()).value(NAMESPACE,
mailbox.getNamespace()).value(UIDVALIDITY,
mailbox.getUidValidity()).value(USER, mailbox.getUser()).value(PATH,
path(mailbox).toString()));
+ }
+
+ private MailboxPath path(Mailbox<?> mailbox) {
+ return new MailboxPath(mailbox.getNamespace(), mailbox.getUser(),
mailbox.getName());
+ }
+
+ @Override
+ public void endRequest() {
+ // Do nothing
+ }
+
+ @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;
+ }
+
+ @Override
+ public List<Mailbox<UUID>> list() throws MailboxException {
+ Builder<Mailbox<UUID>> result = ImmutableList.<Mailbox<UUID>>
builder();
+ for (Row row : session.execute(select(FIELDS).from(TABLE_NAME))) {
+ result.add(mailbox(row));
+ }
+ return result.build();
+ }
+
+ @Override
+ public <T> T execute(Transaction<T> transaction) throws MailboxException {
+ return transaction.run();
+ }
+
+}
Added:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java?rev=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
(added)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,369 @@
+/****************************************************************
+ * 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 com.datastax.driver.core.querybuilder.QueryBuilder.asc;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.decr;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.gt;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.incr;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.lt;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.update;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.BODY_CONTENT;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.BODY_OCTECTS;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.BODY_START_OCTET;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.FIELDS;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.FULL_CONTENT_OCTETS;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.HEADER_CONTENT;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.IMAP_UID;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.INTERNAL_DATE;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.MAILBOX_ID;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.MEDIA_TYPE;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.MOD_SEQ;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.SUB_TYPE;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.TABLE_NAME;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.TEXTUAL_LINE_COUNT;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.ANSWERED;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.DELETED;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.DRAFT;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.FLAGGED;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.JAVAX_MAIL_FLAG;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.RECENT;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.SEEN;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.USER;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.mail.Flags;
+import javax.mail.Flags.Flag;
+import javax.mail.util.SharedByteArrayInputStream;
+
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.cassandra.table.CassandraMailboxCountersTable;
+import org.apache.james.mailbox.cassandra.table.CassandraMessageTable;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MessageMetaData;
+import org.apache.james.mailbox.model.MessageRange;
+import org.apache.james.mailbox.model.UpdatedFlags;
+import org.apache.james.mailbox.store.SimpleMessageMetaData;
+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.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.SimpleMessage;
+
+import com.datastax.driver.core.BoundStatement;
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.querybuilder.Assignment;
+import com.datastax.driver.core.querybuilder.Insert;
+import com.datastax.driver.core.querybuilder.QueryBuilder;
+import com.datastax.driver.core.querybuilder.Select.Where;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.ImmutableSortedSet.Builder;
+import com.google.common.io.ByteStreams;
+import com.google.common.primitives.Bytes;
+
+/**
+ * Cassandra implementation of a {@link MessageMapper}.
+ */
+public class CassandraMessageMapper implements MessageMapper<UUID> {
+
+ private Session session;
+ private ModSeqProvider<UUID> modSeqProvider;
+ private MailboxSession mailboxSession;
+ private UidProvider<UUID> uidProvider;
+
+ public CassandraMessageMapper(Session session, CassandraUidProvider
uidProvider, ModSeqProvider<UUID> modSeqProvider) {
+ this.session = session;
+ this.uidProvider = uidProvider;
+ this.modSeqProvider = modSeqProvider;
+ }
+
+ public CassandraMessageMapper(Session session, CassandraUidProvider
uidProvider, CassandraModSeqProvider modSeqProvider, MailboxSession
mailboxSession) {
+ this(session, uidProvider, modSeqProvider);
+ this.mailboxSession = mailboxSession;
+ }
+
+ @Override
+ public long countMessagesInMailbox(Mailbox<UUID> mailbox) throws
MailboxException {
+ ResultSet results =
session.execute(select(CassandraMailboxCountersTable.COUNT).from(CassandraMailboxCountersTable.TABLE_NAME).where(eq(CassandraMailboxCountersTable.MAILBOX_ID,
mailbox.getMailboxId())));
+ return results.isExhausted() ? 0 :
results.one().getLong(CassandraMailboxCountersTable.COUNT);
+ }
+
+ @Override
+ public long countUnseenMessagesInMailbox(Mailbox<UUID> mailbox) throws
MailboxException {
+ ResultSet results =
session.execute(select(CassandraMailboxCountersTable.UNSEEN).from(CassandraMailboxCountersTable.TABLE_NAME).where(eq(CassandraMailboxCountersTable.MAILBOX_ID,
mailbox.getMailboxId())));
+ if (!results.isExhausted()) {
+ Row row = results.one();
+ if
(row.getColumnDefinitions().contains(CassandraMailboxCountersTable.UNSEEN)) {
+ return row.getLong(CassandraMailboxCountersTable.UNSEEN);
+ }
+ }
+ return 0;
+ }
+
+ @Override
+ public void delete(Mailbox<UUID> mailbox, Message<UUID> message) throws
MailboxException {
+
session.execute(QueryBuilder.delete().from(TABLE_NAME).where(eq(MAILBOX_ID,
mailbox.getMailboxId())).and(eq(IMAP_UID, message.getUid())));
+ decrementCount(mailbox);
+ if (!message.isSeen()) {
+ decrementUnseen(mailbox);
+ }
+ }
+
+ private void decrementCount(Mailbox<UUID> mailbox) {
+ updateMailbox(mailbox, decr(CassandraMailboxCountersTable.COUNT));
+ }
+
+ private void incrementCount(Mailbox<UUID> mailbox) {
+ updateMailbox(mailbox, incr(CassandraMailboxCountersTable.COUNT));
+ }
+
+ private void decrementUnseen(Mailbox<UUID> mailbox) {
+ updateMailbox(mailbox, decr(CassandraMailboxCountersTable.UNSEEN));
+ }
+
+ private void incrementUnseen(Mailbox<UUID> mailbox) {
+ updateMailbox(mailbox, incr(CassandraMailboxCountersTable.UNSEEN));
+ }
+
+ private void updateMailbox(Mailbox<UUID> mailbox, Assignment operation) {
+
session.execute(update(CassandraMailboxCountersTable.TABLE_NAME).with(operation).where(eq(CassandraMailboxCountersTable.MAILBOX_ID,
mailbox.getMailboxId())));
+ }
+
+ @Override
+ public Iterator<Message<UUID>> findInMailbox(Mailbox<UUID> mailbox,
MessageRange set, FetchType ftype, int max) throws MailboxException {
+ Builder<Message<UUID>> result = ImmutableSortedSet.<Message<UUID>>
naturalOrder();
+ ResultSet rows = session.execute(buildQuery(mailbox, set));
+ for (Row row : rows) {
+ result.add(message(row));
+ }
+ return result.build().iterator();
+ }
+
+ private byte[] getFullContent(Row row) {
+ byte[] headerContent = new
byte[row.getBytes(HEADER_CONTENT).remaining()];
+ byte[] bodyContent = new byte[row.getBytes(BODY_CONTENT).remaining()];
+ row.getBytes(HEADER_CONTENT).get(headerContent);
+ row.getBytes(BODY_CONTENT).get(bodyContent);
+ return Bytes.concat(headerContent, bodyContent);
+ }
+
+ private Flags getFlags(Row row) {
+ Flags flags = new Flags();
+ for (String flag : CassandraMessageTable.Flag.ALL) {
+ if (row.getBool(flag)) {
+ flags.add(JAVAX_MAIL_FLAG.get(flag));
+ }
+ }
+ return flags;
+ }
+
+ private PropertyBuilder getPropertyBuilder(Row row) {
+ PropertyBuilder property = new PropertyBuilder();
+ property.setSubType(row.getString(SUB_TYPE));
+ property.setMediaType(row.getString(MEDIA_TYPE));
+ property.setTextualLineCount(row.getLong(TEXTUAL_LINE_COUNT));
+ return property;
+ }
+
+ private Message<UUID> message(Row row) {
+ SimpleMessage<UUID> message = new
SimpleMessage<UUID>(row.getDate(INTERNAL_DATE),
row.getInt(FULL_CONTENT_OCTETS), row.getInt(BODY_START_OCTET), new
SharedByteArrayInputStream(getFullContent(row)), getFlags(row),
getPropertyBuilder(row), row.getUUID(MAILBOX_ID));
+ message.setUid(row.getLong(IMAP_UID));
+ return message;
+ }
+
+ private Where buildQuery(Mailbox<UUID> mailbox, MessageRange set) {
+ final MessageRange.Type type = set.getType();
+ switch (type) {
+ case ALL:
+ return selectAll(mailbox);
+ case FROM:
+ return selectFrom(mailbox, set.getUidFrom());
+ case RANGE:
+ return selectRange(mailbox, set.getUidFrom(), set.getUidTo());
+ case ONE:
+ return selectMessage(mailbox, set.getUidFrom());
+ }
+ throw new UnsupportedOperationException();
+ }
+
+ private Where selectAll(Mailbox<UUID> mailbox) {
+ return select(FIELDS).from(TABLE_NAME).where(eq(MAILBOX_ID,
mailbox.getMailboxId()));
+ }
+
+ private Where selectFrom(Mailbox<UUID> mailbox, long uid) {
+ return select(FIELDS).from(TABLE_NAME).where(eq(MAILBOX_ID,
mailbox.getMailboxId())).and(gt(IMAP_UID, uid));
+ }
+
+ private Where selectRange(Mailbox<UUID> mailbox, long from, long to) {
+ return select(FIELDS).from(TABLE_NAME).where(eq(MAILBOX_ID,
mailbox.getMailboxId())).and(gt(IMAP_UID, from)).and(lt(IMAP_UID, to));
+ }
+
+ private Where selectMessage(Mailbox<UUID> mailbox, long uid) {
+ return select(FIELDS).from(TABLE_NAME).where(eq(MAILBOX_ID,
mailbox.getMailboxId())).and(eq(IMAP_UID, uid));
+ }
+
+ @Override
+ public List<Long> findRecentMessageUidsInMailbox(Mailbox<UUID> mailbox)
throws MailboxException {
+ ImmutableList.Builder<Long> result = ImmutableList.<Long> builder();
+ ResultSet rows =
session.execute(selectAll(mailbox).orderBy(asc(IMAP_UID)));
+ for (Row row : rows) {
+ if (row.getBool(RECENT)) {
+ result.add(row.getLong(IMAP_UID));
+ }
+ }
+ return result.build();
+ }
+
+ @Override
+ public Long findFirstUnseenMessageUid(Mailbox<UUID> mailbox) throws
MailboxException {
+ ResultSet rows =
session.execute(selectAll(mailbox).orderBy(asc(IMAP_UID)));
+ for (Row row : rows) {
+ if (!row.getBool(SEEN)) {
+ return row.getLong(IMAP_UID);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Map<Long, MessageMetaData> expungeMarkedForDeletionInMailbox(final
Mailbox<UUID> mailbox, MessageRange set) throws MailboxException {
+ ImmutableMap.Builder<Long, MessageMetaData> deletedMessages =
ImmutableMap.builder();
+ ResultSet messages = session.execute(buildQuery(mailbox, set));
+ for (Row row : messages) {
+ if (row.getBool(DELETED)) {
+ Message<UUID> message = message(row);
+ delete(mailbox, message);
+ deletedMessages.put(message.getUid(), new
SimpleMessageMetaData(message));
+ }
+ }
+ return deletedMessages.build();
+ }
+
+ @Override
+ public MessageMetaData move(Mailbox<UUID> mailbox, Message<UUID> original)
throws MailboxException {
+ throw new UnsupportedOperationException("Not implemented - see
https://issues.apache.org/jira/browse/IMAP-370");
+ }
+
+ @Override
+ public void endRequest() {
+ // Do nothing
+ }
+
+ @Override
+ public long getHighestModSeq(Mailbox<UUID> mailbox) throws
MailboxException {
+ return modSeqProvider.highestModSeq(mailboxSession, mailbox);
+ }
+
+ @Override
+ public <T> T execute(Transaction<T> transaction) throws MailboxException {
+ return transaction.run();
+ }
+
+ @Override
+ public MessageMetaData add(Mailbox<UUID> mailbox, Message<UUID> message)
throws MailboxException {
+ message.setUid(uidProvider.nextUid(mailboxSession, mailbox));
+ message.setModSeq(modSeqProvider.nextModSeq(mailboxSession, mailbox));
+ MessageMetaData messageMetaData = save(mailbox, message);
+ if (!message.isSeen()) {
+ incrementUnseen(mailbox);
+ }
+ incrementCount(mailbox);
+ return messageMetaData;
+ }
+
+ private MessageMetaData save(Mailbox<UUID> mailbox, Message<UUID> message)
throws MailboxException {
+ try {
+ Insert query = insertInto(TABLE_NAME).value(MAILBOX_ID,
mailbox.getMailboxId()).value(IMAP_UID, message.getUid()).value(MOD_SEQ,
message.getModSeq()).value(INTERNAL_DATE,
message.getInternalDate()).value(MEDIA_TYPE, message.getMediaType())
+ .value(BODY_START_OCTET, message.getFullContentOctets() -
message.getBodyOctets()).value(SUB_TYPE,
message.getSubType()).value(FULL_CONTENT_OCTETS,
message.getFullContentOctets()).value(BODY_OCTECTS,
message.getBodyOctets()).value(ANSWERED, message.isAnswered())
+ .value(DELETED, message.isDeleted()).value(DRAFT,
message.isDraft()).value(FLAGGED, message.isFlagged()).value(RECENT,
message.isRecent()).value(SEEN, message.isSeen()).value(USER,
message.createFlags().contains(Flag.USER)).value(BODY_CONTENT, bindMarker())
+ .value(HEADER_CONTENT,
bindMarker()).value(TEXTUAL_LINE_COUNT, message.getTextualLineCount());
+ PreparedStatement preparedStatement =
session.prepare(query.toString());
+ BoundStatement boundStatement =
preparedStatement.bind(toByteBuffer(message.getBodyContent()),
toByteBuffer(message.getHeaderContent()));
+ session.execute(boundStatement);
+ return new SimpleMessageMetaData(message);
+ } catch (IOException e) {
+ throw new MailboxException("Error saving mail", e);
+ }
+ }
+
+ private ByteBuffer toByteBuffer(InputStream stream) throws IOException {
+ return ByteBuffer.wrap(ByteStreams.toByteArray(stream));
+ }
+
+ @Override
+ public Iterator<UpdatedFlags> updateFlags(Mailbox<UUID> mailbox, Flags
flags, boolean value, boolean replace, MessageRange set) throws
MailboxException {
+ ImmutableList.Builder<UpdatedFlags> result = ImmutableList.builder();
+ for (Row row : session.execute(buildQuery(mailbox, set))) {
+ Message<UUID> message = message(row);
+ Flags originFlags = message.createFlags();
+ Flags updatedFlags = buildFlags(message, flags, value, replace);
+ message.setFlags(updatedFlags);
+ message.setModSeq(modSeqProvider.nextModSeq(mailboxSession,
mailbox));
+ save(mailbox, message);
+ result.add(new UpdatedFlags(message.getUid(), message.getModSeq(),
originFlags, updatedFlags));
+ }
+ return result.build().iterator();
+ }
+
+ private Flags buildFlags(Message<UUID> message, Flags flags, boolean
value, boolean replace) {
+ if (replace) {
+ return message.createFlags();
+ } else {
+ Flags updatedFlags = message.createFlags();
+ if (value) {
+ updatedFlags.add(flags);
+ } else {
+ updatedFlags.remove(flags);
+ }
+ return updatedFlags;
+ }
+ }
+
+ @Override
+ public MessageMetaData copy(Mailbox<UUID> mailbox, Message<UUID> original)
throws MailboxException {
+ original.setUid(uidProvider.nextUid(mailboxSession, mailbox));
+ original.setModSeq(modSeqProvider.nextModSeq(mailboxSession, mailbox));
+ return save(mailbox, original);
+ }
+
+ @Override
+ public long getLastUid(Mailbox<UUID> mailbox) throws MailboxException {
+ return uidProvider.lastUid(mailboxSession, mailbox);
+ }
+
+}
Added:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProvider.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProvider.java?rev=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProvider.java
(added)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProvider.java
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,59 @@
+/****************************************************************
+ * 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 com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.incr;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.update;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMailboxCountersTable.MAILBOX_ID;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMailboxCountersTable.NEXT_MOD_SEQ;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMailboxCountersTable.TABLE_NAME;
+
+import java.util.UUID;
+
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.mail.ModSeqProvider;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Session;
+
+public class CassandraModSeqProvider implements ModSeqProvider<UUID> {
+
+ private Session session;
+
+ public CassandraModSeqProvider(Session session) {
+ this.session = session;
+ }
+
+ @Override
+ public long nextModSeq(MailboxSession mailboxSession, Mailbox<UUID>
mailbox) throws MailboxException {
+
session.execute(update(TABLE_NAME).with(incr(NEXT_MOD_SEQ)).where(eq(MAILBOX_ID,
mailbox.getMailboxId())));
+ return highestModSeq(mailboxSession, mailbox);
+ }
+
+ @Override
+ public long highestModSeq(MailboxSession mailboxSession, Mailbox<UUID>
mailbox) throws MailboxException {
+ ResultSet result =
session.execute(select(NEXT_MOD_SEQ).from(TABLE_NAME).where(eq(MAILBOX_ID,
mailbox.getMailboxId())));
+ return result.isExhausted() ? 0 : result.one().getLong(NEXT_MOD_SEQ);
+ }
+}
Added:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProvider.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProvider.java?rev=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProvider.java
(added)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProvider.java
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,69 @@
+/****************************************************************
+ * 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 com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.set;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.update;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageUidTable.MAILBOX_ID;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageUidTable.NEXT_UID;
+import static
org.apache.james.mailbox.cassandra.table.CassandraMessageUidTable.TABLE_NAME;
+
+import java.util.UUID;
+
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.mail.UidProvider;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Session;
+
+public class CassandraUidProvider implements UidProvider<UUID> {
+ private Session session;
+ private final int applied = 0;
+
+ public CassandraUidProvider(Session session) {
+ this.session = session;
+ }
+
+ @Override
+ public long nextUid(MailboxSession mailboxSession, Mailbox<UUID> mailbox)
throws MailboxException {
+ ResultSet resultat = null;
+ long lastUid = lastUid(mailboxSession, mailbox);
+ if (lastUid == 0) {
+ resultat = session.execute(update(TABLE_NAME).with(set(NEXT_UID,
++lastUid)).where(eq(MAILBOX_ID, mailbox.getMailboxId())));
+ } else {
+ do {
+ lastUid = lastUid(mailboxSession, mailbox);
+ resultat =
session.execute(update(TABLE_NAME).onlyIf(eq(NEXT_UID,
lastUid)).with(set(NEXT_UID, ++lastUid)).where(eq(MAILBOX_ID,
mailbox.getMailboxId())));
+ } while (!resultat.one().getBool(applied));
+ }
+ return lastUid;
+ }
+
+ @Override
+ public long lastUid(MailboxSession mailboxSession, Mailbox<UUID> mailbox)
throws MailboxException {
+ ResultSet result =
session.execute(select(NEXT_UID).from(TABLE_NAME).where(eq(MAILBOX_ID,
mailbox.getMailboxId())));
+ return result.isExhausted() ? 0 : result.one().getLong(NEXT_UID);
+ }
+
+}
Added:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxCountersTable.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxCountersTable.java?rev=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxCountersTable.java
(added)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxCountersTable.java
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,28 @@
+/****************************************************************
+ * 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.table;
+
+public interface CassandraMailboxCountersTable {
+ String TABLE_NAME = "mailboxCounters";
+ String MAILBOX_ID = "mailboxId";
+ String COUNT = "count";
+ String UNSEEN = "unseen";
+ String NEXT_MOD_SEQ = "nextModSeq";
+}
\ No newline at end of file
Added:
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=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxTable.java
(added)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxTable.java
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,31 @@
+/****************************************************************
+ * 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.table;
+
+public interface CassandraMailboxTable {
+ String TABLE_NAME = "mailbox";
+ String ID = "id";
+ String USER = "user";
+ String PATH = "path";
+ String NAMESPACE = "namespace";
+ String UIDVALIDITY = "uidvalidity";
+ String NAME = "name";
+ String[] FIELDS = { ID, USER, NAMESPACE, UIDVALIDITY, NAME, PATH };
+}
Added:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageTable.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageTable.java?rev=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageTable.java
(added)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageTable.java
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,57 @@
+/****************************************************************
+ * 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.table;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+
+public interface CassandraMessageTable {
+
+ String TABLE_NAME = "message";
+ String MAILBOX_ID = "mailboxId";
+ String IMAP_UID = "uid";
+ String INTERNAL_DATE = "internalDate";
+ String BODY_START_OCTET = "bodyStartOctet";
+ String CONTENT = "content";
+ String MOD_SEQ = "modSeq";
+ String MEDIA_TYPE = "mediaType";
+ String SUB_TYPE = "subType";
+ String FULL_CONTENT_OCTETS = "fullContentOctets";
+ String BODY_OCTECTS = "bodyOctets";
+ String TEXTUAL_LINE_COUNT = "textualLineCount";
+ String BODY_CONTENT = "bodyContent";
+ String HEADER_CONTENT = "headerContent";
+ String[] FIELDS = { MAILBOX_ID, IMAP_UID, INTERNAL_DATE, MOD_SEQ,
BODY_START_OCTET, MEDIA_TYPE, SUB_TYPE, FULL_CONTENT_OCTETS, BODY_OCTECTS,
Flag.ANSWERED, Flag.DELETED, Flag.DRAFT, Flag.FLAGGED, Flag.RECENT, Flag.SEEN,
Flag.USER, BODY_CONTENT, HEADER_CONTENT, TEXTUAL_LINE_COUNT };
+
+ interface Flag {
+ String ANSWERED = "flagAnswered";
+ String DELETED = "flagDeleted";
+ String DRAFT = "flagDraft";
+ String RECENT = "flagRecent";
+ String SEEN = "flagSeen";
+ String FLAGGED = "flagFlagged";
+ String USER = "flagUser";
+ String[] ALL = { ANSWERED, DELETED, DRAFT, RECENT, SEEN, FLAGGED, USER
};
+
+ ImmutableMap<String, javax.mail.Flags.Flag> JAVAX_MAIL_FLAG = new
Builder<String, javax.mail.Flags.Flag>().put(ANSWERED,
javax.mail.Flags.Flag.ANSWERED).put(DELETED,
javax.mail.Flags.Flag.DELETED).put(DRAFT,
javax.mail.Flags.Flag.DRAFT).put(RECENT, javax.mail.Flags.Flag.RECENT)
+ .put(SEEN, javax.mail.Flags.Flag.SEEN).put(FLAGGED,
javax.mail.Flags.Flag.FLAGGED).put(USER, javax.mail.Flags.Flag.USER).build();
+
+ }
+}
Added:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageUidTable.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageUidTable.java?rev=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageUidTable.java
(added)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageUidTable.java
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,26 @@
+/****************************************************************
+ * 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.table;
+
+public interface CassandraMessageUidTable {
+ String TABLE_NAME = "messageCounter";
+ String MAILBOX_ID = "mailboxId";
+ String NEXT_UID = "nextUid";
+}
\ No newline at end of file
Added:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraSubscriptionTable.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraSubscriptionTable.java?rev=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraSubscriptionTable.java
(added)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraSubscriptionTable.java
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,29 @@
+/****************************************************************
+ * 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.table;
+
+public interface CassandraSubscriptionTable {
+
+ String TABLE_NAME = "subscription";
+ String USER = "user";
+ String MAILBOX = "mailbox";
+ String[] FIELDS = { MAILBOX, USER };
+
+}
Added:
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapper.java
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapper.java?rev=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapper.java
(added)
+++
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapper.java
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,95 @@
+/****************************************************************
+ * 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 com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+import static
org.apache.james.mailbox.cassandra.table.CassandraSubscriptionTable.FIELDS;
+import static
org.apache.james.mailbox.cassandra.table.CassandraSubscriptionTable.MAILBOX;
+import static
org.apache.james.mailbox.cassandra.table.CassandraSubscriptionTable.TABLE_NAME;
+import static
org.apache.james.mailbox.cassandra.table.CassandraSubscriptionTable.USER;
+
+import java.util.List;
+
+import org.apache.james.mailbox.store.transaction.NonTransactionalMapper;
+import org.apache.james.mailbox.store.user.SubscriptionMapper;
+import org.apache.james.mailbox.store.user.model.Subscription;
+import org.apache.james.mailbox.store.user.model.impl.SimpleSubscription;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.querybuilder.Insert;
+import com.datastax.driver.core.querybuilder.QueryBuilder;
+import com.datastax.driver.core.querybuilder.Select;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+public class CassandraSubscriptionMapper extends NonTransactionalMapper
implements SubscriptionMapper {
+ private Session session;
+
+ public CassandraSubscriptionMapper(Session session) {
+ this.session = session;
+ }
+
+ @Override
+ public synchronized void delete(Subscription subscription) {
+ session.execute(QueryBuilder.delete().from(TABLE_NAME).where(eq(USER,
subscription.getUser())).and(eq(MAILBOX, subscription.getMailbox())));
+ }
+
+ @Override
+ public Subscription findMailboxSubscriptionForUser(String user, String
mailbox) {
+ ResultSet results =
session.execute(select(MAILBOX).from(TABLE_NAME).where(eq(USER,
user)).and(eq(MAILBOX, mailbox)));
+ return !results.isExhausted() ? new SimpleSubscription(user, mailbox)
: null;
+ }
+
+ @Override
+ public List<Subscription> findSubscriptionsForUser(String user) {
+ Builder<Subscription> result = ImmutableList.<Subscription> builder();
+ Select query = select(MAILBOX).from(TABLE_NAME);
+ query.where(eq(USER, user));
+ query.allowFiltering();
+ for (Row row : session.execute(query)) {
+ result.add(new SimpleSubscription(user, row.getString(MAILBOX)));
+ }
+ return result.build();
+ }
+
+ @Override
+ public synchronized void save(Subscription subscription) {
+ Insert query = insertInto(TABLE_NAME).value(USER,
subscription.getUser()).value(MAILBOX, subscription.getMailbox());
+ session.execute(query);
+ }
+
+ public List<SimpleSubscription> list() {
+ Builder<SimpleSubscription> result =
ImmutableList.<SimpleSubscription> builder();
+ for (Row row : session.execute(select(FIELDS).from(TABLE_NAME))) {
+ result.add(new SimpleSubscription(row.getString(USER),
row.getString(MAILBOX)));
+ }
+ return result.build();
+ }
+
+ @Override
+ public void endRequest() {
+ // nothing todo
+ }
+
+}
Added:
james/mailbox/trunk/cassandra/src/main/resources/META-INF/spring/mailbox-cassandra.xml
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/resources/META-INF/spring/mailbox-cassandra.xml?rev=1617517&view=auto
==============================================================================
---
james/mailbox/trunk/cassandra/src/main/resources/META-INF/spring/mailbox-cassandra.xml
(added)
+++
james/mailbox/trunk/cassandra/src/main/resources/META-INF/spring/mailbox-cassandra.xml
Tue Aug 12 16:08:57 2014
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <!--
+ Mailbox Cassandra
+ -->
+ <bean id="cassandra-mailboxmanager"
class="org.apache.james.mailbox.cassandra.CassandraMailboxManager"
init-method="init">
+ <constructor-arg index="0" ref="cassandra-sessionMapperFactory"/>
+ <constructor-arg index="1" ref="authenticator"/>
+ <constructor-arg index="2" ref="cassandra-locker"/>
+ </bean>
+
+ <bean id ="cassandra-subscriptionManager"
class="org.apache.james.mailbox.cassandra.CassandraSubscriptionManager">
+ <constructor-arg index="0" ref="cassandra-sessionMapperFactory"/>
+ </bean>
+
+ <bean id="cassandra-sessionMapperFactory"
class="org.apache.james.mailbox.cassandra.CassandraMailboxSessionMapperFactory">
+ <constructor-arg index="0" ref="cassandra-uidProvider"/>
+ <constructor-arg index="1" ref="cassandra-modSeqProvider"/>
+ <constructor-arg index="2" ref="cassandra-session"/>
+ </bean>
+
+ <bean id="cassandra-uidProvider"
class="org.apache.james.mailbox.cassandra.mail.CassandraUidProvider">
+ <constructor-arg index="0" ref="cassandra-session"/>
+ </bean>
+
+ <bean id="cassandra-modSeqProvider"
class="org.apache.james.mailbox.cassandra.mail.CassandraModSeqProvider">
+ <constructor-arg index="0" ref="cassandra-session"/>
+ </bean>
+
+ <!--
+ The parameters are : the IP of a Cassendra cluster, the port, the
keyspace and the replication factor
+ Default values are : localhost, 9042, apache_james and 1
+ -->
+ <bean id="cassandra-session"
class="org.apache.james.mailbox.cassandra.CassandraSession">
+ <constructor-arg index="0" value="localhost"/>
+ <constructor-arg index="1" value="9042" type="int"/>
+ <constructor-arg index="2" value="apache_james"/>
+ <constructor-arg index="3" value="1" type="int"/>
+ </bean>
+
+ <alias name="jvm-locker" alias="cassandra-locker"/>
+
+</beans>
Added: james/mailbox/trunk/cassandra/src/reporting-site/site.xml
URL:
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/reporting-site/site.xml?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/reporting-site/site.xml (added)
+++ james/mailbox/trunk/cassandra/src/reporting-site/site.xml Tue Aug 12
16:08:57 2014
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ 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.
+-->
+<project name="${project.name}">
+
+ <body>
+
+ <menu ref="parent" />
+ <menu ref="reports" />
+
+ </body>
+
+</project>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]