Repository: james-project
Updated Branches:
  refs/heads/master c739d3aec -> 3b223d537


JAMES-2618 Write SchemaVersion after Types and Tables creation


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

Branch: refs/heads/master
Commit: d796a1d3c103683c2096313805745c78f6d5ef64
Parents: c739d3a
Author: Gautier DI FOLCO <[email protected]>
Authored: Tue Dec 4 18:46:46 2018 +0100
Committer: Raphael Ouazana <[email protected]>
Committed: Wed Dec 19 09:23:43 2018 +0100

----------------------------------------------------------------------
 backends-common/cassandra/pom.xml               |   5 +
 .../cassandra/components/CassandraTable.java    |  55 ++++++-
 .../cassandra/components/CassandraType.java     |  50 +++++-
 .../cassandra/init/CassandraTableManager.java   |  15 +-
 .../cassandra/init/CassandraTypesCreator.java   |  14 +-
 .../SessionWithInitializedTablesFactory.java    |  29 +++-
 .../components/CassandraTableTest.java          | 103 ++++++++++++
 .../cassandra/components/CassandraTypeTest.java | 104 +++++++++++++
 .../init/CassandraTableManagerTest.java         | 104 +++++++++++++
 .../init/CassandraTypeProviderTest.java         |   5 +-
 .../init/CassandraTypesCreatorTest.java         | 112 +++++++++++++
 ...SessionWithInitializedTablesFactoryTest.java | 156 +++++++++++++++++++
 .../cassandra/mail/MailboxAggregateModule.java  |   2 +
 .../CassandraVacationRepositoryTest.java        |   6 +-
 .../cassandra/CassandraMailRepositoryTest.java  |   2 +
 ...abbitMQMailQueueConfigurationChangeTest.java |   2 +
 16 files changed, 741 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/backends-common/cassandra/pom.xml
----------------------------------------------------------------------
diff --git a/backends-common/cassandra/pom.xml 
b/backends-common/cassandra/pom.xml
index 6b35ab1..bcac1fc 100644
--- a/backends-common/cassandra/pom.xml
+++ b/backends-common/cassandra/pom.xml
@@ -122,6 +122,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.junit.platform</groupId>
             <artifactId>junit-platform-launcher</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraTable.java
----------------------------------------------------------------------
diff --git 
a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraTable.java
 
b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraTable.java
index cb9100a..ed2d53b 100644
--- 
a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraTable.java
+++ 
b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraTable.java
@@ -19,9 +19,27 @@
 
 package org.apache.james.backends.cassandra.components;
 
+import java.util.Objects;
+
+import com.datastax.driver.core.KeyspaceMetadata;
+import com.datastax.driver.core.Session;
 import com.datastax.driver.core.Statement;
