You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2017/01/23 06:26:07 UTC

[1/2] james-project git commit: JAMES-1908 make CassandraJmapTestRule composable

Repository: james-project
Updated Branches:
  refs/heads/master 9ca2ca736 -> fabccf51c


JAMES-1908 make CassandraJmapTestRule composable


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/35816961
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/35816961
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/35816961

Branch: refs/heads/master
Commit: 3581696113c82011236f11151a9647f4fccbdccc
Parents: 9ca2ca7
Author: Luc DUZAN <ld...@linagora.com>
Authored: Thu Jan 19 14:49:51 2017 +0100
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Mon Jan 23 13:17:04 2017 +0700

----------------------------------------------------------------------
 server/container/guice/cassandra-guice/pom.xml  |  5 ++
 .../james/AggregateGuiceModuleTestRule.java     | 82 ++++++++++++++++++++
 .../apache/james/CassandraJamesServerTest.java  |  2 +-
 .../org/apache/james/CassandraJmapTestRule.java | 45 +++++------
 .../CassandraMessageIdManagerInjectionTest.java |  2 +-
 .../org/apache/james/EmbeddedCassandraRule.java | 75 ++++++++++++++++++
 .../apache/james/EmbeddedElasticSearchRule.java | 55 +++++++++++++
 .../org/apache/james/GuiceModuleTestRule.java   | 29 +++++++
 .../apache/james/TempFilesystemTestRule.java    | 51 ++++++++++++
 .../java/org/apache/james/JmapJamesServer.java  |  7 +-
 .../CassandraGetMailboxesMethodTest.java        |  2 +-
 .../CassandraGetMessageListMethodTest.java      |  2 +-
 .../CassandraGetVacationResponseTest.java       |  2 +-
 .../CassandraJmapAuthenticationTest.java        |  2 +-
 .../CassandraSetMailboxesMethodTest.java        |  2 +-
 .../CassandraSetMessagesMethodTest.java         |  2 +-
 .../CassandraSetVacationResponseTest.java       |  2 +-
 .../CassandraVacationIntegrationTest.java       |  2 +-
 .../WebAdminServerIntegrationTest.java          |  2 +-
 19 files changed, 334 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/container/guice/cassandra-guice/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/pom.xml b/server/container/guice/cassandra-guice/pom.xml
index 2f49a97..b1bc20f 100644
--- a/server/container/guice/cassandra-guice/pom.xml
+++ b/server/container/guice/cassandra-guice/pom.xml
@@ -278,6 +278,11 @@
                     <artifactId>mockito-core</artifactId>
                     <scope>test</scope>
                 </dependency>
+                <dependency>
+                    <groupId>org.testcontainers</groupId>
+                    <artifactId>testcontainers</artifactId>
+                    <scope>test</scope>
+                </dependency>
             </dependencies>
         </profile>
         <profile>

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/container/guice/cassandra-guice/src/test/java/org/apache/james/AggregateGuiceModuleTestRule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/AggregateGuiceModuleTestRule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/AggregateGuiceModuleTestRule.java
new file mode 100644
index 0000000..b3c4f71
--- /dev/null
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/AggregateGuiceModuleTestRule.java
@@ -0,0 +1,82 @@
+/****************************************************************
+ * 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;
+
+import java.util.List;
+
+import org.junit.rules.RuleChain;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import com.github.steveash.guavate.Guavate;
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Module;
+import com.google.inject.util.Modules;
+
+
+public class AggregateGuiceModuleTestRule implements GuiceModuleTestRule {
+
+    public static AggregateGuiceModuleTestRule of(GuiceModuleTestRule... subrule) {
+        return new AggregateGuiceModuleTestRule(ImmutableList.copyOf(subrule));
+    }
+
+    private final List<GuiceModuleTestRule> subrule;
+    private final RuleChain chain;
+
+    private AggregateGuiceModuleTestRule(List<GuiceModuleTestRule> subrule) {
+        this.subrule = subrule;
+        this.chain = subrule
+                .stream()
+                .reduce(RuleChain.emptyRuleChain(),
+                        RuleChain::around,
+                        RuleChain::around);
+    }
+
+    public AggregateGuiceModuleTestRule aggregate(GuiceModuleTestRule... subrule) {
+        List<GuiceModuleTestRule> guiceModules = ImmutableList.<GuiceModuleTestRule>builder()
+                .addAll(this.subrule)
+                .add(subrule)
+                .build();
+
+        return new AggregateGuiceModuleTestRule(guiceModules);
+    }
+
+    @Override
+    public Module getModule() {
+        List<Module> modules = subrule
+                    .stream()
+                    .map(GuiceModuleTestRule::getModule)
+                    .collect(Guavate.toImmutableList());
+
+        return Modules.combine(modules);
+    }
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return chain.apply(base, description);
+    }
+
+    @Override
+    public void await() {
+        subrule
+            .parallelStream()
+            .forEach(GuiceModuleTestRule::await);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJamesServerTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJamesServerTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJamesServerTest.java
index 41d6b71..579e30c 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJamesServerTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJamesServerTest.java
@@ -24,7 +24,7 @@ import org.junit.Rule;
 public class CassandraJamesServerTest extends AbstractJmapJamesServerTest {
 
     @Rule
-    public CassandraJmapTestRule cassandraJmap = new CassandraJmapTestRule();
+    public CassandraJmapTestRule cassandraJmap = CassandraJmapTestRule.defaultTestRule();
 
     @Override
     protected JmapJamesServer createJamesServer() {

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJmapTestRule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJmapTestRule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJmapTestRule.java
index 44e7b1f..2ad1b33 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJmapTestRule.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraJmapTestRule.java
@@ -18,11 +18,7 @@
  ****************************************************************/
 
 package org.apache.james;
