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 2020/04/17 00:32:17 UTC
[james-project] 25/39: JAMES-3134 Check RabbitMQ version at start up
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 4ad5014a92c16f79389013e8dec46abef828fc00
Author: Gautier DI FOLCO <gd...@linagora.com>
AuthorDate: Mon Apr 6 17:45:26 2020 +0200
JAMES-3134 Check RabbitMQ version at start up
---
.../backends/rabbitmq/RabbitMQHealthCheck.java | 15 ++++
.../backends/rabbitmq/RabbitMQServerVersion.java | 70 ++++++++++++++++
.../backends/rabbitmq/SimpleConnectionPool.java | 13 +++
.../rabbitmq/RabbitMQServerVersionTest.java | 96 ++++++++++++++++++++++
4 files changed, 194 insertions(+)
diff --git a/backends-common/rabbitmq/src/main/java/org/apache/james/backends/rabbitmq/RabbitMQHealthCheck.java b/backends-common/rabbitmq/src/main/java/org/apache/james/backends/rabbitmq/RabbitMQHealthCheck.java
index 09a03df..a5e6d00 100644
--- a/backends-common/rabbitmq/src/main/java/org/apache/james/backends/rabbitmq/RabbitMQHealthCheck.java
+++ b/backends-common/rabbitmq/src/main/java/org/apache/james/backends/rabbitmq/RabbitMQHealthCheck.java
@@ -19,6 +19,8 @@
package org.apache.james.backends.rabbitmq;
+import java.util.Optional;
+
import javax.inject.Inject;
import org.apache.james.core.healthcheck.ComponentName;
@@ -26,6 +28,7 @@ import org.apache.james.core.healthcheck.HealthCheck;
import org.apache.james.core.healthcheck.Result;
public class RabbitMQHealthCheck implements HealthCheck {
+ private static final RabbitMQServerVersion MINIMAL_VERSION = RabbitMQServerVersion.of("3.8.1");
private static final ComponentName COMPONENT_NAME = new ComponentName("RabbitMQ backend");
private final SimpleConnectionPool connectionPool;
@@ -46,6 +49,18 @@ public class RabbitMQHealthCheck implements HealthCheck {
public Result check() {
try {
if (connectionPool.tryConnection() && rabbitChannelPoolImpl.tryChannel()) {
+ Optional<RabbitMQServerVersion> version = connectionPool.version();
+ boolean isCompatible = version
+ .map(fetchedVersion -> fetchedVersion.isAtLeast(MINIMAL_VERSION))
+ .orElse(false);
+ if (!isCompatible) {
+ String versionCompatibilityError = String.format(
+ "RabbitMQ version(%s) is not compatible with the required one(%s)",
+ version.map(RabbitMQServerVersion::asString).orElse("no versions fetched"),
+ MINIMAL_VERSION.asString());
+ return Result.unhealthy(COMPONENT_NAME, versionCompatibilityError);
+ }
+
return Result.healthy(COMPONENT_NAME);
} else {
return Result.unhealthy(COMPONENT_NAME, "The created connection was not opened");
diff --git a/backends-common/rabbitmq/src/main/java/org/apache/james/backends/rabbitmq/RabbitMQServerVersion.java b/backends-common/rabbitmq/src/main/java/org/apache/james/backends/rabbitmq/RabbitMQServerVersion.java
new file mode 100644
index 0000000..a0500c8
--- /dev/null
+++ b/backends-common/rabbitmq/src/main/java/org/apache/james/backends/rabbitmq/RabbitMQServerVersion.java
@@ -0,0 +1,70 @@
+/****************************************************************
+ * 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.rabbitmq;
+
+import java.util.Objects;
+
+import com.fasterxml.jackson.core.Version;
+import com.fasterxml.jackson.core.util.VersionUtil;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.MoreObjects;
+
+public class RabbitMQServerVersion {
+ public static RabbitMQServerVersion of(String input) {
+ return new RabbitMQServerVersion(VersionUtil.parseVersion(input, "rabbitmq", "version"));
+ }
+
+ private final Version version;
+
+ @VisibleForTesting
+ RabbitMQServerVersion(Version version) {
+ this.version = version;
+ }
+
+ public boolean isAtLeast(RabbitMQServerVersion other) {
+ return version.compareTo(other.version) >= 0;
+ }
+
+ public String asString() {
+ return version.toFullString();
+ }
+
+ @Override
+ public final boolean equals(Object other) {
+ if (other instanceof RabbitMQServerVersion) {
+ RabbitMQServerVersion that = (RabbitMQServerVersion) other;
+ return Objects.equals(version, that.version);
+ }
+
+ return false;
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(version);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("version", version)
+ .toString();
+ }
+}
diff --git a/backends-common/rabbitmq/src/main/java/org/apache/james/backends/rabbitmq/SimpleConnectionPool.java b/backends-common/rabbitmq/src/main/java/org/apache/james/backends/rabbitmq/SimpleConnectionPool.java
index 0354002..6aa1ba5 100644
--- a/backends-common/rabbitmq/src/main/java/org/apache/james/backends/rabbitmq/SimpleConnectionPool.java
+++ b/backends-common/rabbitmq/src/main/java/org/apache/james/backends/rabbitmq/SimpleConnectionPool.java
@@ -88,4 +88,17 @@ public class SimpleConnectionPool implements AutoCloseable {
return false;
}
}
+
+ public Optional<RabbitMQServerVersion> version() {
+ try {
+ return getOpenConnection()
+ .map(Connection::getServerProperties)
+ .flatMap(serverProperties -> Mono.justOrEmpty(serverProperties.get("version")))
+ .map(Object::toString)
+ .map(RabbitMQServerVersion::of)
+ .blockOptional(Duration.ofSeconds(1));
+ } catch (Throwable t) {
+ return Optional.empty();
+ }
+ }
}
diff --git a/backends-common/rabbitmq/src/test/java/org/apache/james/backends/rabbitmq/RabbitMQServerVersionTest.java b/backends-common/rabbitmq/src/test/java/org/apache/james/backends/rabbitmq/RabbitMQServerVersionTest.java
new file mode 100644
index 0000000..a90c9c9
--- /dev/null
+++ b/backends-common/rabbitmq/src/test/java/org/apache/james/backends/rabbitmq/RabbitMQServerVersionTest.java
@@ -0,0 +1,96 @@
+/****************************************************************
+ * 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.rabbitmq;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.stream.Stream;
+
+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.fasterxml.jackson.core.Version;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+class RabbitMQServerVersionTest {
+ @Test
+ void shouldMatchBeanContract() {
+ EqualsVerifier.forClass(RabbitMQServerVersion.class)
+ .verify();
+ }
+
+ @ParameterizedTest
+ @MethodSource("versionsToParse")
+ void shouldParseVersion(String input, Version expected) {
+ assertThat(RabbitMQServerVersion.of(input)).isEqualTo(new RabbitMQServerVersion(expected));
+ }
+
+ @ParameterizedTest
+ @MethodSource("versionsComparison")
+ void shouldBeAtLeast(String lower, String upper) {
+ RabbitMQServerVersion lowerVersion = RabbitMQServerVersion.of(lower);
+ RabbitMQServerVersion upperVersion = RabbitMQServerVersion.of(upper);
+ assertThat(upperVersion.isAtLeast(lowerVersion)).isTrue();
+ }
+
+ @ParameterizedTest
+ @MethodSource("versionsReversedComparison")
+ void shouldNotBeAtLeastWhenReversed(String lower, String upper) {
+ RabbitMQServerVersion lowerVersion = RabbitMQServerVersion.of(lower);
+ RabbitMQServerVersion upperVersion = RabbitMQServerVersion.of(upper);
+ assertThat(lowerVersion.isAtLeast(upperVersion)).isFalse();
+ }
+
+ static Stream<Arguments> versionsToParse() {
+ return Stream.of(
+ Arguments.of("3.8.1", version(3, 8, 1)),
+ Arguments.of("3.18.1", version(3, 18, 1)),
+ Arguments.of("3.8.", version(3, 8, 0)),
+ Arguments.of("3.8.0+beta.4.38.g33a7f97", version(3, 8, 0)),
+ Arguments.of("3.7.1-alpha.40", version(3, 7, 1)),
+ Arguments.of("3.7.0~alpha.449-1", version(3, 7, 0))
+ );
+ }
+
+ static Stream<Arguments> versionsComparison() {
+ return Stream.of(
+ Arguments.of("3.8.1", "3.8.1"),
+ Arguments.of("3.18.1", "3.18.1"),
+ Arguments.of("3.8.", "3.8.0"),
+ Arguments.of("3.7.5", "3.8.1"),
+ Arguments.of("3.8", "3.8.1"),
+ Arguments.of("3.8.0", "4.0.0")
+ );
+ }
+
+ static Stream<Arguments> versionsReversedComparison() {
+ return Stream.of(
+ Arguments.of("3.7.5", "3.8.1"),
+ Arguments.of("3.8", "3.8.1"),
+ Arguments.of("3.8.0", "4.0.0")
+ );
+ }
+
+ private static Version version(int major, int minor, int patch) {
+ return new Version(major, minor, patch, "", "rabbitmq", "version");
+ }
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org