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 2019/05/16 08:48:37 UTC
[james-project] 22/23: JAMES-2763 CassandraSchemaVersion
StartUpCheck
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 201328786d3a5e4fcb33f18c2763010fe9ccd32e
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Wed May 15 16:56:16 2019 +0700
JAMES-2763 CassandraSchemaVersion StartUpCheck
---
.../CassandraSchemaVersionStartUpCheck.java | 116 +++++++++++++++++++++
.../modules/mailbox/CassandraSessionModule.java | 54 +---------
.../CassandraSchemaVersionStartUpCheckTest.java} | 42 +++++---
.../org/apache/james/StartUpChecksPerformer.java | 15 ++-
4 files changed, 159 insertions(+), 68 deletions(-)
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSchemaVersionStartUpCheck.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSchemaVersionStartUpCheck.java
new file mode 100644
index 0000000..0e6b24a
--- /dev/null
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSchemaVersionStartUpCheck.java
@@ -0,0 +1,116 @@
+/****************************************************************
+ * 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 org.apache.james.StartUpChecksPerformer;
+import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+
+public class CassandraSchemaVersionStartUpCheck implements StartUpChecksPerformer.StartUpCheck {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CassandraSchemaVersionStartUpCheck.class);
+ static final String CHECK_NAME = "CassandraSchemaVersionStartUpCheck";
+
+ private final CassandraSchemaVersionManager versionManager;
+
+ @Inject
+ public CassandraSchemaVersionStartUpCheck(CassandraSchemaVersionManager versionManager) {
+ this.versionManager = versionManager;
+ }
+
+ @Override
+ public CheckResult check() {
+ CassandraSchemaVersionManager.SchemaState schemaState = versionManager.computeSchemaState();
+ switch (schemaState) {
+ case TOO_OLD:
+ return checkTooOldState();
+ case TOO_RECENT:
+ return checkTooRecentState();
+ case UP_TO_DATE:
+ return checkUpToDateState();
+ case UPGRADABLE:
+ return checkUpgradeAbleState();
+ default:
+ String unknownSchemaStateMessage = "Unknown schema state " + schemaState;
+ LOGGER.error(unknownSchemaStateMessage);
+ return CheckResult.builder()
+ .checkName(CHECK_NAME)
+ .resultType(ResultType.BAD)
+ .description(unknownSchemaStateMessage)
+ .build();
+ }
+ }
+
+ private CheckResult checkUpgradeAbleState() {
+ String upgradeVersionMessage =
+ String.format("Current schema version is %d. Recommended version is %d",
+ versionManager.computeVersion().getValue(),
+ versionManager.getMaximumSupportedVersion().getValue());
+ LOGGER.warn(upgradeVersionMessage);
+ return CheckResult.builder()
+ .checkName(CHECK_NAME)
+ .resultType(ResultType.GOOD)
+ .description(upgradeVersionMessage)
+ .build();
+ }
+
+ private CheckResult checkUpToDateState() {
+ String message = "Schema version is up-to-date";
+ LOGGER.info(message);
+ return CheckResult.builder()
+ .checkName(CHECK_NAME)
+ .resultType(ResultType.GOOD)
+ .description(message)
+ .build();
+ }
+
+ private CheckResult checkTooRecentState() {
+ String versionExceedMaximumSupportedMessage =
+ String.format("Current schema version is %d whereas the maximum supported version is %d. " +
+ "Recommended version is %d.",
+ versionManager.computeVersion().getValue(),
+ versionManager.getMaximumSupportedVersion().getValue(),
+ versionManager.getMaximumSupportedVersion().getValue());
+ LOGGER.error(versionExceedMaximumSupportedMessage);
+ return CheckResult.builder()
+ .checkName(CHECK_NAME)
+ .resultType(ResultType.BAD)
+ .description(versionExceedMaximumSupportedMessage)
+ .build();
+ }
+
+ private CheckResult checkTooOldState() {
+ String versionToOldMessage =
+ String.format("Current schema version is %d whereas minimum required version is %d. " +
+ "Recommended version is %d",
+ versionManager.computeVersion().getValue(),
+ versionManager.getMinimumSupportedVersion().getValue(),
+ versionManager.getMaximumSupportedVersion().getValue());
+ LOGGER.error(versionToOldMessage);
+ return CheckResult.builder()
+ .checkName(CHECK_NAME)
+ .resultType(ResultType.BAD)
+ .description(versionToOldMessage)
+ .build();
+ }
+}
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 1613dfe..951a328 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,11 +19,11 @@
package org.apache.james.modules.mailbox;
import java.io.FileNotFoundException;
-import java.util.List;
import java.util.Set;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
+import org.apache.james.StartUpChecksPerformer;
import org.apache.james.backends.cassandra.components.CassandraModule;
import org.apache.james.backends.cassandra.init.CassandraZonedDateTimeModule;
import org.apache.james.backends.cassandra.init.SessionWithInitializedTablesFactory;
@@ -33,14 +33,11 @@ import org.apache.james.backends.cassandra.utils.CassandraHealthCheck;
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.CassandraSchemaVersionManager.SchemaState;
import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule;
import org.apache.james.core.healthcheck.HealthCheck;
-import org.apache.james.lifecycle.api.Startable;
import org.apache.james.mailbox.store.BatchSizes;
import org.apache.james.server.CassandraProbe;
import org.apache.james.util.Host;
-import org.apache.james.utils.ConfigurationPerformer;
import org.apache.james.utils.GuiceProbe;
import org.apache.james.utils.PropertiesProvider;
import org.slf4j.Logger;
@@ -49,9 +46,7 @@ import org.slf4j.LoggerFactory;
import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.Session;
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;
@@ -79,7 +74,8 @@ public class CassandraSessionModule extends AbstractModule {
bind(CassandraSchemaVersionManager.class).in(Scopes.SINGLETON);
bind(CassandraSchemaVersionDAO.class).in(Scopes.SINGLETON);
- Multibinder.newSetBinder(binder(), ConfigurationPerformer.class).addBinding().to(CassandraSchemaChecker.class);
+ Multibinder.newSetBinder(binder(), StartUpChecksPerformer.StartUpCheck.class)
+ .addBinding().to(CassandraSchemaVersionStartUpCheck.class);
Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(CassandraProbe.class);
@@ -136,48 +132,4 @@ public class CassandraSessionModule extends AbstractModule {
.build();
}
}
-
- public static class CassandraSchemaChecker implements ConfigurationPerformer {
- private final CassandraSchemaVersionManager versionManager;
-
- @Inject
- public CassandraSchemaChecker(CassandraSchemaVersionManager versionManager) {
- this.versionManager = versionManager;
- }
-
- @Override
- public void initModule() {
- SchemaState schemaState = versionManager.computeSchemaState();
- switch (schemaState) {
- case TOO_OLD:
- throw new IllegalStateException(
- String.format("Current schema version is %d whereas minimum required version is %d. " +
- "Recommended version is %d",
- versionManager.computeVersion().getValue(),
- versionManager.getMinimumSupportedVersion().getValue(),
- versionManager.getMaximumSupportedVersion().getValue()));
- case TOO_RECENT:
- throw new IllegalStateException(
- String.format("Current schema version is %d whereas the minimum supported version is %d. " +
- "Recommended version is %d.",
- versionManager.computeVersion().getValue(),
- versionManager.getMinimumSupportedVersion().getValue(),
- versionManager.getMaximumSupportedVersion().getValue()));
- case UP_TO_DATE:
- LOGGER.info("Schema version is up-to-date");
- return;
- case UPGRADABLE:
- LOGGER.warn("Current schema version is {}. Recommended version is {}", versionManager.computeVersion(),
- versionManager.getMaximumSupportedVersion());
- return;
- default:
- throw new IllegalStateException("Unknown schema state " + schemaState);
- }
- }
-
- @Override
- public List<Class<? extends Startable>> forClasses() {
- return ImmutableList.of();
- }
- }
}
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/modules/mailbox/CassandraSchemaVersionStartUpCheckTest.java
similarity index 77%
rename from server/container/guice/cassandra-guice/src/test/java/org/apache/james/CassandraVersionCheckingTest.java
rename to server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/mailbox/CassandraSchemaVersionStartUpCheckTest.java
index d7cb7d1..a653310 100644
--- 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/modules/mailbox/CassandraSchemaVersionStartUpCheckTest.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
-package org.apache.james;
+package org.apache.james.modules.mailbox;
import static org.apache.james.CassandraJamesServerMain.ALL_BUT_JMX_CASSANDRA_MODULE;
import static org.assertj.core.api.Assertions.assertThat;
@@ -31,6 +31,12 @@ import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Optional;
+import org.apache.james.CassandraExtension;
+import org.apache.james.DockerElasticSearchExtension;
+import org.apache.james.GuiceJamesServer;
+import org.apache.james.JamesServerBuilder;
+import org.apache.james.JamesServerExtension;
+import org.apache.james.StartUpChecksPerformer.StartUpChecksException;
import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionDAO;
import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionManager;
import org.apache.james.backends.cassandra.versions.SchemaVersion;
@@ -45,9 +51,10 @@ import org.junit.jupiter.api.extension.RegisterExtension;
import reactor.core.publisher.Mono;
-class CassandraVersionCheckingTest {
+class CassandraSchemaVersionStartUpCheckTest {
private static final int LIMIT_TO_10_MESSAGES = 10;
private static final String LOCAL_HOST = "127.0.0.1";
+ private static final String EXPECTED_SERVER_CONNECTED_MESSAGE = "* OK JAMES IMAP4rev1 Server";
private static final SchemaVersion MIN_VERSION = new SchemaVersion(2);
private static final SchemaVersion MAX_VERSION = new SchemaVersion(4);
@@ -85,7 +92,9 @@ class CassandraVersionCheckingTest {
when(versionDAO.getCurrentSchemaVersion())
.thenReturn(Mono.just(Optional.of(MAX_VERSION)));
- assertThatServerStartCorrectly(server);
+ server.start();
+ assertThat(responseAfterConnectTo(server))
+ .startsWith(EXPECTED_SERVER_CONNECTED_MESSAGE);
}
@Test
@@ -93,7 +102,9 @@ class CassandraVersionCheckingTest {
when(versionDAO.getCurrentSchemaVersion())
.thenReturn(Mono.just(Optional.of(MIN_VERSION.next())));
- assertThatServerStartCorrectly(server);
+ server.start();
+ assertThat(responseAfterConnectTo(server))
+ .startsWith(EXPECTED_SERVER_CONNECTED_MESSAGE);
}
@Test
@@ -101,7 +112,9 @@ class CassandraVersionCheckingTest {
when(versionDAO.getCurrentSchemaVersion())
.thenReturn(Mono.just(Optional.of(MIN_VERSION)));
- assertThatServerStartCorrectly(server);
+ server.start();
+ assertThat(responseAfterConnectTo(server))
+ .startsWith(EXPECTED_SERVER_CONNECTED_MESSAGE);
}
@Test
@@ -109,7 +122,11 @@ class CassandraVersionCheckingTest {
when(versionDAO.getCurrentSchemaVersion())
.thenReturn(Mono.just(Optional.of(MIN_VERSION.previous())));
- assertThatThrownBy(server::start).isInstanceOf(IllegalStateException.class);
+ assertThatThrownBy(server::start)
+ .isInstanceOfSatisfying(
+ StartUpChecksException.class,
+ exception -> assertThat(exception.badCheckNames())
+ .containsOnly(CassandraSchemaVersionStartUpCheck.CHECK_NAME));
}
@Test
@@ -117,17 +134,16 @@ class CassandraVersionCheckingTest {
when(versionDAO.getCurrentSchemaVersion())
.thenReturn(Mono.just(Optional.of(MAX_VERSION.next())));
- assertThatThrownBy(server::start).isInstanceOf(IllegalStateException.class);
+ assertThatThrownBy(server::start)
+ .isInstanceOfSatisfying(
+ StartUpChecksException.class,
+ exception -> assertThat(exception.badCheckNames())
+ .containsOnly(CassandraSchemaVersionStartUpCheck.CHECK_NAME));
}
- private void assertThatServerStartCorrectly(GuiceJamesServer server) throws Exception {
- server.start();
+ private String responseAfterConnectTo(GuiceJamesServer server) throws IOException {
socketChannel.connect(new InetSocketAddress(LOCAL_HOST, server.getProbe(ImapGuiceProbe.class).getImapPort()));
- 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();
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/StartUpChecksPerformer.java b/server/container/guice/guice-common/src/main/java/org/apache/james/StartUpChecksPerformer.java
index 02d895e..e047e97 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/StartUpChecksPerformer.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/StartUpChecksPerformer.java
@@ -65,6 +65,13 @@ public class StartUpChecksPerformer {
public List<StartUpCheck.CheckResult> getBadChecks() {
return badChecks;
}
+
+ @VisibleForTesting
+ public List<String> badCheckNames() {
+ return badChecks.stream()
+ .map(StartUpCheck.CheckResult::getName)
+ .collect(Guavate.toImmutableList());
+ }
}
public interface StartUpCheck {
@@ -75,19 +82,19 @@ public class StartUpChecksPerformer {
class CheckResult {
- static class Builder {
+ public static class Builder {
@FunctionalInterface
- interface RequireCheckName {
+ public interface RequireCheckName {
RequireResultType checkName(String name);
}
@FunctionalInterface
- interface RequireResultType {
+ public interface RequireResultType {
ReadyToBuild resultType(ResultType resultType);
}
- static class ReadyToBuild {
+ public static class ReadyToBuild {
private final String name;
private final ResultType resultType;
private Optional<String> description;
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org