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 8bf1969e58e097beffb354fad3fbefe003d7fbf8
Author: Tran Tien Duc <[email protected]>
AuthorDate: Thu Dec 12 15:47:49 2019 +0700

    JAMES-3007 MessageFastViewProjection HealthCheck
---
 .../MessageFastViewProjectionHealthCheck.java      |  74 ++++++++
 .../MessageFastViewProjectionHealthCheckTest.java  | 186 +++++++++++++++++++++
 2 files changed, 260 insertions(+)

diff --git 
a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/MessageFastViewProjectionHealthCheck.java
 
b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/MessageFastViewProjectionHealthCheck.java
new file mode 100644
index 0000000..de18851
--- /dev/null
+++ 
b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/MessageFastViewProjectionHealthCheck.java
@@ -0,0 +1,74 @@
+/****************************************************************
+ * 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.jmap.api.projections;
+
+import static 
org.apache.james.jmap.api.projections.MessageFastViewProjection.METRIC_RETRIEVE_HIT_COUNT;
+import static 
org.apache.james.jmap.api.projections.MessageFastViewProjection.METRIC_RETRIEVE_MISS_COUNT;
+
+import javax.inject.Inject;
+
+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.metrics.api.Metric;
+import org.apache.james.metrics.api.MetricFactory;
+
+public class MessageFastViewProjectionHealthCheck implements HealthCheck {
+
+    private static final ComponentName COMPONENT_NAME = new 
ComponentName("MessageFastViewProjection");
+    private static final double MAXIMUM_MISS_PERCENTAGE_ACCEPTED = 10;
+
+    private final Metric retrieveHitCountMetric;
+    private final Metric retrieveMissCountMetric;
+
+    @Inject
+    MessageFastViewProjectionHealthCheck(MetricFactory metricFactory) {
+        retrieveHitCountMetric = 
metricFactory.generate(METRIC_RETRIEVE_HIT_COUNT);
+        retrieveMissCountMetric = 
metricFactory.generate(METRIC_RETRIEVE_MISS_COUNT);
+    }
+
+    @Override
+    public ComponentName componentName() {
+        return COMPONENT_NAME;
+    }
+
+    @Override
+    public Result check() {
+        long hitCount = retrieveHitCountMetric.getCount();
+        long missCount = retrieveMissCountMetric.getCount();
+
+        if (missCount == 0) {
+            return Result.healthy(COMPONENT_NAME);
+        }
+        return check(hitCount, missCount);
+    }
+
+    private Result check(long hitCount, long missCount) {
+        long totalCount = hitCount + missCount;
+        double missCountPercentage = missCount * 100.0d / totalCount;
+        if (missCountPercentage > MAXIMUM_MISS_PERCENTAGE_ACCEPTED) {
+            return Result.degraded(COMPONENT_NAME,
+                String.format("retrieveMissCount percentage %s%% (%d/%d) is 
higher than the threshold %s%%",
+                    missCountPercentage, missCount, totalCount, 
MAXIMUM_MISS_PERCENTAGE_ACCEPTED));
+        }
+
+        return Result.healthy(COMPONENT_NAME);
+    }
+}
diff --git 
a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/projections/MessageFastViewProjectionHealthCheckTest.java
 
b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/projections/MessageFastViewProjectionHealthCheckTest.java
new file mode 100644
index 0000000..b9888e7
--- /dev/null
+++ 
b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/projections/MessageFastViewProjectionHealthCheckTest.java
@@ -0,0 +1,186 @@
+/****************************************************************
+ * 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.jmap.api.projections;
+
+import static 
org.apache.james.jmap.api.projections.MessageFastViewProjection.METRIC_RETRIEVE_HIT_COUNT;
+import static 
org.apache.james.jmap.api.projections.MessageFastViewProjection.METRIC_RETRIEVE_MISS_COUNT;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.stream.IntStream;
+
+import org.apache.james.core.healthcheck.ComponentName;
+import org.apache.james.core.healthcheck.Result;
+import org.apache.james.metrics.api.Metric;
+import org.apache.james.metrics.tests.RecordingMetricFactory;
+import org.assertj.core.api.SoftAssertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+class MessageFastViewProjectionHealthCheckTest {
+
+    private static final ComponentName COMPONENT_NAME = new 
ComponentName("MessageFastViewProjection");
+
+    private MessageFastViewProjectionHealthCheck testee;
+    private Metric hitMetric;
+    private Metric missMetric;
+
+    @BeforeEach
+    void setUp() {
+        RecordingMetricFactory metricFactory = new RecordingMetricFactory();
+        testee = new MessageFastViewProjectionHealthCheck(metricFactory);
+
+        hitMetric = metricFactory.generate(METRIC_RETRIEVE_HIT_COUNT);
+        missMetric = metricFactory.generate(METRIC_RETRIEVE_MISS_COUNT);
+    }
+
+    @Test
+    void componentNameShouldReturnTheRightValue() {
+        assertThat(testee.componentName())
+            .isEqualTo(COMPONENT_NAME);
+    }
+
+    @Nested
+    class WithTenPercentMaximumOfMissCount {
+
+        @Test
+        void checkShouldReturnHealthyWhenNoRetrieveCalled() {
+            assertThat(testee.check())
+                .isEqualTo(Result.healthy(COMPONENT_NAME));
+        }
+
+        @Test
+        void checkShouldReturnDegradedWhenNoHitButSomeMiss() {
+            missMetric.increment();
+            missMetric.increment();
+
+            assertThat(testee.check())
+                .isEqualTo(Result.degraded(COMPONENT_NAME, "retrieveMissCount 
percentage 100.0% (2/2) is higher than the threshold 10.0%"));
+        }
+
+        @Test
+        void 
checkShouldReturnHealthyWhenMissCountPercentageIsLessThanThreshold() {
+            missMetric.increment();
+            hitMetric.add(43);
+
+            assertThat(testee.check())
+                .isEqualTo(Result.healthy(COMPONENT_NAME));
+        }
+
+        @Test
+        void 
checkShouldReturnHealthyWhenMissCountPercentageIsEqualToThreshold() {
+            missMetric.increment();
+            hitMetric.add(9);
+
+            assertThat(testee.check())
+                .isEqualTo(Result.healthy(COMPONENT_NAME));
+        }
+
+        @Test
+        void 
checkShouldReturnDegradedWhenMissCountPercentageIsGreaterThanThreshold() {
+            missMetric.increment();
+            hitMetric.add(3);
+
+            assertThat(testee.check())
+                .isEqualTo(Result.degraded(COMPONENT_NAME,
+                    "retrieveMissCount percentage 25.0% (1/4) is higher than 
the threshold 10.0%"));
+        }
+
+        @Test
+        void checkShouldReturnHealthyAfterMoreHits() {
+            missMetric.increment();
+            hitMetric.increment();
+            Result resultWithLessHit = testee.check();
+
+            // more hits
+            hitMetric.add(10);
+            Result resultWithMoreHit = testee.check();
+
+            SoftAssertions.assertSoftly(softly -> {
+                softly.assertThat(resultWithLessHit)
+                    .isEqualTo(Result.degraded(COMPONENT_NAME,
+                    "retrieveMissCount percentage 50.0% (1/2) is higher than 
the threshold 10.0%"));
+                softly.assertThat(resultWithMoreHit)
+                    .isEqualTo(Result.healthy(COMPONENT_NAME));
+            });
+        }
+
+        @Test
+        void checkShouldKeepBeingDegradedAfterNotEnoughOfHits() {
+            missMetric.increment();
+            hitMetric.increment();
+            Result resultWithLessHit = testee.check();
+
+            // more hits, but not enough
+            hitMetric.add(3);
+            Result resultWithMoreHit = testee.check();
+
+            SoftAssertions.assertSoftly(softly -> {
+                softly.assertThat(resultWithLessHit)
+                    .isEqualTo(Result.degraded(COMPONENT_NAME,
+                    "retrieveMissCount percentage 50.0% (1/2) is higher than 
the threshold 10.0%"));
+                softly.assertThat(resultWithMoreHit)
+                    .isEqualTo(Result.degraded(COMPONENT_NAME,
+                        "retrieveMissCount percentage 20.0% (1/5) is higher 
than the threshold 10.0%"));
+            });
+        }
+
+        @Test
+        void checkShouldReturnDegradedAfterMoreHiss() {
+            missMetric.increment();
+            // enough of hits
+            hitMetric.add(10);
+
+            Result resultWithEnoughOfHits = testee.check();
+
+            // more miss
+            missMetric.increment();
+            Result resultWithMoreMiss = testee.check();
+
+            SoftAssertions.assertSoftly(softly -> {
+                softly.assertThat(resultWithEnoughOfHits)
+                    .isEqualTo(Result.healthy(COMPONENT_NAME));
+                softly.assertThat(resultWithMoreMiss)
+                    .isEqualTo(Result.degraded(COMPONENT_NAME,
+                        "retrieveMissCount percentage 16.666666666666668% 
(2/12) is higher than the threshold 10.0%"));
+            });
+        }
+
+        @Test
+        void checkShouldKeepBeingHealthyAfterNotEnoughOfMiss() {
+            missMetric.increment();
+            // enough of hits
+            hitMetric.add(10000);
+            Result resultWithEnoughOfHits = testee.check();
+
+            // more miss, but not enough
+            IntStream.rangeClosed(1, 3)
+                .forEach(counter -> missMetric.increment());
+            Result resultWithMoreMiss = testee.check();
+
+            SoftAssertions.assertSoftly(softly -> {
+                softly.assertThat(resultWithEnoughOfHits)
+                    .isEqualTo(Result.healthy(COMPONENT_NAME));
+                softly.assertThat(resultWithMoreMiss)
+                    .isEqualTo(Result.healthy(COMPONENT_NAME));
+            });
+        }
+    }
+}
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to