Author: eric
Date: Thu May 28 15:51:11 2015
New Revision: 1682267

URL: http://svn.apache.org/r1682267
Log:
Add missing files to support Cassandra table creation, patch contributed by 
Benoit Tellier (MAILBOX-226)

Added:
    james/mailbox/trunk/cassandra/README.txt
    
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraConstants.java
    
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTableManager.java
    
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/ClusterFactory.java
    
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/ClusterWithKeyspaceCreatedFactory.java
    
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/SessionFactory.java
Removed:
    
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSession.java

Added: james/mailbox/trunk/cassandra/README.txt
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/README.txt?rev=1682267&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/README.txt (added)
+++ james/mailbox/trunk/cassandra/README.txt Thu May 28 15:51:11 2015
@@ -0,0 +1,18 @@
+= Cassandra Mailbox implementation
+
+This Mailbox sub-project is about providing a scalable mailbox implementation 
relying on Cassandra database.
+
+Concurrency is handled by this implementation while performing writes using 
Lightweight transactions. You do not need to lock anything, or provide utils to 
lock anything, when using this implementation.
+
+== Configuration
+
+The configuration is achieved through Spring. The file is 
'src/main/resources/META-INF/spring/mailbox-cassandra.xml' .
+
+The components are instanciated and wired together.
+
+What might interest you the most is the way you want to connect your Cassandra 
cluster.
+
+Factories are used. You have :
+  * ClusterFactory : you specify which Cassandra servers you want to connect, 
with ( optional ) which user name and password to use.
+  * ClusterWithKeyspaceCreatedFactory : This ( optional ) component creates a 
Keyspace if it does not already exists. You may want to skip this step in 
production environment.
+  * SessionFactory : Connect the appropriated Keyspace, to create a Session 
our application can work with.
\ No newline at end of file

Added: 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraConstants.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraConstants.java?rev=1682267&view=auto
==============================================================================
--- 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraConstants.java
 (added)
+++ 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraConstants.java
 Thu May 28 15:51:11 2015