-import org.apache.james.backends.cassandra.EmbeddedCassandra;
-import org.apache.james.mailbox.elasticsearch.EmbeddedElasticSearch;
-import org.apache.james.modules.CassandraJmapServerModule;
-import org.junit.rules.RuleChain;
-import org.junit.rules.TemporaryFolder;
+import org.apache.james.modules.TestJMAPServerModule;
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
@@ -32,37 +28,36 @@ import com.google.inject.Module;
 
 public class CassandraJmapTestRule implements TestRule {
 
-    private TemporaryFolder temporaryFolder = new TemporaryFolder();
-    private EmbeddedElasticSearch embeddedElasticSearch = new EmbeddedElasticSearch(temporaryFolder);
-    private EmbeddedCassandra cassandra = EmbeddedCassandra.createStartServer();
+    private static final int LIMIT_TO_3_MESSAGES = 3;
 
-    public RuleChain chain = RuleChain
-        .outerRule(temporaryFolder)
-        .around(embeddedElasticSearch);
+    public static CassandraJmapTestRule defaultTestRule() {
+        return new CassandraJmapTestRule(
+                AggregateGuiceModuleTestRule.of(new EmbeddedElasticSearchRule(), new EmbeddedCassandraRule()));
+    }
 
-    public JmapJamesServer jmapServer() {
-        return new JmapJamesServer()
-                    .combineWith(CassandraJamesServerMain.cassandraServerModule)
-                    .overrideWith(new CassandraJmapServerModule(temporaryFolder, embeddedElasticSearch, cassandra));
+    private GuiceModuleTestRule guiceModuleTestRule;
+
+    public CassandraJmapTestRule(GuiceModuleTestRule... guiceModuleTestRule) {
+        this.guiceModuleTestRule =
+                AggregateGuiceModuleTestRule
+                    .of(guiceModuleTestRule)
+                    .aggregate(new TempFilesystemTestRule());
     }
 
-    public JmapJamesServer jmapServer(Module additional) {
+    public JmapJamesServer jmapServer(Module... additionals) {
         return new JmapJamesServer()
-            .combineWith(CassandraJamesServerMain.cassandraServerModule, additional)
-            .overrideWith(new CassandraJmapServerModule(temporaryFolder, embeddedElasticSearch, cassandra));
+            .combineWith(CassandraJamesServerMain.cassandraServerModule)
+            .overrideWith(new TestJMAPServerModule(LIMIT_TO_3_MESSAGES))
+            .overrideWith(guiceModuleTestRule.getModule())
+            .overrideWith(additionals);
     }
 
     @Override
     public Statement apply(Statement base, Description description) {
-        return chain.apply(base, description);
+        return guiceModuleTestRule.apply(base, description);
     }
-    
 
-    public EmbeddedElasticSearch getElasticSearch() {
-        return embeddedElasticSearch;
-    }
-    
     public void await() {
-        embeddedElasticSearch.awaitForElasticSearch();
+        guiceModuleTestRule.await();
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraMessageIdManagerInjectionTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraMessageIdManagerInjectionTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraMessageIdManagerInjectionTest.java
index 7e3b5dd..b5e9dc2 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraMessageIdManagerInjectionTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraMessageIdManagerInjectionTest.java
@@ -41,7 +41,7 @@ import com.google.inject.multibindings.Multibinder;
 public class CassandraMessageIdManagerInjectionTest {
 
     @Rule
-    public CassandraJmapTestRule cassandraJmap = new CassandraJmapTestRule();
+    public CassandraJmapTestRule cassandraJmap = CassandraJmapTestRule.defaultTestRule();
     private JmapJamesServer server;
 
     @Before

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/container/guice/cassandra-guice/src/test/java/org/apache/james/EmbeddedCassandraRule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/EmbeddedCassandraRule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/EmbeddedCassandraRule.java
new file mode 100644
index 0000000..c9a65a7
--- /dev/null
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/EmbeddedCassandraRule.java
@@ -0,0 +1,75 @@
+/****************************************************************
+ * 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;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.backends.cassandra.EmbeddedCassandra;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import com.datastax.driver.core.Session;
+import com.google.inject.Module;
+import com.google.inject.Scopes;
+import com.google.inject.util.Modules;
+
+
+public class EmbeddedCassandraRule implements GuiceModuleTestRule {
+
+    public static class SessionProvider implements Provider<Session> {
+
+        private final Session session;
+
+        @Inject
+        private SessionProvider(CassandraCluster cluster) {
+            session = cluster.getConf();
+        }
+
+        @Override
+        public Session get() {
+            return session;
+        }
+    }
+
+    private EmbeddedCassandra cassandra;
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                cassandra = EmbeddedCassandra.createStartServer();
+                base.evaluate();
+            }
+        };
+    }
+
+    @Override
+    public void await() {
+    }
+
+    @Override
+    public Module getModule() {
+        return Modules.combine(
+                (binder) -> binder.bind(EmbeddedCassandra.class).toInstance(cassandra),
+                (binder) -> binder.bind(Session.class).toProvider(SessionProvider.class).in(Scopes.SINGLETON));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/container/guice/cassandra-guice/src/test/java/org/apache/james/EmbeddedElasticSearchRule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/EmbeddedElasticSearchRule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/EmbeddedElasticSearchRule.java
new file mode 100644
index 0000000..efb5508
--- /dev/null
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/EmbeddedElasticSearchRule.java
@@ -0,0 +1,55 @@
+/****************************************************************
+ * 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;
+import org.apache.james.mailbox.elasticsearch.EmbeddedElasticSearch;
+import org.apache.james.modules.TestElasticSearchModule;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import com.google.inject.Module;
+
+
+public class EmbeddedElasticSearchRule implements GuiceModuleTestRule {
+
+    private final TemporaryFolder temporaryFolder = new TemporaryFolder();
+    private final EmbeddedElasticSearch embeddedElasticSearch = new EmbeddedElasticSearch(temporaryFolder);
+
+    private final RuleChain chain = RuleChain
+        .outerRule(temporaryFolder)
+        .around(embeddedElasticSearch);
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return chain.apply(base, description);
+    }
+
+    @Override
+    public void await() {
+        embeddedElasticSearch.awaitForElasticSearch();
+    }
+
+
+    @Override
+    public Module getModule() {
+        return new TestElasticSearchModule(embeddedElasticSearch);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/container/guice/cassandra-guice/src/test/java/org/apache/james/GuiceModuleTestRule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/GuiceModuleTestRule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/GuiceModuleTestRule.java
new file mode 100644
index 0000000..4b78ea8
--- /dev/null
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/GuiceModuleTestRule.java
@@ -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;
+
+import org.junit.rules.TestRule;
+
+import com.google.inject.Module;
+
+public interface GuiceModuleTestRule extends TestRule {
+    Module getModule();
+    void await();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/container/guice/cassandra-guice/src/test/java/org/apache/james/TempFilesystemTestRule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/TempFilesystemTestRule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/TempFilesystemTestRule.java
new file mode 100644
index 0000000..4037f0c
--- /dev/null
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/TempFilesystemTestRule.java
@@ -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;
+
+import org.apache.james.modules.TestFilesystemModule;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import com.google.inject.Module;
+
+public class TempFilesystemTestRule implements GuiceModuleTestRule {
+
+    private final TemporaryFolder temporaryFolder;
+
+    public TempFilesystemTestRule() {
+        this.temporaryFolder = new TemporaryFolder();
+    }
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return temporaryFolder.apply(base, description);
+    }
+
+    @Override
+    public Module getModule() {
+        return new TestFilesystemModule(temporaryFolder::getRoot);
+    }
+
+    @Override
+    public void await() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/container/guice/guice-common/src/main/java/org/apache/james/JmapJamesServer.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/JmapJamesServer.java b/server/container/guice/guice-common/src/main/java/org/apache/james/JmapJamesServer.java
index 9dabe86..46122a8 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/JmapJamesServer.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/JmapJamesServer.java
@@ -19,6 +19,7 @@
 package org.apache.james;
 
 import java.util.Arrays;
+import java.util.Collection;
 
 import org.apache.james.utils.JmapGuiceProbe;
 import org.apache.james.utils.WebAdminGuiceProbe;
@@ -42,6 +43,10 @@ public class JmapJamesServer extends GuiceJamesServerImpl implements GuiceJamesS
     }
 
     public JmapJamesServer overrideWith(Module... overrides) {
+        return overrideWith(Arrays.asList(overrides));
+    }
+
+    public JmapJamesServer overrideWith(Collection<Module> overrides) {
         return new JmapJamesServer(Modules.override(module).with(overrides));
     }
 
@@ -55,5 +60,5 @@ public class JmapJamesServer extends GuiceJamesServerImpl implements GuiceJamesS
         return getGuiceProbeProvider().getProbe(WebAdminGuiceProbe.class);
     }
 
-    
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraGetMailboxesMethodTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraGetMailboxesMethodTest.java b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraGetMailboxesMethodTest.java
index 67a7cd1..299a8f1 100644
--- a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraGetMailboxesMethodTest.java
+++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraGetMailboxesMethodTest.java
@@ -27,7 +27,7 @@ import org.junit.Rule;
 public class CassandraGetMailboxesMethodTest extends GetMailboxesMethodTest {
 
     @Rule 
-    public CassandraJmapTestRule rule = new CassandraJmapTestRule();
+    public CassandraJmapTestRule rule = CassandraJmapTestRule.defaultTestRule();
     
     @Override
     protected JmapJamesServer createJmapServer() {

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraGetMessageListMethodTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraGetMessageListMethodTest.java b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraGetMessageListMethodTest.java
index 8d5aa57..cae3a6d 100644
--- a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraGetMessageListMethodTest.java
+++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraGetMessageListMethodTest.java
@@ -27,7 +27,7 @@ import org.junit.Rule;
 public class CassandraGetMessageListMethodTest extends GetMessageListMethodTest {
 
     @Rule 
-    public CassandraJmapTestRule rule = new CassandraJmapTestRule();
+    public CassandraJmapTestRule rule = CassandraJmapTestRule.defaultTestRule();
     
     @Override
     protected JmapJamesServer createJmapServer() {

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraGetVacationResponseTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraGetVacationResponseTest.java b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraGetVacationResponseTest.java
index 6e52b05..c50f048 100644
--- a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraGetVacationResponseTest.java
+++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraGetVacationResponseTest.java
@@ -28,7 +28,7 @@ import org.junit.Rule;
 public class CassandraGetVacationResponseTest extends GetVacationResponseTest {
 
     @Rule 
-    public CassandraJmapTestRule rule = new CassandraJmapTestRule();
+    public CassandraJmapTestRule rule = CassandraJmapTestRule.defaultTestRule();
     
     @Override
     protected JmapJamesServer createJmapServer(ZonedDateTimeProvider zonedDateTimeProvider) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraJmapAuthenticationTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraJmapAuthenticationTest.java b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraJmapAuthenticationTest.java
index 28667a3..d4027aa 100644
--- a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraJmapAuthenticationTest.java
+++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraJmapAuthenticationTest.java
@@ -28,7 +28,7 @@ import org.junit.Rule;
 public class CassandraJmapAuthenticationTest extends JMAPAuthenticationTest {
 
     @Rule 
-    public CassandraJmapTestRule rule = new CassandraJmapTestRule();
+    public CassandraJmapTestRule rule = CassandraJmapTestRule.defaultTestRule();
     
     @Override
     protected JmapJamesServer createJmapServer(FixedDateZonedDateTimeProvider zonedDateTimeProvider) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMailboxesMethodTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMailboxesMethodTest.java b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMailboxesMethodTest.java
index 10c32e5..02e5333 100644
--- a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMailboxesMethodTest.java
+++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMailboxesMethodTest.java
@@ -27,7 +27,7 @@ import org.junit.Rule;
 public class CassandraSetMailboxesMethodTest extends SetMailboxesMethodTest {
 
     @Rule 
-    public CassandraJmapTestRule rule = new CassandraJmapTestRule();
+    public CassandraJmapTestRule rule = CassandraJmapTestRule.defaultTestRule();
     
     @Override
     protected JmapJamesServer createJmapServer() {

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMessagesMethodTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMessagesMethodTest.java b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMessagesMethodTest.java
index 12b4045..e0e36c5 100644
--- a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMessagesMethodTest.java
+++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMessagesMethodTest.java
@@ -29,7 +29,7 @@ import org.junit.Rule;
 public class CassandraSetMessagesMethodTest extends SetMessagesMethodTest {
 
     @Rule 
-    public CassandraJmapTestRule rule = new CassandraJmapTestRule();
+    public CassandraJmapTestRule rule = CassandraJmapTestRule.defaultTestRule();
 
     @Override
     protected JmapJamesServer createJmapServer() {

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetVacationResponseTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetVacationResponseTest.java b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetVacationResponseTest.java
index 463971f..6300459 100644
--- a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetVacationResponseTest.java
+++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetVacationResponseTest.java
@@ -27,7 +27,7 @@ import org.junit.Rule;
 public class CassandraSetVacationResponseTest extends SetVacationResponseTest {
 
     @Rule 
-    public CassandraJmapTestRule rule = new CassandraJmapTestRule();
+    public CassandraJmapTestRule rule = CassandraJmapTestRule.defaultTestRule();
     
     @Override
     protected JmapJamesServer createJmapServer() {

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraVacationIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraVacationIntegrationTest.java b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraVacationIntegrationTest.java
index c16c96d..adbb077 100644
--- a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraVacationIntegrationTest.java
+++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraVacationIntegrationTest.java
@@ -28,7 +28,7 @@ public class CassandraVacationIntegrationTest extends VacationIntegrationTest {
 
 
     @Rule 
-    public CassandraJmapTestRule rule = new CassandraJmapTestRule();
+    public CassandraJmapTestRule rule = CassandraJmapTestRule.defaultTestRule();
     
     @Override
     protected JmapJamesServer createJmapServer() {

http://git-wip-us.apache.org/repos/asf/james-project/blob/35816961/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java b/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java
index 4e7744e..6bc58fa 100644
--- a/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java
@@ -52,7 +52,7 @@ public class WebAdminServerIntegrationTest {
     public static final String SPECIFIC_MAILBOX = SPECIFIC_USER + SEPARATOR + UserMailboxesRoutes.MAILBOXES + SEPARATOR + MAILBOX;
 
     @Rule
-    public CassandraJmapTestRule cassandraJmapTestRule = new CassandraJmapTestRule();
+    public CassandraJmapTestRule cassandraJmapTestRule = CassandraJmapTestRule.defaultTestRule();
 
     private JmapJamesServer guiceJamesServer;
 


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


[2/2] james-project git commit: JAMES-1908 add support for multiple cassandra node ip in configuration

Posted by bt...@apache.org.
JAMES-1908 add support for multiple cassandra node ip in configuration


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/fabccf51
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/fabccf51
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/fabccf51

Branch: refs/heads/master
Commit: fabccf51c74bdc3361a0abea919b22421a617f45
Parents: 3581696
Author: Luc DUZAN <ld...@linagora.com>
Authored: Thu Jan 19 14:51:26 2017 +0100
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Mon Jan 23 13:17:21 2017 +0700

----------------------------------------------------------------------
 .../cassandra/init/CassandraNodeIpAndPort.java  |  95 +++++++++++++++
 .../backends/cassandra/init/ClusterFactory.java |  25 ++--
 .../init/CassandraNodeIpAndPortTest.java        |  94 +++++++++++++++
 .../destination/conf/cassandra.properties       |   4 +-
 server/container/guice/cassandra-guice/pom.xml  |   6 +
 .../sample-configuration/cassandra.properties   |   3 +-
 .../mailbox/CassandraSessionConfiguration.java  |  31 +++++
 .../modules/mailbox/CassandraSessionModule.java |  34 ++++--
 .../org/apache/james/CassandraConfTest.java     | 119 +++++++++++++++++++
 .../org/apache/james/DockerCassandraRule.java   |  92 ++++++++++++++
 .../src/test/resources/test.properties          |   3 +-
 server/src/site/xdoc/config-cassandra.xml       |   6 +-
 12 files changed, 474 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/fabccf51/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPort.java
----------------------------------------------------------------------
diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPort.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPort.java
new file mode 100644
index 0000000..b9b3f19
--- /dev/null
+++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPort.java
@@ -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.backends.cassandra.init;
+
+import java.util.List;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+public class CassandraNodeIpAndPort {
+    public static final int DEFAULT_CASSANDRA_PORT = 9042;
+
+    public static CassandraNodeIpAndPort parseConfString(String ipAndPort) {
+        Preconditions.checkNotNull(ipAndPort);
+        Preconditions.checkArgument(!ipAndPort.isEmpty());
+
+        List<String> parts = Splitter.on(':')
+                .trimResults()
+                .splitToList(ipAndPort);
+
+        if (parts.size() < 1 || parts.size() > 2) {
+            throw new IllegalArgumentException(ipAndPort + " is not a valid cassandra node");
+        }
+
+        String ip = parts.get(0);
+        int port = getPortFromConfPart(parts);
+
+        return new CassandraNodeIpAndPort(ip, port);
+    }
+
+    private static int getPortFromConfPart(List<String> parts) {
+        if (parts.size() == 2) {
+            return Integer.valueOf(parts.get(1));
+        } else {
+            return DEFAULT_CASSANDRA_PORT;
+        }
+    }
+
+    private final String ip;
+    private final int port;
+
+    public CassandraNodeIpAndPort(String ip, int port) {
+        this.ip = ip;
+        this.port = port;
+    }
+
+    public CassandraNodeIpAndPort(String ip) {
+        this(ip, DEFAULT_CASSANDRA_PORT);
+    }
+
+    public String getIp() {
+        return ip;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(ip, port);
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (object instanceof CassandraNodeIpAndPort) {
+            CassandraNodeIpAndPort that = (CassandraNodeIpAndPort) object;
+            return Objects.equal(this.ip, that.ip) && Objects.equal(this.port, that.port);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return this.ip + ":" + this.port;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fabccf51/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterFactory.java
----------------------------------------------------------------------
diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterFactory.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterFactory.java
index 1f61091..8660933 100644
--- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterFactory.java
+++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterFactory.java
@@ -29,25 +29,14 @@ import com.google.common.collect.ImmutableList;
 
 public class ClusterFactory {
 
-    public static class CassandraServer {
-        private final String ip;
-        private final 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, 
+    public static Cluster createClusterForClusterWithPassWord(List<CassandraNodeIpAndPort> servers, String userName, String password,
             Optional<Integer> refreshSchemaIntervalMillis) {
 
         Cluster.Builder clusterBuilder = Cluster.builder();
         servers.forEach(
-            (server) -> clusterBuilder.addContactPoint(server.ip).withPort(server.port)
+            (server) -> clusterBuilder.addContactPoint(server.getIp()).withPort(server.getPort())
         );
         if(!Strings.isNullOrEmpty(userName) && !Strings.isNullOrEmpty(password)) {
             clusterBuilder.withCredentials(userName, password);
@@ -58,23 +47,23 @@ public class ClusterFactory {
         return clusterBuilder.build();
     }
 
-    public static Cluster createClusterForClusterWithoutPassWord(List<CassandraServer> servers) {
+    public static Cluster createClusterForClusterWithoutPassWord(List<CassandraNodeIpAndPort> servers) {
         return createClusterForClusterWithPassWord(servers, null, null, Optional.empty());
     }
 
     public static Cluster createClusterForSingleServerWithPassWord(String ip, int port, String userName, String password) {
-        return createClusterForClusterWithPassWord(ImmutableList.of(new CassandraServer(ip, port)), userName, password, Optional.empty());
+        return createClusterForClusterWithPassWord(ImmutableList.of(new CassandraNodeIpAndPort(ip, port)), userName, password, Optional.empty());
     }
 
     public static Cluster createClusterForSingleServerWithoutPassWord(String ip, int port) {
-        return createClusterForClusterWithPassWord(ImmutableList.of(new CassandraServer(ip, port)), null, null, Optional.empty());
+        return createClusterForClusterWithPassWord(ImmutableList.of(new CassandraNodeIpAndPort(ip, port)), null, null, Optional.empty());
     }
 
     public static Cluster createTestingCluster(String ip, int port) {
-        return createClusterForClusterWithPassWord(ImmutableList.of(new CassandraServer(ip, port)), null, null, Optional.of(0));
+        return createClusterForClusterWithPassWord(ImmutableList.of(new CassandraNodeIpAndPort(ip, port)), null, null, Optional.of(0));
     }
 
     public static Cluster createDefaultSession() {
-        return createClusterForSingleServerWithoutPassWord(DEFAULT_CLUSTER_IP, DEFAULT_CLUSTER_PORT);
+        return createClusterForSingleServerWithoutPassWord(DEFAULT_CLUSTER_IP, CassandraNodeIpAndPort.DEFAULT_CASSANDRA_PORT);
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/fabccf51/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPortTest.java
----------------------------------------------------------------------
diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPortTest.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPortTest.java
new file mode 100644
index 0000000..1e97ef3
--- /dev/null
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPortTest.java
@@ -0,0 +1,94 @@
+/****************************************************************
+ * 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 static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class CassandraNodeIpAndPortTest {
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void parseConfStringShouldParseConfWithIpAndPort() {
+        //Given
+        String ipAndPort = "142.145.254.111:44";
+        int expectedPort = 44;
+        String expectedIp = "142.145.254.111";
+
+        //When
+        CassandraNodeIpAndPort actual = CassandraNodeIpAndPort.parseConfString(ipAndPort);
+
+        //Then
+        assertThat(actual).isEqualTo(new CassandraNodeIpAndPort(expectedIp, expectedPort));
+    }
+
+    @Test
+    public void parseConfStringShouldParseConfWithIpOnly() {
+        //Given
+        String ipAndPort = "142.145.254.111";
+        int expectedPort = CassandraNodeIpAndPort.DEFAULT_CASSANDRA_PORT;
+        String expectedIp = "142.145.254.111";
+
+        //When
+        CassandraNodeIpAndPort actual = CassandraNodeIpAndPort.parseConfString(ipAndPort);
+
+        //Then
+        assertThat(actual).isEqualTo(new CassandraNodeIpAndPort(expectedIp, expectedPort));
+    }
+
+    @Test
+    public void parseConfStringShouldFailWhenConfigIsAnEmptyString() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        //Given
+        String ipAndPort = "";
+
+        //When
+        CassandraNodeIpAndPort.parseConfString(ipAndPort);
+    }
+
+    @Test
+    public void parseConfStringShouldFailWhenConfigIsANullString() {
+        expectedException.expect(NullPointerException.class);
+
+        //Given
+        String ipAndPort = null;
+
+        //When
+        CassandraNodeIpAndPort.parseConfString(ipAndPort);
+    }
+
+
+    @Test
+    public void parseConfStringShouldFailWhenConfigIsInvalid() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        //Given
+        String ipAndPort = "10.10.10.10:42:43";
+
+        //When
+        CassandraNodeIpAndPort.parseConfString(ipAndPort);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fabccf51/dockerfiles/run/guice/cassandra/destination/conf/cassandra.properties
----------------------------------------------------------------------
diff --git a/dockerfiles/run/guice/cassandra/destination/conf/cassandra.properties b/dockerfiles/run/guice/cassandra/destination/conf/cassandra.properties
index c9a94bb..6070413 100644
--- a/dockerfiles/run/guice/cassandra/destination/conf/cassandra.properties
+++ b/dockerfiles/run/guice/cassandra/destination/conf/cassandra.properties
@@ -1,7 +1,5 @@
 # Configuration file for cassandra mailbox
-
-cassandra.ip=cassandra
-cassandra.port=9042
+cassandra.nodes=cassandra
 cassandra.keyspace=apache_james
 cassandra.replication.factor=1
 cassandra.retryConnection.maxRetries=10

http://git-wip-us.apache.org/repos/asf/james-project/blob/fabccf51/server/container/guice/cassandra-guice/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/pom.xml b/server/container/guice/cassandra-guice/pom.xml
index b1bc20f..be98559 100644
--- a/server/container/guice/cassandra-guice/pom.xml
+++ b/server/container/guice/cassandra-guice/pom.xml
@@ -244,6 +244,12 @@
                     <scope>test</scope>
                 </dependency>
                 <dependency>
+                    <groupId>${project.groupId}</groupId>
+                    <artifactId>james-server-util-java8</artifactId>
+                    <scope>test</scope>
+                    <type>test-jar</type>
+                </dependency>
+                <dependency>
                     <groupId>ch.qos.logback</groupId>
                     <artifactId>logback-classic</artifactId>
                     <version>1.1.7</version>

http://git-wip-us.apache.org/repos/asf/james-project/blob/fabccf51/server/container/guice/cassandra-guice/sample-configuration/cassandra.properties
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/sample-configuration/cassandra.properties b/server/container/guice/cassandra-guice/sample-configuration/cassandra.properties
index 1358332..80b8426 100644
--- a/server/container/guice/cassandra-guice/sample-configuration/cassandra.properties
+++ b/server/container/guice/cassandra-guice/sample-configuration/cassandra.properties
@@ -1,6 +1,5 @@
 # Configuration file for cassandra mailbox
 
-cassandra.ip=172.17.0.2
-cassandra.port=9042
+cassandra.nodes=172.17.0.2:9042
 cassandra.keyspace=apache_james
 cassandra.replication.factor=1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/fabccf51/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionConfiguration.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionConfiguration.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionConfiguration.java
new file mode 100644
index 0000000..29c3ea3
--- /dev/null
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionConfiguration.java
@@ -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.modules.mailbox;
+
+import java.io.FileNotFoundException;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+
+public interface CassandraSessionConfiguration {
+
+    PropertiesConfiguration getConfiguration() throws FileNotFoundException, ConfigurationException;
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fabccf51/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
index 716b95f..a79ff8f 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
@@ -19,6 +19,8 @@
 package org.apache.james.modules.mailbox;
 
 import java.io.FileNotFoundException;
+import java.util.Arrays;
+import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ScheduledExecutorService;
@@ -27,6 +29,7 @@ import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.PropertiesConfiguration;
 import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
+import org.apache.james.backends.cassandra.init.CassandraNodeIpAndPort;
 import org.apache.james.backends.cassandra.init.CassandraZonedDateTimeModule;
 import org.apache.james.backends.cassandra.init.ClusterFactory;
 import org.apache.james.backends.cassandra.init.ClusterWithKeyspaceCreatedFactory;
@@ -36,6 +39,7 @@ import org.apache.james.filesystem.api.FileSystem;
 import com.datastax.driver.core.Cluster;
 import com.datastax.driver.core.Session;
 import com.datastax.driver.core.exceptions.NoHostAvailableException;
+import com.github.steveash.guavate.Guavate;
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import com.google.inject.Singleton;
@@ -54,7 +58,7 @@ public class CassandraSessionModule extends AbstractModule {
         Multibinder<CassandraModule> cassandraDataDefinitions = Multibinder.newSetBinder(binder(), CassandraModule.class);
         cassandraDataDefinitions.addBinding().to(CassandraZonedDateTimeModule.class);
     }
-    
+
     @Provides
     @Singleton
     CassandraModule composeDataDefinitions(Set<CassandraModule> modules) {
@@ -63,30 +67,42 @@ public class CassandraSessionModule extends AbstractModule {
 
     @Provides
     @Singleton
-    Session provideSession(FileSystem fileSystem, Cluster cluster, CassandraModule cassandraModule)
+    Session provideSession(CassandraSessionConfiguration configuration, Cluster cluster, CassandraModule cassandraModule)
             throws FileNotFoundException, ConfigurationException{
-        PropertiesConfiguration configuration = getConfiguration(fileSystem);
-        String keyspace = configuration.getString("cassandra.keyspace");
+        String keyspace = configuration.getConfiguration().getString("cassandra.keyspace");
         return new SessionWithInitializedTablesFactory(cassandraModule).createSession(cluster, keyspace);
     }
 
     @Provides
     @Singleton
-    Cluster provideCluster(FileSystem fileSystem, AsyncRetryExecutor executor) throws FileNotFoundException, ConfigurationException, ExecutionException, InterruptedException {
-        PropertiesConfiguration configuration = getConfiguration(fileSystem);
+    CassandraSessionConfiguration getCassandraSessionConfiguration(FileSystem fileSystem) {
+        return () -> getConfiguration(fileSystem);
+    }
+
+    @Provides
+    @Singleton
+    Cluster provideCluster(CassandraSessionConfiguration cassandraSessionConfiguration, AsyncRetryExecutor executor) throws FileNotFoundException, ConfigurationException, ExecutionException, InterruptedException {
+        PropertiesConfiguration configuration = cassandraSessionConfiguration.getConfiguration();
+        List<CassandraNodeIpAndPort> servers = listCassandraServers(configuration);
 
         return getRetryer(executor, configuration)
                 .getWithRetry(ctx -> ClusterWithKeyspaceCreatedFactory
                         .config(
-                            ClusterFactory.createClusterForSingleServerWithoutPassWord(
-                                    configuration.getString("cassandra.ip"),
-                                    configuration.getInt("cassandra.port")),
+                            ClusterFactory.createClusterForClusterWithoutPassWord(servers),
                             configuration.getString("cassandra.keyspace"))
                         .replicationFactor(configuration.getInt("cassandra.replication.factor"))
                         .clusterWithInitializedKeyspace())
                 .get();
     }
 
+    private List<CassandraNodeIpAndPort> listCassandraServers(PropertiesConfiguration configuration) {
+        String[] ipAndPorts = configuration.getStringArray("cassandra.nodes");
+
+        return Arrays.stream(ipAndPorts)
+                .map(CassandraNodeIpAndPort::parseConfString)
+                .collect(Guavate.toImmutableList());
+    }
+
     private static AsyncRetryExecutor getRetryer(AsyncRetryExecutor executor, PropertiesConfiguration configuration) {
         return executor.retryOn(NoHostAvailableException.class)
                 .withProportionalJitter()

http://git-wip-us.apache.org/repos/asf/james-project/blob/fabccf51/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraConfTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraConfTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraConfTest.java
new file mode 100644
index 0000000..6d1f0a2
--- /dev/null
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraConfTest.java
@@ -0,0 +1,119 @@
+/****************************************************************
+ * 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;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.nio.charset.Charset;
+
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.james.modules.mailbox.CassandraSessionConfiguration;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.testcontainers.DockerClientFactory;
+
+public class CassandraConfTest {
+
+    private static final int IMAP_PORT = 1143;
+
+    private static String getDockerHostIp() {
+        return DockerClientFactory.instance().dockerHostIpAddress();
+    }
+
+    private final DockerCassandraRule dockerCassandraRule = new DockerCassandraRule();
+
+    @Rule
+    public CassandraJmapTestRule cassandraJmapTestRule = new CassandraJmapTestRule(dockerCassandraRule,
+            new EmbeddedElasticSearchRule());
+
+    private GuiceJamesServerImpl jamesServer;
+    private SocketChannel socketChannel;
+
+    @Before
+    public void setUp() throws IOException {
+        socketChannel = SocketChannel.open();
+    }
+
+    @After
+    public void after() throws IOException {
+        socketChannel.close();
+        if (jamesServer != null) {
+            jamesServer.stop();
+        }
+    }
+
+    @Test
+    public void serverShouldStartServiceWhenNodeIsReachable() throws Exception {
+        jamesServer = cassandraJmapTestRule.jmapServer();
+
+        assertThatServerStartCorrectly();
+    }
+
+    @Test
+    public void serverShouldStartWhenOneCassandraNodeIsUnreachable() throws Exception {
+        String unreachableNode = "10.2.3.42";
+        PropertiesConfiguration configuration = getCassandraConfigurationForDocker(unreachableNode + "," + dockerCassandraRule.getIp());
+
+        jamesServer = cassandraJmapTestRule.jmapServer(
+                (binder) -> binder.bind(CassandraSessionConfiguration.class).toInstance(() -> configuration));
+
+        assertThatServerStartCorrectly();
+    }
+
+    @Test
+    public void configShouldWorkWithNonDefaultPort() throws Exception {
+        PropertiesConfiguration configuration = getCassandraConfigurationForDocker(getDockerHostIp() + ":" + dockerCassandraRule.getBindingPort());
+        jamesServer = cassandraJmapTestRule.jmapServer(
+                (binder) -> binder.bind(CassandraSessionConfiguration.class).toInstance(() -> configuration));
+
+        assertThatServerStartCorrectly();
+    }
+
+    private void assertThatServerStartCorrectly() throws Exception, IOException {
+        jamesServer.start();
+        socketChannel.connect(new InetSocketAddress("127.0.0.1", IMAP_PORT));
+        assertThat(getServerConnectionResponse(socketChannel)).startsWith("* OK JAMES IMAP4rev1 Server");
+    }
+
+    private PropertiesConfiguration getCassandraConfigurationForDocker(String confIps) {
+        PropertiesConfiguration configuration = new PropertiesConfiguration();
+
+        configuration.addProperty("cassandra.nodes", confIps);
+        configuration.addProperty("cassandra.keyspace", "apache_james");
+        configuration.addProperty("cassandra.replication.factor", 1);
+        configuration.addProperty("cassandra.retryConnection.maxRetries", 10);
+        configuration.addProperty("cassandra.retryConnection", 5000);
+
+        return configuration;
+    }
+
+    private String getServerConnectionResponse(SocketChannel socketChannel) throws IOException {
+        ByteBuffer byteBuffer = ByteBuffer.allocate(1000);
+        socketChannel.read(byteBuffer);
+        byte[] bytes = byteBuffer.array();
+        return new String(bytes, Charset.forName("UTF-8"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fabccf51/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java
new file mode 100644
index 0000000..fa01e1c
--- /dev/null
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java
@@ -0,0 +1,92 @@
+/****************************************************************
+ * 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;
+import java.util.Arrays;
+
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.james.modules.mailbox.CassandraSessionConfiguration;
+import org.apache.james.util.streams.SwarmGenericContainer;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.shaded.com.github.dockerjava.api.model.ExposedPort;
+import org.testcontainers.shaded.com.github.dockerjava.api.model.Ports;
+import org.testcontainers.shaded.com.github.dockerjava.api.model.Ports.Binding;
+
+import com.google.inject.Module;
+
+
+public class DockerCassandraRule implements GuiceModuleTestRule {
+
+    private static final int CASSANDRA_PORT = 9042;
+
+    private static boolean isBindingToEveryThing(Binding binding) {
+        String bindingIp = binding.getHostIp();
+        return bindingIp == null || bindingIp.equals("0.0.0.0");
+    }
+
+    private PropertiesConfiguration getCassandraConfigurationForDocker() {
+        PropertiesConfiguration configuration = new PropertiesConfiguration();
+
+        configuration.addProperty("cassandra.nodes", getIp() + ":" + CASSANDRA_PORT);
+        configuration.addProperty("cassandra.keyspace", "apache_james");
+        configuration.addProperty("cassandra.replication.factor", 1);
+        configuration.addProperty("cassandra.retryConnection.maxRetries", 10);
+        configuration.addProperty("cassandra.retryConnection", 5000);
+
+        return configuration;
+    }
+
+    private GenericContainer<SwarmGenericContainer> cassandraContainer = new SwarmGenericContainer("cassandra:2.2");
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return cassandraContainer.apply(base, description);
+    }
+
+    @Override
+    public void await() {
+    }
+
+    @Override
+    public Module getModule() {
+        return (binder) -> binder.bind(CassandraSessionConfiguration.class).toInstance(this::getCassandraConfigurationForDocker);
+    }
+
+    @SuppressWarnings("deprecation")
+    public String getIp() {
+        return cassandraContainer.getContainerInfo().getNetworkSettings().getIpAddress();
+    }
+
+    public int getBindingPort() {
+        Ports.Binding[] bindings =  cassandraContainer
+                .getContainerInfo()
+                .getNetworkSettings()
+                .getPorts()
+                .getBindings()
+                .get(ExposedPort.tcp(CASSANDRA_PORT));
+
+        return Integer.valueOf(
+                Arrays.stream(bindings)
+                    .filter(DockerCassandraRule::isBindingToEveryThing)
+                    .map(binding -> binding.getHostPortSpec())
+                    .findFirst().get());
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fabccf51/server/container/guice/guice-common/src/test/resources/test.properties
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/test/resources/test.properties b/server/container/guice/guice-common/src/test/resources/test.properties
index b4db9c1..a020cc8 100644
--- a/server/container/guice/guice-common/src/test/resources/test.properties
+++ b/server/container/guice/guice-common/src/test/resources/test.properties
@@ -1,6 +1,5 @@
 # Configuration file for cassandra mailbox
 
-cassandra.ip=127.0.0.1
-cassandra.port=9142
+cassandra.nodes=127.0.0.1:9142
 cassandra.keyspace=apache_james
 cassandra.replication.factor=1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/fabccf51/server/src/site/xdoc/config-cassandra.xml
----------------------------------------------------------------------
diff --git a/server/src/site/xdoc/config-cassandra.xml b/server/src/site/xdoc/config-cassandra.xml
index 88efb3c..70160c7 100644
--- a/server/src/site/xdoc/config-cassandra.xml
+++ b/server/src/site/xdoc/config-cassandra.xml
@@ -30,10 +30,8 @@
     <p>Consult <a href="https://github.com/apache/james-project/tree/master/server/app/src/main/resources/cassandra-template.properties">cassandra-template.properties</a> to get some examples and hints.</p>
 
       <dl>
-        <dt><strong>cassandra.ip</strong></dt>
-        <dd>Is the IP (or host) of the Cassandra used. (cluster is not yet supported)</dd>
-        <dt><strong>cassandra.port</strong></dt>
-        <dd>Is the port used to connect to Cassandra.</dd>
+        <dt><strong>cassandra.nodes</strong></dt>
+        <dd>List of some nodes of the cassandra's cluster in following format host:port or host, if the port is not specified we use 9042</dd>
         <dt><strong>cassandra.keyspace</strong></dt>
         <dd>Is the name of the keyspace used by James.</dd>
         <dt><strong>cassandra.replication.factor</strong></dt>


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