+import com.google.common.base.MoreObjects;
 
 public class CassandraTable {
+    public enum InitializationStatus {
+        ALREADY_DONE,
+        PARTIAL,
+        FULL;
+
+        public InitializationStatus reduce(InitializationStatus other) {
+            if (this == other) {
+                return this;
+            }
+
+            return PARTIAL;
+        }
+    }
 
     private final Statement createStatement;
     private final String name;
@@ -31,11 +49,40 @@ public class CassandraTable {
         this.name = name;
     }
 
-    public Statement getCreateStatement() {
-        return createStatement;
-    }
-
     public String getName() {
         return name;
     }
+
+    public InitializationStatus initialize(KeyspaceMetadata keyspaceMetadata, 
Session session) {
+        if (keyspaceMetadata.getTable(name) != null) {
+            return InitializationStatus.ALREADY_DONE;
+        }
+
+        session.execute(createStatement);
+        return InitializationStatus.FULL;
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof CassandraTable) {
+            CassandraTable that = (CassandraTable) o;
+
+            return Objects.equals(this.name, that.name)
+                    && Objects.equals(this.createStatement, 
that.createStatement);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(name, createStatement);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("name", name)
+                .add("createStatement", createStatement)
+                .toString();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraType.java
----------------------------------------------------------------------
diff --git 
a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraType.java
 
b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraType.java
index 2b41d72..082eff2 100644
--- 
a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraType.java
+++ 
b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraType.java
@@ -19,9 +19,27 @@
 
 package org.apache.james.backends.cassandra.components;
 
+import java.util.Objects;
+
+import com.datastax.driver.core.KeyspaceMetadata;
+import com.datastax.driver.core.Session;
 import com.datastax.driver.core.schemabuilder.CreateType;
+import com.google.common.base.MoreObjects;
 
 public class CassandraType {
+    public enum InitializationStatus {
+        ALREADY_DONE,
+        PARTIAL,
+        FULL;
+
+         public InitializationStatus reduce(InitializationStatus other) {
+             if (this == other) {
+                 return this;
+             }
+
+             return PARTIAL;
+        }
+    }
 
     private final String name;
     private final CreateType createStatement;
@@ -35,8 +53,36 @@ public class CassandraType {
         return name;
     }
 
-    public CreateType getCreateStatement() {
-        return createStatement;
+    public InitializationStatus initialize(KeyspaceMetadata keyspaceMetadata, 
Session session) {
+        if (keyspaceMetadata.getUserType(name) != null) {
+            return InitializationStatus.ALREADY_DONE;
+        }
+
+        session.execute(createStatement);
+        return InitializationStatus.FULL;
     }
 
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof CassandraType) {
+            CassandraType that = (CassandraType) o;
+
+            return Objects.equals(this.name, that.name)
+                    && Objects.equals(this.createStatement, 
that.createStatement);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(name, createStatement);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("name", name)
+                .add("createStatement", createStatement)
+                .toString();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTableManager.java
----------------------------------------------------------------------
diff --git 
a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTableManager.java
 
b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTableManager.java
index f406b5c..3317138 100644
--- 
a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTableManager.java
+++ 
b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTableManager.java
@@ -23,6 +23,7 @@ import javax.inject.Inject;
 
 import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.backends.cassandra.components.CassandraTable;
+import 
org.apache.james.backends.cassandra.components.CassandraTable.InitializationStatus;
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 
 import com.datastax.driver.core.KeyspaceMetadata;
@@ -43,17 +44,16 @@ public class CassandraTableManager {
         this.module = module;
     }
 
-    public CassandraTableManager ensureAllTables() {
+    public InitializationStatus initializeTables() {
         KeyspaceMetadata keyspaceMetadata = session.getCluster()
             .getMetadata()
             .getKeyspace(session.getLoggedKeyspace());
 
-        module.moduleTables()
-            .stream()
-            .filter(table -> keyspaceMetadata.getTable(table.getName()) == 
null)
-            .forEach(table -> session.execute(table.getCreateStatement()));
-
-        return this;
+        return module.moduleTables()
+                .stream()
+                .map(table -> table.initialize(keyspaceMetadata, session))
+                .reduce((left, right) -> left.reduce(right))
+                .orElse(InitializationStatus.ALREADY_DONE);
     }
 
     public void clearAllTables() {
@@ -75,5 +75,4 @@ public class CassandraTableManager {
                 .filter(resultSet -> !resultSet.isExhausted())
                 .flatMap(ignored -> 
Mono.fromFuture(executor.execute(QueryBuilder.truncate(name))));
     }
-
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesCreator.java
----------------------------------------------------------------------
diff --git 
a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesCreator.java
 
b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesCreator.java
index 27179bc..8c9a0aa 100644
--- 
a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesCreator.java
+++ 
b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesCreator.java
@@ -21,7 +21,9 @@ package org.apache.james.backends.cassandra.init;
 
 import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.backends.cassandra.components.CassandraType;
+import 
org.apache.james.backends.cassandra.components.CassandraType.InitializationStatus;
 
+import com.datastax.driver.core.KeyspaceMetadata;
 import com.datastax.driver.core.Session;
 import com.google.common.collect.ImmutableList;
 
@@ -34,8 +36,14 @@ public class CassandraTypesCreator {
         this.session = session;
     }
 
-    public void initializeTypes() {
-        types.forEach((type) -> session.execute(type.getCreateStatement()));
-    }
+    public InitializationStatus initializeTypes() {
+        KeyspaceMetadata keyspaceMetadata = session.getCluster()
+                .getMetadata()
+                .getKeyspace(session.getLoggedKeyspace());
 
+        return types.stream()
+                .map(type -> type.initialize(keyspaceMetadata, session))
+                .reduce((left, right) -> left.reduce(right))
+                .orElse(InitializationStatus.ALREADY_DONE);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactory.java
----------------------------------------------------------------------
diff --git 
a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactory.java
 
b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactory.java
index d87b41b..b5213d7 100644
--- 
a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactory.java
+++ 
b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactory.java
@@ -19,13 +19,19 @@
 
 package org.apache.james.backends.cassandra.init;
 
+import java.util.stream.Stream;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 import javax.inject.Provider;
 import javax.inject.Singleton;
 
 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.configuration.ClusterConfiguration;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionDAO;
+import 
org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager;
 
 import com.datastax.driver.core.Cluster;
 import com.datastax.driver.core.Session;
@@ -44,10 +50,10 @@ public class SessionWithInitializedTablesFactory implements 
Provider<Session> {
     private Session createSession(Cluster cluster, String keyspace) {
         Session session = cluster.connect(keyspace);
         try {
-            new CassandraTypesCreator(module, session)
-                .initializeTypes();
-            new CassandraTableManager(module, session)
-                .ensureAllTables();
+            if (allOperationsAreFullyPerformed(session)) {
+                new CassandraSchemaVersionDAO(session, 
CassandraUtils.WITH_DEFAULT_CONFIGURATION)
+                        
.updateVersion(CassandraSchemaVersionManager.MAX_VERSION);
+            }
             return session;
         } catch (Exception e) {
             session.close();
@@ -55,6 +61,21 @@ public class SessionWithInitializedTablesFactory implements 
Provider<Session> {
         }
     }
 
+    private boolean allOperationsAreFullyPerformed(Session session) {
+        Stream<Boolean> operations = Stream.of(createTypes(session), 
createTables(session));
+        return operations.allMatch(updated -> updated);
+    }
+
+    private boolean createTypes(Session session) {
+        return new CassandraTypesCreator(module, session)
+                .initializeTypes() == CassandraType.InitializationStatus.FULL;
+    }
+
+    private boolean createTables(Session session) {
+        return new CassandraTableManager(module, session)
+            .initializeTables() == CassandraTable.InitializationStatus.FULL;
+    }
+
     @Override
     public Session get() {
         return session;

http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/components/CassandraTableTest.java
----------------------------------------------------------------------
diff --git 
a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/components/CassandraTableTest.java
 
b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/components/CassandraTableTest.java
new file mode 100644
index 0000000..a0d264f
--- /dev/null
+++ 
b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/components/CassandraTableTest.java
@@ -0,0 +1,103 @@
+/****************************************************************
+ * 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 static 
org.apache.james.backends.cassandra.components.CassandraTable.InitializationStatus.ALREADY_DONE;
+import static 
org.apache.james.backends.cassandra.components.CassandraTable.InitializationStatus.FULL;
+import static 
org.apache.james.backends.cassandra.components.CassandraTable.InitializationStatus.PARTIAL;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.stream.Stream;
+
+import 
org.apache.james.backends.cassandra.components.CassandraTable.InitializationStatus;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import com.datastax.driver.core.KeyspaceMetadata;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.Statement;
+import com.datastax.driver.core.TableMetadata;
+import com.datastax.driver.core.schemabuilder.SchemaBuilder;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+class CassandraTableTest {
+    private static final String NAME = "tableName";
+    private static final Statement STATEMENT = SchemaBuilder.createTable(NAME);
+    private static final CassandraTable TABLE = new CassandraTable(NAME, 
STATEMENT);
+
+    @Test
+    void shouldRespectBeanContract() {
+        EqualsVerifier.forClass(CassandraTable.class)
+                .verify();
+    }
+
+    @Test
+    void 
initializeShouldExecuteCreateStatementAndReturnFullWhenTableDoesNotExist() {
+        KeyspaceMetadata keyspace = mock(KeyspaceMetadata.class);
+        when(keyspace.getTable(NAME)).thenReturn(null);
+        Session session = mock(Session.class);
+
+        assertThat(TABLE.initialize(keyspace, session))
+                .isEqualByComparingTo(FULL);
+
+        verify(keyspace).getTable(NAME);
+        verify(session).execute(STATEMENT);
+    }
+
+    @Test
+    void initializeShouldExecuteReturnAlreadyDoneWhenTableExists() {
+        KeyspaceMetadata keyspace = mock(KeyspaceMetadata.class);
+        when(keyspace.getTable(NAME)).thenReturn(mock(TableMetadata.class));
+        Session session = mock(Session.class);
+
+        assertThat(TABLE.initialize(keyspace, session))
+                .isEqualByComparingTo(ALREADY_DONE);
+
+        verify(keyspace).getTable(NAME);
+        verify(session, never()).execute(STATEMENT);
+    }
+
+    @ParameterizedTest
+    @MethodSource
+    void 
initializationStatusReduceShouldFallIntoTheRightState(InitializationStatus 
left, InitializationStatus right, InitializationStatus expectedResult) {
+        assertThat(left.reduce(right)).isEqualByComparingTo(expectedResult);
+    }
+
+    private static Stream<Arguments> 
initializationStatusReduceShouldFallIntoTheRightState() {
+        return Stream.of(
+                Arguments.of(ALREADY_DONE, ALREADY_DONE, ALREADY_DONE),
+                Arguments.of(ALREADY_DONE, PARTIAL, PARTIAL),
+                Arguments.of(ALREADY_DONE, FULL, PARTIAL),
+                Arguments.of(PARTIAL, PARTIAL, PARTIAL),
+                Arguments.of(PARTIAL, PARTIAL, PARTIAL),
+                Arguments.of(PARTIAL, FULL, PARTIAL),
+                Arguments.of(FULL, ALREADY_DONE, PARTIAL),
+                Arguments.of(FULL, PARTIAL, PARTIAL),
+                Arguments.of(FULL, FULL, FULL)
+        );
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/components/CassandraTypeTest.java
----------------------------------------------------------------------
diff --git 
a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/components/CassandraTypeTest.java
 
b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/components/CassandraTypeTest.java
new file mode 100644
index 0000000..7973c83
--- /dev/null
+++ 
b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/components/CassandraTypeTest.java
@@ -0,0 +1,104 @@
+/****************************************************************
+ * 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 static 
org.apache.james.backends.cassandra.components.CassandraType.InitializationStatus.ALREADY_DONE;
+import static 
org.apache.james.backends.cassandra.components.CassandraType.InitializationStatus.FULL;
+import static 
org.apache.james.backends.cassandra.components.CassandraType.InitializationStatus.PARTIAL;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.stream.Stream;
+
+import 
org.apache.james.backends.cassandra.components.CassandraType.InitializationStatus;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import com.datastax.driver.core.KeyspaceMetadata;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.UserType;
+import com.datastax.driver.core.schemabuilder.CreateType;
+import com.datastax.driver.core.schemabuilder.SchemaBuilder;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+class CassandraTypeTest {
+    private static final String NAME = "typeName";
+    private static final CreateType STATEMENT = SchemaBuilder.createType(NAME);
+    private static final CassandraType TYPE = new CassandraType(NAME, 
STATEMENT);
+
+    @Test
+    void shouldRespectBeanContract() {
+        EqualsVerifier.forClass(CassandraType.class)
+                .withPrefabValues(CreateType.class, 
SchemaBuilder.createType("name1"), SchemaBuilder.createType("name2"))
+                .verify();
+    }
+
+    @Test
+    void 
initializeShouldExecuteCreateStatementAndReturnFullWhenTypeDoesNotExist() {
+        KeyspaceMetadata keyspace = mock(KeyspaceMetadata.class);
+        when(keyspace.getUserType(NAME)).thenReturn(null);
+        Session session = mock(Session.class);
+
+        assertThat(TYPE.initialize(keyspace, session))
+                .isEqualByComparingTo(FULL);
+
+        verify(keyspace).getUserType(NAME);
+        verify(session).execute(STATEMENT);
+    }
+
+    @Test
+    void initializeShouldReturnAlreadyDoneWhenTypeExists() {
+        KeyspaceMetadata keyspace = mock(KeyspaceMetadata.class);
+        when(keyspace.getUserType(NAME)).thenReturn(mock(UserType.class));
+        Session session = mock(Session.class);
+
+        assertThat(TYPE.initialize(keyspace, session))
+                .isEqualByComparingTo(ALREADY_DONE);
+
+        verify(keyspace).getUserType(NAME);
+        verify(session, never()).execute(STATEMENT);
+    }
+
+    @ParameterizedTest
+    @MethodSource
+    void 
initializationStatusReduceShouldFallIntoTheRightState(InitializationStatus 
left, InitializationStatus right, InitializationStatus expectedResult) {
+        assertThat(left.reduce(right)).isEqualByComparingTo(expectedResult);
+    }
+
+    static Stream<Arguments> 
initializationStatusReduceShouldFallIntoTheRightState() {
+        return Stream.of(
+                Arguments.of(ALREADY_DONE, ALREADY_DONE, ALREADY_DONE),
+                Arguments.of(ALREADY_DONE, PARTIAL, PARTIAL),
+                Arguments.of(ALREADY_DONE, FULL, PARTIAL),
+                Arguments.of(PARTIAL, PARTIAL, PARTIAL),
+                Arguments.of(PARTIAL, PARTIAL, PARTIAL),
+                Arguments.of(PARTIAL, FULL, PARTIAL),
+                Arguments.of(FULL, ALREADY_DONE, PARTIAL),
+                Arguments.of(FULL, PARTIAL, PARTIAL),
+                Arguments.of(FULL, FULL, FULL)
+        );
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTableManagerTest.java
----------------------------------------------------------------------
diff --git 
a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTableManagerTest.java
 
b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTableManagerTest.java
new file mode 100644
index 0000000..2b5206b
--- /dev/null
+++ 
b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTableManagerTest.java
@@ -0,0 +1,104 @@
+/****************************************************************
+ * 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 static org.assertj.core.api.Assertions.assertThatCode;
+
+import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.backends.cassandra.components.CassandraTable;
+import 
org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule;
+import 
org.apache.james.backends.cassandra.versions.table.CassandraSchemaVersionTable;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.querybuilder.QueryBuilder;
+import com.datastax.driver.core.schemabuilder.SchemaBuilder;
+
+class CassandraTableManagerTest {
+    private static final String TABLE_NAME = "tablename";
+
+    public static final CassandraModule MODULE = 
CassandraModule.aggregateModules(
+            CassandraSchemaVersionModule.MODULE,
+            CassandraModule.table(TABLE_NAME)
+                .comment("Testing table")
+                .statement(statement -> statement
+                        .addPartitionKey("id", DataType.timeuuid())
+                        .addClusteringColumn("clustering", DataType.bigint()))
+                .build());
+
+    @RegisterExtension
+    static CassandraClusterExtension cassandraCluster = new 
CassandraClusterExtension(MODULE);
+
+    private CassandraCluster cassandra;
+
+    @BeforeEach
+    void setUp(CassandraCluster cassandra) {
+        this.cassandra = cassandra;
+    }
+
+    @Test
+    void describeShouldNotReturnNullNorFailWhenTableIsDefined() {
+        ensureTableExistence(TABLE_NAME);
+    }
+
+    @Test
+    void initializeTableShouldCreateAllTheTables() {
+        cassandra.getConf().execute(SchemaBuilder.dropTable(TABLE_NAME));
+        
cassandra.getConf().execute(SchemaBuilder.dropTable(CassandraSchemaVersionTable.TABLE_NAME));
+
+        assertThat(new CassandraTableManager(MODULE, 
cassandra.getConf()).initializeTables())
+                
.isEqualByComparingTo(CassandraTable.InitializationStatus.FULL);
+
+        ensureTableExistence(TABLE_NAME);
+    }
+
+    @Test
+    void initializeTableShouldCreateAllTheMissingTable() {
+        cassandra.getConf().execute(SchemaBuilder.dropTable(TABLE_NAME));
+
+        assertThat(new CassandraTableManager(MODULE, 
cassandra.getConf()).initializeTables())
+                
.isEqualByComparingTo(CassandraTable.InitializationStatus.PARTIAL);
+
+        ensureTableExistence(TABLE_NAME);
+    }
+
+    @Test
+    void initializeTableShouldNotPerformIfCalledASecondTime() {
+        assertThat(new CassandraTableManager(MODULE, 
cassandra.getConf()).initializeTables())
+                
.isEqualByComparingTo(CassandraTable.InitializationStatus.ALREADY_DONE);
+    }
+
+    @Test
+    void initializeTableShouldNotFailIfCalledASecondTime() {
+        new CassandraTableManager(MODULE, 
cassandra.getConf()).initializeTables();
+
+        ensureTableExistence(TABLE_NAME);
+    }
+
+    private void ensureTableExistence(String tableName) {
+        assertThatCode(() -> 
cassandra.getConf().execute(QueryBuilder.select().from(tableName).limit(1)))
+            .doesNotThrowAnyException();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTypeProviderTest.java
----------------------------------------------------------------------
diff --git 
a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTypeProviderTest.java
 
b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTypeProviderTest.java
index 1bf149c..e2e6f21 100644
--- 
a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTypeProviderTest.java
+++ 
b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTypeProviderTest.java
@@ -25,6 +25,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.backends.cassandra.components.CassandraType;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
@@ -59,7 +60,9 @@ class CassandraTypeProviderTest {
     void initializeTypesShouldCreateTheTypes() {
         cassandra.getConf().execute(SchemaBuilder.dropType(TYPE_NAME));
 
-        new CassandraTypesCreator(MODULE, 
cassandra.getConf()).initializeTypes();
+        assertThat(new CassandraTypesCreator(MODULE, 
cassandra.getConf()).initializeTypes())
+            .isEqualByComparingTo(CassandraType.InitializationStatus.FULL);
+
         CassandraTypesProvider cassandraTypesProviderTest = new 
CassandraTypesProvider(MODULE, cassandra.getConf());
         assertThat(cassandraTypesProviderTest.getDefinedUserType(TYPE_NAME))
             .isNotNull();

http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTypesCreatorTest.java
----------------------------------------------------------------------
diff --git 
a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTypesCreatorTest.java
 
b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTypesCreatorTest.java
new file mode 100644
index 0000000..9db2f8c
--- /dev/null
+++ 
b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraTypesCreatorTest.java
@@ -0,0 +1,112 @@
+/****************************************************************
+ * 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 com.datastax.driver.core.DataType.text;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.backends.cassandra.components.CassandraType;
+import 
org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import com.datastax.driver.core.schemabuilder.SchemaBuilder;
+
+class CassandraTypesCreatorTest {
+    private static final String TYPE_NAME_1 = "typename1";
+    private static final String PROPERTY_1 = "property1";
+    private static final String TYPE_NAME_2 = "typename2";
+    private static final String PROPERTY_2 = "property2";
+
+    public static final CassandraModule MODULE = 
CassandraModule.aggregateModules(
+            CassandraSchemaVersionModule.MODULE,
+            CassandraModule.type(TYPE_NAME_1)
+                .statement(statement -> statement.addColumn(PROPERTY_1, 
text()))
+                .build(),
+            CassandraModule.type(TYPE_NAME_2)
+                .statement(statement -> statement.addColumn(PROPERTY_2, 
text()))
+                .build());
+
+    @RegisterExtension
+    static CassandraClusterExtension cassandraCluster = new 
CassandraClusterExtension(MODULE);
+
+    private CassandraCluster cassandra;
+
+    @BeforeEach
+    void setUp(CassandraCluster cassandra) {
+        this.cassandra = cassandra;
+        cassandra.getTypesProvider();
+    }
+
+    @Test
+    void getDefinedUserTypeShouldNotReturnNullNorFailWhenTypeIsDefined() {
+        
assertThat(cassandra.getTypesProvider().getDefinedUserType(TYPE_NAME_1))
+                .isNotNull();
+        
assertThat(cassandra.getTypesProvider().getDefinedUserType(TYPE_NAME_2))
+                .isNotNull();
+    }
+
+    @Test
+    void initializeTypesShouldCreateTheAllTypes() {
+        cassandra.getConf().execute(SchemaBuilder.dropType(TYPE_NAME_1));
+        cassandra.getConf().execute(SchemaBuilder.dropType(TYPE_NAME_2));
+
+        assertThat(new CassandraTypesCreator(MODULE, 
cassandra.getConf()).initializeTypes())
+                .isEqualByComparingTo(CassandraType.InitializationStatus.FULL);
+
+        CassandraTypesProvider cassandraTypesProviderTest = new 
CassandraTypesProvider(MODULE, cassandra.getConf());
+        assertThat(cassandraTypesProviderTest.getDefinedUserType(TYPE_NAME_1))
+                .isNotNull();
+        assertThat(cassandraTypesProviderTest.getDefinedUserType(TYPE_NAME_2))
+                .isNotNull();
+    }
+
+    @Test
+    void initializeTypesShouldCreateTheMissingType() {
+        cassandra.getConf().execute(SchemaBuilder.dropType(TYPE_NAME_1));
+
+        assertThat(new CassandraTypesCreator(MODULE, 
cassandra.getConf()).initializeTypes())
+                
.isEqualByComparingTo(CassandraType.InitializationStatus.PARTIAL);
+
+        CassandraTypesProvider cassandraTypesProviderTest = new 
CassandraTypesProvider(MODULE, cassandra.getConf());
+        assertThat(cassandraTypesProviderTest.getDefinedUserType(TYPE_NAME_1))
+                .isNotNull();
+    }
+
+    @Test
+    void initializeTypesShouldNotPerformIfCalledASecondTime() {
+        assertThat(new CassandraTypesCreator(MODULE, 
cassandra.getConf()).initializeTypes())
+                
.isEqualByComparingTo(CassandraType.InitializationStatus.ALREADY_DONE);
+    }
+
+    @Test
+    void initializeTypesShouldNotFailIfCalledASecondTime() {
+        new CassandraTypesCreator(MODULE, 
cassandra.getConf()).initializeTypes();
+
+        
assertThat(cassandra.getTypesProvider().getDefinedUserType(TYPE_NAME_1))
+                .isNotNull();
+        
assertThat(cassandra.getTypesProvider().getDefinedUserType(TYPE_NAME_2))
+                .isNotNull();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactoryTest.java
----------------------------------------------------------------------
diff --git 
a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactoryTest.java
 
b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactoryTest.java
new file mode 100644
index 0000000..631a027
--- /dev/null
+++ 
b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactoryTest.java
@@ -0,0 +1,156 @@
+/****************************************************************
+ * 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 com.datastax.driver.core.DataType.text;
+import static org.apache.james.backends.cassandra.CassandraCluster.KEYSPACE;
+import static 
org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager.MAX_VERSION;
+import static 
org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager.MIN_VERSION;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.function.Supplier;
+
+import org.apache.james.backends.cassandra.DockerCassandraExtension;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import 
org.apache.james.backends.cassandra.init.configuration.ClusterConfiguration;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionDAO;
+import 
org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager;
+import 
org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule;
+import org.apache.james.util.Host;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.schemabuilder.SchemaBuilder;
+
+@ExtendWith(DockerCassandraExtension.class)
+class SessionWithInitializedTablesFactoryTest {
+    private static final String TABLE_NAME = "tablename";
+    private static final String TYPE_NAME = "typename";
+    private static final String PROPERTY = "property";
+
+    public static final CassandraModule MODULE = 
CassandraModule.aggregateModules(
+            CassandraSchemaVersionModule.MODULE,
+            CassandraModule.table(TABLE_NAME)
+                    .comment("Testing table")
+                    .statement(statement -> statement
+                            .addPartitionKey("id", DataType.timeuuid())
+                            .addClusteringColumn("clustering", 
DataType.bigint()))
+                    .build(),
+            CassandraModule.type(TYPE_NAME)
+                    .statement(statement -> statement.addColumn(PROPERTY, 
text()))
+                    .build());
+
+    private Supplier<Session> testee;
+
+    @BeforeEach
+    void setUp(DockerCassandraExtension.DockerCassandra cassandraServer) {
+        this.testee = createSession(cassandraServer);
+    }
+
+    @AfterEach
+    void tearDown() {
+        cleanCassandra(testee.get());
+    }
+
+    @BeforeAll
+    @AfterAll
+    static void stabilizeCassandra(DockerCassandraExtension.DockerCassandra 
cassandraServer) {
+        cleanCassandra(createSession(cassandraServer).get());
+    }
+
+    @Test
+    void 
createSessionShouldSetTheLatestSchemaVersionWhenCreatingTypesAndTables() {
+        assertThat(versionManager(testee.get()).computeVersion())
+                .isEqualTo(MAX_VERSION);
+    }
+
+    @Test
+    void 
createSessionShouldKeepTheSetSchemaVersionWhenTypesAndTablesHaveNotChanged() {
+        Session session = testee.get();
+        assertThat(versionManager(session).computeVersion())
+                .isEqualTo(MAX_VERSION);
+
+        new CassandraTableManager(MODULE, session).clearAllTables();
+        versionManagerDAO(session).updateVersion(MIN_VERSION);
+        assertThat(versionManager(session).computeVersion())
+                .isEqualTo(MIN_VERSION);
+
+        assertThat(versionManager(testee.get()).computeVersion())
+                .isEqualTo(MIN_VERSION);
+    }
+
+    @Test
+    void 
createSessionShouldKeepTheSetSchemaVersionWhenTypesAndTablesHavePartiallyChanged()
 {
+        Session session = testee.get();
+        assertThat(versionManager(session).computeVersion())
+                .isEqualTo(MAX_VERSION);
+
+        new CassandraTableManager(MODULE, session).clearAllTables();
+        versionManagerDAO(session).updateVersion(MIN_VERSION);
+        assertThat(versionManager(session).computeVersion())
+                .isEqualTo(MIN_VERSION);
+        session.execute(SchemaBuilder.dropTable(TABLE_NAME));
+        session.execute(SchemaBuilder.dropType(TYPE_NAME));
+
+        assertThat(versionManager(testee.get()).computeVersion())
+                .isEqualTo(MIN_VERSION);
+    }
+
+    private static Supplier<Session> 
createSession(DockerCassandraExtension.DockerCassandra cassandraServer) {
+        Host host = cassandraServer.getHost();
+        Cluster cluster = ClusterBuilder.builder()
+                .host(host.getHostName())
+                .port(host.getPort())
+                .build();
+        return () -> new SessionWithInitializedTablesFactory(
+                ClusterConfiguration.builder()
+                        .host(host)
+                        .keyspace(KEYSPACE)
+                        .replicationFactor(1)
+                        .build(),
+                ClusterWithKeyspaceCreatedFactory
+                        .config(cluster, KEYSPACE)
+                        .replicationFactor(1)
+                        .disableDurableWrites()
+                        .clusterWithInitializedKeyspace(),
+                MODULE).get();
+    }
+
+    private static void cleanCassandra(Session session) {
+        MODULE.moduleTables().forEach(table -> 
session.execute(SchemaBuilder.dropTable(table.getName())));
+        MODULE.moduleTypes().forEach(type -> 
session.execute(SchemaBuilder.dropType(type.getName())));
+    }
+
+    private CassandraSchemaVersionManager versionManager(Session session) {
+        return new CassandraSchemaVersionManager(versionManagerDAO(session));
+    }
+
+    private CassandraSchemaVersionDAO versionManagerDAO(Session session) {
+        return new CassandraSchemaVersionDAO(session, 
CassandraUtils.WITH_DEFAULT_CONFIGURATION);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/MailboxAggregateModule.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/MailboxAggregateModule.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/MailboxAggregateModule.java
index 841a785..dd1fd57 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/MailboxAggregateModule.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/MailboxAggregateModule.java
@@ -20,6 +20,7 @@
 package org.apache.james.mailbox.cassandra.mail;
 
 import org.apache.james.backends.cassandra.components.CassandraModule;
+import 
org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule;
 import org.apache.james.blob.cassandra.CassandraBlobModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraAnnotationModule;
@@ -38,6 +39,7 @@ import 
org.apache.james.mailbox.cassandra.modules.CassandraUidModule;
 
 public interface MailboxAggregateModule {
     CassandraModule MODULE = CassandraModule.aggregateModules(
+            CassandraSchemaVersionModule.MODULE,
             CassandraAclModule.MODULE,
             CassandraMailboxModule.MODULE,
             CassandraMessageModule.MODULE,

http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationRepositoryTest.java
----------------------------------------------------------------------
diff --git 
a/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationRepositoryTest.java
 
b/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationRepositoryTest.java
index 7db419b..caf644e 100644
--- 
a/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationRepositoryTest.java
+++ 
b/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationRepositoryTest.java
@@ -23,6 +23,7 @@ import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
 import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.backends.cassandra.init.CassandraZonedDateTimeModule;
+import 
org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule;
 import org.apache.james.jmap.api.vacation.AbstractVacationRepositoryTest;
 import org.apache.james.jmap.api.vacation.VacationRepository;
 import org.junit.After;
@@ -39,7 +40,10 @@ public class CassandraVacationRepositoryTest extends 
AbstractVacationRepositoryT
 
     @BeforeClass
     public static void setUpClass() {
-        CassandraModule module = 
CassandraModule.aggregateModules(CassandraVacationModule.MODULE, 
CassandraZonedDateTimeModule.MODULE);
+        CassandraModule module = CassandraModule.aggregateModules(
+                CassandraSchemaVersionModule.MODULE,
+                CassandraVacationModule.MODULE,
+                CassandraZonedDateTimeModule.MODULE);
         cassandra = CassandraCluster.create(module, cassandraServer.getHost());
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/server/mailrepository/mailrepository-cassandra/src/test/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryTest.java
----------------------------------------------------------------------
diff --git 
a/server/mailrepository/mailrepository-cassandra/src/test/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryTest.java
 
b/server/mailrepository/mailrepository-cassandra/src/test/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryTest.java
index d83677e..b0c059e 100644
--- 
a/server/mailrepository/mailrepository-cassandra/src/test/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryTest.java
+++ 
b/server/mailrepository/mailrepository-cassandra/src/test/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryTest.java
@@ -23,6 +23,7 @@ import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import 
org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule;
 import org.apache.james.blob.api.HashBlobId;
 import org.apache.james.blob.cassandra.CassandraBlobModule;
 import org.apache.james.blob.cassandra.CassandraBlobsDAO;
@@ -42,6 +43,7 @@ class CassandraMailRepositoryTest implements 
MailRepositoryContract {
     @RegisterExtension
     static CassandraClusterExtension cassandraCluster = new 
CassandraClusterExtension(
         CassandraModule.aggregateModules(
+            CassandraSchemaVersionModule.MODULE,
             CassandraMailRepositoryModule.MODULE,
             CassandraBlobModule.MODULE));
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/d796a1d3/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueueConfigurationChangeTest.java
----------------------------------------------------------------------
diff --git 
a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueueConfigurationChangeTest.java
 
b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueueConfigurationChangeTest.java
index d0acd5d..4ae8328 100644
--- 
a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueueConfigurationChangeTest.java
+++ 
b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueueConfigurationChangeTest.java
@@ -39,6 +39,7 @@ import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.backends.cassandra.components.CassandraModule;
 import 
org.apache.james.backends.cassandra.init.configuration.CassandraConfiguration;
+import 
org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule;
 import org.apache.james.blob.api.HashBlobId;
 import org.apache.james.blob.cassandra.CassandraBlobModule;
 import org.apache.james.blob.cassandra.CassandraBlobsDAO;
@@ -79,6 +80,7 @@ class RabbitMQMailQueueConfigurationChangeTest {
 
     @RegisterExtension
     static CassandraClusterExtension cassandraCluster = new 
CassandraClusterExtension(CassandraModule.aggregateModules(
+        CassandraSchemaVersionModule.MODULE,
         CassandraBlobModule.MODULE,
         CassandraMailQueueViewModule.MODULE,
         CassandraEventStoreModule.MODULE));


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

Reply via email to