JAMES-2083 Plug CassandraSchemaVersionManager into guice A integration test has also been added.
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/5981b46e Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/5981b46e Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/5981b46e Branch: refs/heads/master Commit: 5981b46ebf78f6fe28dea353fc04180c86f0a252 Parents: 0672d3b Author: Luc DUZAN <ldu...@linagora.com> Authored: Tue Jul 4 11:28:31 2017 +0200 Committer: Antoine Duprat <adup...@linagora.com> Committed: Mon Jul 10 14:24:00 2017 +0200 ---------------------------------------------------------------------- .../modules/mailbox/CassandraSessionModule.java | 32 ++++ .../james/CassandraVersionCheckingTest.java | 161 +++++++++++++++++++ 2 files changed, 193 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/5981b46e/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 73be94a..8459560 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 @@ -39,8 +39,13 @@ import org.apache.james.backends.cassandra.init.ClusterWithKeyspaceCreatedFactor import org.apache.james.backends.cassandra.init.QueryLoggerConfiguration; import org.apache.james.backends.cassandra.init.SessionWithInitializedTablesFactory; 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.lifecycle.api.Configurable; import org.apache.james.mailbox.store.BatchSizes; import org.apache.james.util.Host; +import org.apache.james.utils.ConfigurationPerformer; import org.apache.james.utils.PropertiesProvider; import org.apache.james.utils.RetryExecutorUtil; import org.slf4j.Logger; @@ -55,7 +60,9 @@ import com.datastax.driver.core.Session; import com.datastax.driver.core.exceptions.NoHostAvailableException; import com.github.steveash.guavate.Guavate; import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; import com.google.inject.AbstractModule; +import com.google.inject.Inject; import com.google.inject.Provides; import com.google.inject.Scopes; import com.google.inject.Singleton; @@ -98,6 +105,12 @@ public class CassandraSessionModule extends AbstractModule { Multibinder<CassandraModule> cassandraDataDefinitions = Multibinder.newSetBinder(binder(), CassandraModule.class); cassandraDataDefinitions.addBinding().to(CassandraZonedDateTimeModule.class); + cassandraDataDefinitions.addBinding().to(CassandraSchemaVersionModule.class); + + bind(CassandraSchemaVersionManager.class).in(Scopes.SINGLETON); + bind(CassandraSchemaVersionDAO.class).in(Scopes.SINGLETON); + + Multibinder.newSetBinder(binder(), ConfigurationPerformer.class).addBinding().to(CassandraSchemaChecker.class); } @Provides @@ -302,4 +315,23 @@ public class CassandraSessionModule extends AbstractModule { return propertiesConfiguration; } } + + public static class CassandraSchemaChecker implements ConfigurationPerformer { + private final CassandraSchemaVersionManager versionManager; + + @Inject + public CassandraSchemaChecker(CassandraSchemaVersionManager versionManager) { + this.versionManager = versionManager; + } + + @Override + public void initModule() { + versionManager.ensureSchemaIsSupported(); + } + + @Override + public List<Class<? extends Configurable>> forClasses() { + return ImmutableList.of(); + } + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/5981b46e/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraVersionCheckingTest.java ---------------------------------------------------------------------- diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraVersionCheckingTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraVersionCheckingTest.java new file mode 100644 index 0000000..f66c7bb --- /dev/null +++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraVersionCheckingTest.java @@ -0,0 +1,161 @@ +/**************************************************************** + * 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 static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; +import java.nio.charset.Charset; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; + +import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionDAO; +import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class CassandraVersionCheckingTest { + + private static final String LOCAL_HOST = "127.0.0.1"; + private static final int IMAP_PORT = 1143; + private static final int MIN_VERSION = 2; + private static final int MAX_VERSION = 4; + + @Rule + public CassandraJmapTestRule cassandraJmapTestRule = CassandraJmapTestRule.defaultTestRule(); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private GuiceJamesServer jamesServer; + private SocketChannel socketChannel; + private CassandraSchemaVersionDAO versionDAO; + + @Before + public void setUp() throws IOException { + socketChannel = SocketChannel.open(); + versionDAO = mock(CassandraSchemaVersionDAO.class); + } + + @After + public void tearDown() throws IOException { + socketChannel.close(); + if (jamesServer != null) { + jamesServer.stop(); + } + } + + @Test + public void serverShouldStartSuccessfullyWhenMaxVersion() throws Exception { + when(versionDAO.getCurrentSchemaVersion()) + .thenReturn(CompletableFuture.completedFuture(Optional.of(MAX_VERSION))); + + jamesServer = cassandraJmapTestRule.jmapServer( + binder -> binder.bind(CassandraSchemaVersionDAO.class) + .toInstance(versionDAO), + binder -> binder.bind(CassandraSchemaVersionManager.class) + .toInstance(new CassandraSchemaVersionManager(versionDAO, MIN_VERSION, MAX_VERSION))); + + assertThatServerStartCorrectly(); + } + + @Test + public void serverShouldStartSuccessfullyWhenBetweenMinAndMaxVersion() throws Exception { + when(versionDAO.getCurrentSchemaVersion()) + .thenReturn(CompletableFuture.completedFuture(Optional.of(MIN_VERSION + 1))); + + jamesServer = cassandraJmapTestRule.jmapServer( + binder -> binder.bind(CassandraSchemaVersionDAO.class) + .toInstance(versionDAO), + binder -> binder.bind(CassandraSchemaVersionManager.class) + .toInstance(new CassandraSchemaVersionManager(versionDAO, MIN_VERSION, MAX_VERSION))); + + assertThatServerStartCorrectly(); + } + + @Test + public void serverShouldStartSuccessfullyWhenMinVersion() throws Exception { + when(versionDAO.getCurrentSchemaVersion()) + .thenReturn(CompletableFuture.completedFuture(Optional.of(MIN_VERSION))); + + jamesServer = cassandraJmapTestRule.jmapServer( + binder -> binder.bind(CassandraSchemaVersionDAO.class) + .toInstance(versionDAO), + binder -> binder.bind(CassandraSchemaVersionManager.class) + .toInstance(new CassandraSchemaVersionManager(versionDAO, MIN_VERSION, MAX_VERSION))); + + assertThatServerStartCorrectly(); + } + + @Test + public void serverShouldNotStartWhenUnderMinVersion() throws Exception { + when(versionDAO.getCurrentSchemaVersion()) + .thenReturn(CompletableFuture.completedFuture(Optional.of(MIN_VERSION - 1))); + + jamesServer = cassandraJmapTestRule.jmapServer( + binder -> binder.bind(CassandraSchemaVersionDAO.class) + .toInstance(versionDAO), + binder -> binder.bind(CassandraSchemaVersionManager.class) + .toInstance(new CassandraSchemaVersionManager(versionDAO, MIN_VERSION, MAX_VERSION))); + + expectedException.expect(IllegalStateException.class); + + jamesServer.start(); + } + + @Test + public void serverShouldNotStartWhenAboveMaxVersion() throws Exception { + when(versionDAO.getCurrentSchemaVersion()) + .thenReturn(CompletableFuture.completedFuture(Optional.of(MAX_VERSION + 1))); + + jamesServer = cassandraJmapTestRule.jmapServer( + binder -> binder.bind(CassandraSchemaVersionDAO.class) + .toInstance(versionDAO), + binder -> binder.bind(CassandraSchemaVersionManager.class) + .toInstance(new CassandraSchemaVersionManager(versionDAO, MIN_VERSION, MAX_VERSION))); + + expectedException.expect(IllegalStateException.class); + + jamesServer.start(); + } + + private void assertThatServerStartCorrectly() throws Exception { + jamesServer.start(); + socketChannel.connect(new InetSocketAddress(LOCAL_HOST, IMAP_PORT)); + assertThat(getServerConnectionResponse(socketChannel)) + .startsWith("* OK JAMES IMAP4rev1 Server"); + } + + 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")); + } + +} --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org