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:31:54 UTC

[james-project] 02/39: JAMES-3117 Add PeriodicalHealthChecks/Test

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 2e7b08bc939b8bf6c3f0bb332b4c3c490345cc4b
Author: LanKhuat <kh...@gmail.com>
AuthorDate: Thu Mar 19 10:56:58 2020 +0700

    JAMES-3117 Add PeriodicalHealthChecks/Test
---
 server/container/guice/guice-common/pom.xml        |  9 +++
 .../org/apache/james/PeriodicalHealthChecks.java   | 64 +++++++++++++++
 .../apache/james/PeriodicalHealthChecksTest.java   | 91 ++++++++++++++++++++++
 3 files changed, 164 insertions(+)

diff --git a/server/container/guice/guice-common/pom.xml b/server/container/guice/guice-common/pom.xml
index dfff299..4433636 100644
--- a/server/container/guice/guice-common/pom.xml
+++ b/server/container/guice/guice-common/pom.xml
@@ -152,6 +152,15 @@
             <artifactId>guice</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/PeriodicalHealthChecks.java b/server/container/guice/guice-common/src/main/java/org/apache/james/PeriodicalHealthChecks.java
new file mode 100644
index 0000000..91d0872
--- /dev/null
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/PeriodicalHealthChecks.java
@@ -0,0 +1,64 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james;
+
+import java.time.Duration;
+import java.util.Set;
+
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+
+import org.apache.james.core.healthcheck.HealthCheck;
+import org.apache.james.lifecycle.api.Startable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import reactor.core.Disposable;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+import reactor.core.scheduler.Schedulers;
+
+public class PeriodicalHealthChecks implements Startable {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(PeriodicalHealthChecks.class);
+    private static final long INITIAL_DELAY = 1;
+    private static final long PERIOD = 1;
+
+    private final Flux<HealthCheck> healthChecks;
+    private Disposable disposable;
+
+    @Inject
+    PeriodicalHealthChecks(Set<HealthCheck> healthChecks) {
+        this.healthChecks = Flux.fromIterable(healthChecks);
+    }
+
+    public void start() {
+        disposable = Flux.interval(Duration.ofSeconds(INITIAL_DELAY), Duration.ofSeconds(PERIOD))
+            .flatMap(any ->
+                healthChecks.flatMap(healthCheck -> Mono.just(healthCheck.check())))
+            .subscribeOn(Schedulers.elastic())
+            .subscribe();
+    }
+
+    @PreDestroy
+    public void stop() {
+        disposable.dispose();
+    }
+}
diff --git a/server/container/guice/guice-common/src/test/java/org/apache/james/PeriodicalHealthChecksTest.java b/server/container/guice/guice-common/src/test/java/org/apache/james/PeriodicalHealthChecksTest.java
new file mode 100644
index 0000000..f029333
--- /dev/null
+++ b/server/container/guice/guice-common/src/test/java/org/apache/james/PeriodicalHealthChecksTest.java
@@ -0,0 +1,91 @@
+/****************************************************************
+ * 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.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.james.core.healthcheck.ComponentName;
+import org.apache.james.core.healthcheck.HealthCheck;
+import org.apache.james.core.healthcheck.Result;
+import org.apache.james.mailbox.events.EventDeadLettersHealthCheck;
+import org.awaitility.Awaitility;
+import org.awaitility.Duration;
+import org.awaitility.core.ConditionFactory;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+public class PeriodicalHealthChecksTest {
+
+    private static final ConditionFactory AWAIT = Awaitility.await()
+        .atMost(Duration.TEN_SECONDS)
+        .with()
+        .pollInterval(Duration.ONE_SECOND);
+
+    private HealthCheck mockHealthCheck1;
+    private HealthCheck mockHealthCheck2;
+    private PeriodicalHealthChecks testee;
+
+    @BeforeEach
+    void setUp() {
+        mockHealthCheck1 = Mockito.mock(EventDeadLettersHealthCheck.class);
+        mockHealthCheck2 = Mockito.mock(GuiceLifecycleHealthCheck.class);
+        when(mockHealthCheck1.check()).thenReturn(Result.healthy(new ComponentName("mock1")));
+        when(mockHealthCheck2.check()).thenReturn(Result.healthy(new ComponentName("mock2")));
+
+        Set<HealthCheck> healthCheckSet = new HashSet<>();
+        healthCheckSet.add(mockHealthCheck1);
+        healthCheckSet.add(mockHealthCheck2);
+
+        testee = new PeriodicalHealthChecks(healthCheckSet);
+        testee.start();
+    }
+
+    @AfterEach
+    void tearDown() {
+        testee.stop();
+    }
+
+    @Test
+    void startShouldCallHealthCheckAtLeastOnce() {
+        AWAIT.untilAsserted(() -> verify(mockHealthCheck1, atLeast(1)).check());
+    }
+
+    @Test
+    void startShouldCallHealthCheckMultipleTimes() {
+        AWAIT.untilAsserted(() -> verify(mockHealthCheck1, times(5)).check());
+    }
+
+    @Test
+    void startShouldCallAllHealthChecks() {
+        AWAIT.untilAsserted(() -> {
+            verify(mockHealthCheck1, atLeast(5)).check();
+            verify(mockHealthCheck2, atLeast(5)).check();
+        });
+    }
+}


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