@@ -0,0 +1,24 @@
+/****************************************************************
+ * 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;
+
+public interface CassandraConstants {
+    int LIGHTWEIGHT_TRANSACTION_APPLIED = 0;
+}

Added: 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTableManager.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTableManager.java?rev=1682267&view=auto
==============================================================================
--- 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTableManager.java
 (added)
+++ 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTableManager.java
 Thu May 28 15:51:11 2015
@@ -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 static com.datastax.driver.core.DataType.*;
+
+import com.datastax.driver.core.querybuilder.QueryBuilder;
+import com.datastax.driver.core.schemabuilder.Create;
+
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.schemabuilder.SchemaBuilder;
+import com.datastax.driver.core.schemabuilder.SchemaStatement;
+import org.apache.james.mailbox.cassandra.table.CassandraACLTable;
+import org.apache.james.mailbox.cassandra.table.CassandraMailboxCountersTable;
+import org.apache.james.mailbox.cassandra.table.CassandraMailboxTable;
+import org.apache.james.mailbox.cassandra.table.CassandraMessageTable;
+import org.apache.james.mailbox.cassandra.table.CassandraMessageUidTable;
+import org.apache.james.mailbox.cassandra.table.CassandraSubscriptionTable;
+
+import java.util.Arrays;
+
+public class CassandraTableManager {
+
+    private Session session;
+
+    enum TABLE {
+        Mailbox(CassandraMailboxTable.TABLE_NAME,
+            SchemaBuilder.createTable(CassandraMailboxTable.TABLE_NAME)
+                .ifNotExists()
+                .addPartitionKey(CassandraMailboxTable.ID, uuid())
+                .addColumn(CassandraMailboxTable.NAMESPACE, text())
+                .addColumn(CassandraMailboxTable.USER, text())
+                .addColumn(CassandraMailboxTable.NAME, text())
+                .addColumn(CassandraMailboxTable.PATH, text())
+                .addColumn(CassandraMailboxTable.UIDVALIDITY, bigint())),
+        MailboxCounter(CassandraMailboxCountersTable.TABLE_NAME,
+            SchemaBuilder.createTable(CassandraMailboxCountersTable.TABLE_NAME)
+                .ifNotExists()
+                .addPartitionKey(CassandraMailboxCountersTable.MAILBOX_ID, 
uuid())
+                .addColumn(CassandraMailboxCountersTable.COUNT, counter())
+                .addColumn(CassandraMailboxCountersTable.UNSEEN, counter())
+                .addColumn(CassandraMailboxCountersTable.NEXT_MOD_SEQ, 
counter())),
+        MessageUid(CassandraMessageUidTable.TABLE_NAME,
+            SchemaBuilder.createTable(CassandraMessageUidTable.TABLE_NAME)
+                .ifNotExists()
+                .addPartitionKey(CassandraMessageUidTable.MAILBOX_ID, uuid())
+                .addColumn(CassandraMessageUidTable.NEXT_UID, bigint())),
+        Message(CassandraMessageTable.TABLE_NAME,
+            SchemaBuilder.createTable(CassandraMessageTable.TABLE_NAME)
+                .ifNotExists()
+                .addPartitionKey(CassandraMessageTable.MAILBOX_ID, uuid())
+                .addClusteringColumn(CassandraMessageTable.IMAP_UID, bigint())
+                .addColumn(CassandraMessageTable.INTERNAL_DATE, timestamp())
+                .addColumn(CassandraMessageTable.BODY_START_OCTET, cint())
+                .addColumn(CassandraMessageTable.BODY_OCTECTS, cint())
+                .addColumn(CassandraMessageTable.TEXTUAL_LINE_COUNT, bigint())
+                .addColumn(CassandraMessageTable.MOD_SEQ, bigint())
+                .addColumn(CassandraMessageTable.MEDIA_TYPE, text())
+                .addColumn(CassandraMessageTable.SUB_TYPE, text())
+                .addColumn(CassandraMessageTable.FULL_CONTENT_OCTETS, cint())
+                .addColumn(CassandraMessageTable.BODY_CONTENT, blob())
+                .addColumn(CassandraMessageTable.HEADER_CONTENT, blob())
+                .addColumn(CassandraMessageTable.Flag.ANSWERED, cboolean())
+                .addColumn(CassandraMessageTable.Flag.DELETED, cboolean())
+                .addColumn(CassandraMessageTable.Flag.DRAFT, cboolean())
+                .addColumn(CassandraMessageTable.Flag.FLAGGED, cboolean())
+                .addColumn(CassandraMessageTable.Flag.RECENT, cboolean())
+                .addColumn(CassandraMessageTable.Flag.SEEN, cboolean())
+                .addColumn(CassandraMessageTable.Flag.USER, cboolean())
+                .addColumn(CassandraMessageTable.FLAG_VERSION, bigint())),
+        Subscription(CassandraSubscriptionTable.TABLE_NAME,
+            SchemaBuilder.createTable(CassandraSubscriptionTable.TABLE_NAME)
+                .ifNotExists()
+                .addPartitionKey(CassandraSubscriptionTable.MAILBOX, text())
+                .addClusteringColumn(CassandraSubscriptionTable.USER, text())
+        ),
+        Acl(CassandraACLTable.TABLE_NAME,
+            SchemaBuilder.createTable(CassandraACLTable.TABLE_NAME)
+                .ifNotExists()
+                .addPartitionKey(CassandraACLTable.ID, uuid())
+                .addColumn(CassandraACLTable.ACL, text())
+                .addColumn(CassandraACLTable.VERSION, bigint())
+        )
+        ;
+        private Create createStatement;
+        private String name;
+
+        TABLE(String name, Create createStatement) {
+            this.createStatement = createStatement;
+            this.name = name;
+        }
+    }
+
+    enum INDEX {
+        MailboxPath(SchemaBuilder.createIndex(CassandraMailboxTable.TABLE_NAME)
+            .ifNotExists()
+            .onTable(CassandraMailboxTable.TABLE_NAME)
+            .andColumn(CassandraMailboxTable.PATH));
+        private SchemaStatement createIndexStatement;
+
+        INDEX(SchemaStatement createIndexStatement) {
+            this.createIndexStatement = createIndexStatement;
+        }
+    }
+
+    public CassandraTableManager(Session session) {
+        this.session = session;
+    }
+
+    public CassandraTableManager ensureAllTables() {
+        Arrays.asList(TABLE.values())
+            .forEach(
+                (table) -> session.execute(table.createStatement)
+            );
+        Arrays.asList(INDEX.values())
+            .forEach(
+                (table) -> session.execute(table.createIndexStatement)
+            );
+        return this;
+    }
+
+    public void clearAllTables() {
+        Arrays.asList(TABLE.values())
+            .forEach(
+                (table) -> clearTable(table.name)
+            );
+    }
+
+    private void clearTable(String tableName) {
+        session.execute(QueryBuilder.truncate(tableName));
+    }
+}

Added: 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/ClusterFactory.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/ClusterFactory.java?rev=1682267&view=auto
==============================================================================
--- 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/ClusterFactory.java
 (added)
+++ 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/ClusterFactory.java
 Thu May 28 15:51:11 2015
@@ -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;
+
+import com.datastax.driver.core.Cluster;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+public class ClusterFactory {
+
+    public static class CassandraServer {
+        private String ip;
+        private int port;
+
+        public CassandraServer(String ip, int port) {
+            this.ip = ip;
+            this.port = port;
+        }
+    }
+
+    private final static String DEFAULT_CLUSTER_IP = "localhost";
+    private final static int DEFAULT_CLUSTER_PORT = 9042;
+
+    public Cluster createClusterForClusterWithPassWord(List<CassandraServer> 
servers, String userName, String password) {
+        Cluster.Builder clusterBuilder = Cluster.builder();
+        servers.forEach(
+            (server) -> 
clusterBuilder.addContactPoint(server.ip).withPort(server.port)
+        );
+        if(!Strings.isNullOrEmpty(userName) && 
!Strings.isNullOrEmpty(password)) {
+            clusterBuilder.withCredentials(userName, password);
+        }
+        return clusterBuilder.build();
+    }
+
+    public Cluster 
createClusterForClusterWithoutPassWord(List<CassandraServer> servers) {
+        return createClusterForClusterWithPassWord(servers, null, null);
+    }
+    
+    public Cluster createClusterForSingleServerWithPassWord(String ip, int 
port, String userName, String password) {
+        return createClusterForClusterWithPassWord(ImmutableList.of(new 
CassandraServer(ip, port)), userName, password);
+    }
+
+    public Cluster createClusterForSingleServerWithoutPassWord(String ip, int 
port) {
+        return createClusterForClusterWithPassWord(ImmutableList.of(new 
CassandraServer(ip, port)), null, null);
+    }
+
+    public Cluster createDefaultSession() {
+        return createClusterForSingleServerWithoutPassWord(DEFAULT_CLUSTER_IP, 
DEFAULT_CLUSTER_PORT);
+    }
+}

Added: 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/ClusterWithKeyspaceCreatedFactory.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/ClusterWithKeyspaceCreatedFactory.java?rev=1682267&view=auto
==============================================================================
--- 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/ClusterWithKeyspaceCreatedFactory.java
 (added)
+++ 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/ClusterWithKeyspaceCreatedFactory.java
 Thu May 28 15:51:11 2015
@@ -0,0 +1,32 @@
+package org.apache.james.mailbox.cassandra;
+
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.Session;
+
+public class ClusterWithKeyspaceCreatedFactory {
+
+    private final static int DEFAULT_REPLICATION_FACTOR = 1;
+
+    public Cluster clusterWithInitializedKeyspace(Cluster cluster, String 
keyspace, int replicationFactor) {
+        if (isKeyspacePresent(cluster, keyspace)) {
+            createKeyspace(cluster, keyspace, replicationFactor);
+        }
+        return cluster;
+    }
+
+    public Cluster clusterWithInitializedKeyspace(Cluster cluster, String 
keyspace) {
+        return clusterWithInitializedKeyspace(cluster, keyspace, 
DEFAULT_REPLICATION_FACTOR);
+    }
+
+    private boolean isKeyspacePresent(Cluster cluster, String keyspace) {
+        return cluster.getMetadata().getKeyspace(keyspace) == null;
+    }
+
+    private void createKeyspace(Cluster cluster, String keyspace, int 
replicationFactor) {
+        try (Session session = cluster.connect()) {
+            session.execute("CREATE KEYSPACE IF NOT EXISTS " + keyspace
+                + " WITH replication = {'class':'SimpleStrategy', 
'replication_factor':" + replicationFactor + "};");
+        }
+    }
+
+}

Added: 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/SessionFactory.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/SessionFactory.java?rev=1682267&view=auto
==============================================================================
--- 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/SessionFactory.java
 (added)
+++ 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/SessionFactory.java
 Thu May 28 15:51:11 2015
@@ -0,0 +1,39 @@
+/****************************************************************
+ * 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.Cluster;
+import com.datastax.driver.core.Session;
+
+public class SessionFactory {
+    private final static String DEFAULT_KEYSPACE_NAME = "apache_james";
+
+    public Session createSession(Cluster cluster, String keyspace) {
+        Session session = cluster.connect(keyspace);
+        new CassandraTableManager(session)
+            .ensureAllTables();
+        return session;
+    }
+
+    public Session createSession(Cluster cluster) {
+        return createSession(cluster, DEFAULT_KEYSPACE_NAME);
+    }
+
+}



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

Reply via email to