Author: matthieu
Date: Thu Oct 29 14:13:14 2015
New Revision: 1711266

URL: http://svn.apache.org/viewvc?rev=1711266&view=rev
Log:
JAMES-1588 Moving and improving Cassandra session init

Added:
    
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/
    
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraIndex.java
    
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraModule.java
    
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraTable.java
    
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraType.java
    
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/
    
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTableManager.java
    
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesCreator.java
    
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesProvider.java
    
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterFactory.java
    
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterWithKeyspaceCreatedFactory.java
    
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactory.java
    
james/project/trunk/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraClusterSingleton.java
    
james/project/trunk/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/
    
james/project/trunk/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTypeProviderTest.java

Added: 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraIndex.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraIndex.java?rev=1711266&view=auto
==============================================================================
--- 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraIndex.java
 (added)
+++ 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraIndex.java
 Thu Oct 29 14:13:14 2015
@@ -0,0 +1,38 @@
+/****************************************************************
+ * 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.backends.cassandra.components;
+
+import com.datastax.driver.core.schemabuilder.SchemaStatement;
+
+public class CassandraIndex {
+
+    public final static String INDEX_PREFIX = "INDEX_";
+
+    private final SchemaStatement createIndexStatement;
+
+    public CassandraIndex(SchemaStatement createIndexStatement) {
+        this.createIndexStatement = createIndexStatement;
+    }
+
+    public SchemaStatement getCreateIndexStatement() {
+        return createIndexStatement;
+    }
+
+}

Added: 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraModule.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraModule.java?rev=1711266&view=auto
==============================================================================
--- 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraModule.java
 (added)
+++ 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraModule.java
 Thu Oct 29 14:13:14 2015
@@ -0,0 +1,32 @@
+/****************************************************************
+ * 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.backends.cassandra.components;
+
+import java.util.List;
+
+public interface CassandraModule {
+
+    List<CassandraTable> moduleTables();
+
+    List<CassandraIndex> moduleIndex();
+
+    List<CassandraType> moduleTypes();
+
+}

Added: 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraTable.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraTable.java?rev=1711266&view=auto
==============================================================================
--- 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraTable.java
 (added)
+++ 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraTable.java
 Thu Oct 29 14:13:14 2015
@@ -0,0 +1,41 @@
+/****************************************************************
+ * 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.backends.cassandra.components;
+
+import com.datastax.driver.core.schemabuilder.Create;
+
+public class CassandraTable {
+
+    private final Create createStatement;
+    private final String name;
+
+    public CassandraTable(String name, Create createStatement) {
+        this.createStatement = createStatement;
+        this.name = name;
+    }
+
+    public Create getCreateStatement() {
+        return createStatement;
+    }
+
+    public String getName() {
+        return name;
+    }
+}

Added: 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraType.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraType.java?rev=1711266&view=auto
==============================================================================
--- 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraType.java
 (added)
+++ 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraType.java
 Thu Oct 29 14:13:14 2015
@@ -0,0 +1,42 @@
+/****************************************************************
+ * 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.backends.cassandra.components;
+
+import com.datastax.driver.core.schemabuilder.CreateType;
+
+public class CassandraType {
+
+    private final String name;
+    private final CreateType createStatement;
+
+    public CassandraType(String name, CreateType createStatement) {
+        this.name = name;
+        this.createStatement = createStatement;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public CreateType getCreateStatement() {
+        return createStatement;
+    }
+
+}

Added: 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTableManager.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTableManager.java?rev=1711266&view=auto
==============================================================================
--- 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTableManager.java
 (added)
+++ 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTableManager.java
 Thu Oct 29 14:13:14 2015
@@ -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.backends.cassandra.init;
+
+import java.util.List;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.querybuilder.QueryBuilder;
+import com.google.common.collect.ImmutableList;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+
+public class CassandraTableManager {
+
+    private final Session session;
+    private final ImmutableList<CassandraModule> modules;
+
+    public CassandraTableManager(List<CassandraModule> modules, Session 
session) {
+        this.session = session;
+        this.modules = ImmutableList.copyOf(modules);
+    }
+
+    public CassandraTableManager ensureAllTables() {
+        modules.stream()
+            .flatMap(module -> module.moduleTables().stream())
+            .forEach(table -> session.execute(table.getCreateStatement()));
+        modules.stream()
+            .flatMap(module -> module.moduleIndex().stream())
+            .forEach(index -> 
session.execute(index.getCreateIndexStatement()));
+        return this;
+    }
+
+    public void clearAllTables() {
+        modules.stream()
+            .flatMap(module -> module.moduleTables().stream())
+            .forEach(table -> clearTable(table.getName()));
+    }
+
+    private void clearTable(String tableName) {
+        session.execute(QueryBuilder.truncate(tableName));
+    }
+}

Added: 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesCreator.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesCreator.java?rev=1711266&view=auto
==============================================================================
--- 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesCreator.java
 (added)
+++ 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesCreator.java
 Thu Oct 29 14:13:14 2015
@@ -0,0 +1,48 @@
+/****************************************************************
+ * 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.backends.cassandra.init;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.UserType;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.backends.cassandra.components.CassandraType;
+
+public class CassandraTypesCreator {
+    private final ImmutableList<CassandraType> types;
+    private final Session session;
+
+    public CassandraTypesCreator(List<CassandraModule> modules, Session 
session) {
+        this.types = ImmutableList.copyOf(modules.stream()
+            .flatMap(module -> module.moduleTypes().stream())
+            .collect(Collectors.toList()));
+        this.session = session;
+    }
+
+    public void initializeTypes() {
+        types.forEach((type) -> session.execute(type.getCreateStatement()));
+    }
+
+}

Added: 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesProvider.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesProvider.java?rev=1711266&view=auto
==============================================================================
--- 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesProvider.java
 (added)
+++ 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesProvider.java
 Thu Oct 29 14:13:14 2015
@@ -0,0 +1,53 @@
+/****************************************************************
+ * 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.backends.cassandra.init;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.UserType;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.backends.cassandra.components.CassandraType;
+
+public class CassandraTypesProvider {
+    private final ImmutableMap<String, UserType> userTypes;
+
+    public CassandraTypesProvider(List<CassandraModule> modules, Session 
session) {
+        userTypes = ImmutableMap.copyOf(modules.stream()
+            .flatMap(module -> module.moduleTypes().stream())
+            .collect(
+                Collectors.toMap(
+                    CassandraType::getName,
+                    type -> session.getCluster()
+                    .getMetadata()
+                    .getKeyspace(session.getLoggedKeyspace())
+                    .getUserType(type.getName()))));
+    }
+
+    public UserType getDefinedUserType(String typeName) {
+        return Optional.ofNullable(userTypes.get(typeName))
+            .orElseThrow(() -> new RuntimeException("Cassandra UDT " + 
typeName + " can not be retrieved"));
+    }
+
+}

Added: 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterFactory.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterFactory.java?rev=1711266&view=auto
==============================================================================
--- 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterFactory.java
 (added)
+++ 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterFactory.java
 Thu Oct 29 14:13:14 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.backends.cassandra.init;
+
+import java.util.List;
+
+import com.datastax.driver.core.Cluster;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+
+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 static 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 static Cluster 
createClusterForClusterWithoutPassWord(List<CassandraServer> servers) {
+        return createClusterForClusterWithPassWord(servers, null, null);
+    }
+
+    public static Cluster createClusterForSingleServerWithPassWord(String ip, 
int port, String userName, String password) {
+        return createClusterForClusterWithPassWord(ImmutableList.of(new 
CassandraServer(ip, port)), userName, password);
+    }
+
+    public static Cluster createClusterForSingleServerWithoutPassWord(String 
ip, int port) {
+        return createClusterForClusterWithPassWord(ImmutableList.of(new 
CassandraServer(ip, port)), null, null);
+    }
+
+     public static Cluster createDefaultSession() {
+        return createClusterForSingleServerWithoutPassWord(DEFAULT_CLUSTER_IP, 
DEFAULT_CLUSTER_PORT);
+    }
+}

Added: 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterWithKeyspaceCreatedFactory.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterWithKeyspaceCreatedFactory.java?rev=1711266&view=auto
==============================================================================
--- 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterWithKeyspaceCreatedFactory.java
 (added)
+++ 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterWithKeyspaceCreatedFactory.java
 Thu Oct 29 14:13:14 2015
@@ -0,0 +1,51 @@
+/****************************************************************
+ * 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.backends.cassandra.init;
+
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.Session;
+
+public class ClusterWithKeyspaceCreatedFactory {
+
+    private final static int DEFAULT_REPLICATION_FACTOR = 1;
+
+    public static Cluster clusterWithInitializedKeyspace(Cluster cluster, 
String keyspace, int replicationFactor) {
+        if (isKeyspacePresent(cluster, keyspace)) {
+            createKeyspace(cluster, keyspace, replicationFactor);
+        }
+        return cluster;
+    }
+
+    public static Cluster clusterWithInitializedKeyspace(Cluster cluster, 
String keyspace) {
+        return clusterWithInitializedKeyspace(cluster, keyspace, 
DEFAULT_REPLICATION_FACTOR);
+    }
+
+    private static boolean isKeyspacePresent(Cluster cluster, String keyspace) 
{
+        return cluster.getMetadata().getKeyspace(keyspace) == null;
+    }
+
+    private static 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/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactory.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactory.java?rev=1711266&view=auto
==============================================================================
--- 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactory.java
 (added)
+++ 
james/project/trunk/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactory.java
 Thu Oct 29 14:13:14 2015
@@ -0,0 +1,50 @@
+/****************************************************************
+ * 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.backends.cassandra.init;
+
+import java.util.List;
+
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.Session;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+
+public class SessionWithInitializedTablesFactory {
+    private final static String DEFAULT_KEYSPACE_NAME = "apache_james";
+
+    private List<CassandraModule> modules;
+
+    public SessionWithInitializedTablesFactory(List<CassandraModule> modules) {
+        this.modules = modules;
+    }
+
+    public Session createSession(Cluster cluster, String keyspace) {
+        Session session = cluster.connect(keyspace);
+        new CassandraTypesCreator(modules, session)
+            .initializeTypes();
+        new CassandraTableManager(modules, session)
+            .ensureAllTables();
+        return session;
+    }
+
+    public Session createSession(Cluster cluster) {
+        return createSession(cluster, DEFAULT_KEYSPACE_NAME);
+    }
+
+}

Added: 
james/project/trunk/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraClusterSingleton.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraClusterSingleton.java?rev=1711266&view=auto
==============================================================================
--- 
james/project/trunk/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraClusterSingleton.java
 (added)
+++ 
james/project/trunk/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraClusterSingleton.java
 Thu Oct 29 14:13:14 2015
@@ -0,0 +1,110 @@
+/****************************************************************
+ * 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.backends.cassandra;
+
+import com.datastax.driver.core.exceptions.NoHostAvailableException;
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.Session;
+import com.google.common.base.Throwables;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.backends.cassandra.init.CassandraTableManager;
+import org.apache.james.backends.cassandra.init.CassandraTypesProvider;
+import org.apache.james.backends.cassandra.init.ClusterFactory;
+import 
org.apache.james.backends.cassandra.init.ClusterWithKeyspaceCreatedFactory;
+import 
org.apache.james.backends.cassandra.init.SessionWithInitializedTablesFactory;
+import org.apache.james.backends.cassandra.utils.FunctionRunnerWithRetry;
+import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+public final class CassandraClusterSingleton {
+    private static final String CLUSTER_IP = "localhost";
+    private static final int CLUSTER_PORT_TEST = 9142;
+    private static final String KEYSPACE_NAME = "apache_james";
+    private static final int REPLICATION_FACTOR = 1;
+
+    private static final long SLEEP_BEFORE_RETRY = 200;
+    private static final int MAX_RETRY = 200;
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(CassandraClusterSingleton.class);
+    private static CassandraClusterSingleton cluster = null;
+    private final List<CassandraModule> modules;
+    private Session session;
+    private CassandraTypesProvider typesProvider;
+
+    public static synchronized CassandraClusterSingleton 
create(CassandraModule module) throws RuntimeException {
+        LOG.info("Retrieving cluster instance.");
+        if (cluster == null) {
+            cluster = new CassandraClusterSingleton(Arrays.asList(module));
+        }
+        return cluster;
+    }
+
+    private CassandraClusterSingleton(List<CassandraModule> modules) throws 
RuntimeException {
+        this.modules = modules;
+        try {
+            EmbeddedCassandraServerHelper.startEmbeddedCassandra();
+            session = new FunctionRunnerWithRetry(MAX_RETRY)
+                
.executeAndRetrieveObject(CassandraClusterSingleton.this::tryInitializeSession);
+            typesProvider = new CassandraTypesProvider(modules, session);
+        } catch(Exception exception) {
+            Throwables.propagate(exception);
+        }
+    }
+
+    public Session getConf() {
+        return session;
+    }
+
+    public void ensureAllTables() {
+        new CassandraTableManager(modules, session).ensureAllTables();
+    }
+
+    public void clearAllTables() {
+        new CassandraTableManager(modules, session).clearAllTables();
+    }
+
+    private Optional<Session> tryInitializeSession() {
+        try {
+            Cluster cluster = 
ClusterFactory.createClusterForSingleServerWithoutPassWord(CLUSTER_IP, 
CLUSTER_PORT_TEST);
+            Cluster clusterWithInitializedKeyspace = 
ClusterWithKeyspaceCreatedFactory
+                .clusterWithInitializedKeyspace(cluster, KEYSPACE_NAME, 
REPLICATION_FACTOR);
+            return Optional.of(new 
SessionWithInitializedTablesFactory(modules).createSession(clusterWithInitializedKeyspace,
 KEYSPACE_NAME));
+        } catch (NoHostAvailableException exception) {
+            sleep(SLEEP_BEFORE_RETRY);
+            return Optional.empty();
+        }
+    }
+
+    private void sleep(long sleepMs) {
+        try {
+            Thread.sleep(sleepMs);
+        } catch(InterruptedException interruptedException) {
+            Throwables.propagate(interruptedException);
+        }
+    }
+
+    public CassandraTypesProvider getTypesProvider() {
+        return typesProvider;
+    }
+}
\ No newline at end of file

Added: 
james/project/trunk/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTypeProviderTest.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTypeProviderTest.java?rev=1711266&view=auto
==============================================================================
--- 
james/project/trunk/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTypeProviderTest.java
 (added)
+++ 
james/project/trunk/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTypeProviderTest.java
 Thu Oct 29 14:13:14 2015
@@ -0,0 +1,109 @@
+/****************************************************************
+ * 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.backends.cassandra.init;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static com.datastax.driver.core.DataType.text;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
+
+import com.datastax.driver.core.schemabuilder.SchemaBuilder;
+import com.google.common.collect.ImmutableList;
+import org.apache.james.backends.cassandra.CassandraClusterSingleton;
+import org.apache.james.backends.cassandra.components.CassandraIndex;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.backends.cassandra.components.CassandraTable;
+import org.apache.james.backends.cassandra.components.CassandraType;
+import org.apache.james.backends.cassandra.init.CassandraTypesProvider;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CassandraTypeProviderTest {
+
+    private static final String TYPE_NAME = "typename";
+    private static final String PROPERTY = "property";
+    
+    private CassandraClusterSingleton cassandra;
+    private CassandraModule module;
+
+    @Before
+    public void setUp() {
+        module = new CassandraModule() {
+            @Override public List<CassandraTable> moduleTables() {
+                return ImmutableList.of();
+            }
+
+            @Override public List<CassandraIndex> moduleIndex() {
+                return ImmutableList.of();
+            }
+
+            @Override public List<CassandraType> moduleTypes() {
+                return ImmutableList.copyOf(
+                    Arrays.asList(new CassandraType(TYPE_NAME, 
SchemaBuilder.createType(TYPE_NAME)
+                        .ifNotExists()
+                        .addColumn(PROPERTY, text()))));
+            }
+        };
+        cassandra = CassandraClusterSingleton.create(module);
+        cassandra.getTypesProvider();
+        cassandra.ensureAllTables();
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void 
getDefinedUserTypeShouldNotReturnNullNorFailWhenTypeIsDefined() {
+        assertThat(cassandra.getTypesProvider().getDefinedUserType(TYPE_NAME))
+            .isNotNull();
+    }
+
+    @Test
+    public void initializeTypesShouldCreateTheTypes() {
+        deleteMailboxBaseType();
+        new CassandraTypesCreator(Arrays.asList(module), 
cassandra.getConf()).initializeTypes();
+        CassandraTypesProvider cassandraTypesProviderTest = new 
CassandraTypesProvider(Arrays.asList(module), cassandra.getConf());
+        assertThat(cassandraTypesProviderTest.getDefinedUserType(TYPE_NAME))
+            .isNotNull();
+    }
+
+    @Test
+    public void initializeTypesShouldNotFailIfCalledTwice() {
+        new CassandraTypesProvider(Arrays.asList(module), cassandra.getConf());
+        assertThat(cassandra.getTypesProvider().getDefinedUserType(TYPE_NAME))
+            .isNotNull();
+    }
+
+    private void deleteMailboxBaseType() {
+        try {
+            cassandra.getConf().execute(SchemaBuilder.dropType(TYPE_NAME));
+        } catch (Exception exception) {
+            exception.printStackTrace();
+            fail("Exception is thrown on Type deletion");
+        }
+    }
+
+
+
+}




---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to