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 <[email protected]> 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: [email protected] For additional commands, e-mail: [email protected]
