You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2022/09/22 02:51:01 UTC

[james-project] 04/07: JAMES-3784 HealthCheck /var/mail/error repository size

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch 3.7.x
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 474222f41b20ade6e48e4690d0459a9a484d53a5
Author: Tung Van TRAN <vt...@linagora.com>
AuthorDate: Thu Jun 23 17:51:35 2022 +0700

    JAMES-3784 HealthCheck /var/mail/error repository size
---
 .../ErrorMailRepositoryEmptyHealthCheckModule.java | 45 +++++++++++
 .../api/EmptyErrorMailRepositoryHealthCheck.java   | 56 +++++++++++++
 ...mptyErrorMailRepositoryHealthCheckContract.java | 94 ++++++++++++++++++++++
 ...oryEmptyErrorMailRepositoryHealthCheckTest.java | 65 +++++++++++++++
 4 files changed, 260 insertions(+)

diff --git a/server/container/guice/common/src/main/java/org/apache/james/modules/ErrorMailRepositoryEmptyHealthCheckModule.java b/server/container/guice/common/src/main/java/org/apache/james/modules/ErrorMailRepositoryEmptyHealthCheckModule.java
new file mode 100644
index 0000000000..753d98989c
--- /dev/null
+++ b/server/container/guice/common/src/main/java/org/apache/james/modules/ErrorMailRepositoryEmptyHealthCheckModule.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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;
+
+import static org.apache.james.mailrepository.api.MailRepositoryEmptyHealthCheck.ErrorMailRepositoryEmptyHealthCheck;
+
+import org.apache.james.core.healthcheck.HealthCheck;
+import org.apache.james.mailrepository.api.MailRepositoryStore;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+import com.google.inject.Singleton;
+import com.google.inject.multibindings.Multibinder;
+
+public class ErrorMailRepositoryEmptyHealthCheckModule extends AbstractModule {
+
+    @Override
+    protected void configure() {
+        Multibinder.newSetBinder(binder(), HealthCheck.class).addBinding().to(ErrorMailRepositoryEmptyHealthCheck.class);
+    }
+
+    @Singleton
+    @Provides
+    ErrorMailRepositoryEmptyHealthCheck provideErrorMailRepositoryEmptyHealthCheck(MailRepositoryStore mailRepositoryStore) {
+        return new ErrorMailRepositoryEmptyHealthCheck(mailRepositoryStore);
+    }
+
+}
diff --git a/server/mailrepository/mailrepository-api/src/main/java/org/apache/james/mailrepository/api/EmptyErrorMailRepositoryHealthCheck.java b/server/mailrepository/mailrepository-api/src/main/java/org/apache/james/mailrepository/api/EmptyErrorMailRepositoryHealthCheck.java
new file mode 100644
index 0000000000..dd8752b0ca
--- /dev/null
+++ b/server/mailrepository/mailrepository-api/src/main/java/org/apache/james/mailrepository/api/EmptyErrorMailRepositoryHealthCheck.java
@@ -0,0 +1,56 @@
+/****************************************************************
+ * 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.mailrepository.api;
+
+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.util.FunctionalUtils;
+
+import com.github.fge.lambdas.Throwing;
+
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+public class EmptyErrorMailRepositoryHealthCheck implements HealthCheck {
+    public static final ComponentName COMPONENT_NAME = new ComponentName("EmptyErrorMailRepository");
+    private final MailRepositoryStore repositoryStore;
+    private final MailRepositoryPath errorRepositoryPath;
+
+    public EmptyErrorMailRepositoryHealthCheck(MailRepositoryPath errorRepositoryPath, MailRepositoryStore repositoryStore) {
+        this.repositoryStore = repositoryStore;
+        this.errorRepositoryPath = errorRepositoryPath;
+    }
+
+    @Override
+    public ComponentName componentName() {
+        return COMPONENT_NAME;
+    }
+
+    @Override
+    public Mono<Result> check() {
+        // TODO: use .sizeReactive of https://github.com/apache/james-project/pull/1049/
+        return Flux.fromStream(Throwing.supplier(() -> repositoryStore.getByPath(errorRepositoryPath)))
+            .any(Throwing.predicate(repository -> repository.size() > 0))
+            .filter(FunctionalUtils.identityPredicate())
+            .map(hasSize -> Result.degraded(COMPONENT_NAME, "MailRepository is not empty"))
+            .switchIfEmpty(Mono.just(Result.healthy(COMPONENT_NAME)));
+    }
+}
diff --git a/server/mailrepository/mailrepository-api/src/test/java/org/apache/james/mailrepository/api/EmptyErrorMailRepositoryHealthCheckContract.java b/server/mailrepository/mailrepository-api/src/test/java/org/apache/james/mailrepository/api/EmptyErrorMailRepositoryHealthCheckContract.java
new file mode 100644
index 0000000000..ae9975de61
--- /dev/null
+++ b/server/mailrepository/mailrepository-api/src/test/java/org/apache/james/mailrepository/api/EmptyErrorMailRepositoryHealthCheckContract.java
@@ -0,0 +1,94 @@
+/****************************************************************
+ * 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.mailrepository.api;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.james.core.builder.MimeMessageBuilder;
+import org.apache.james.core.healthcheck.ComponentName;
+import org.apache.james.core.healthcheck.Result;
+import org.apache.mailet.base.test.FakeMail;
+import org.junit.jupiter.api.Test;
+
+public interface EmptyErrorMailRepositoryHealthCheckContract {
+    MailRepositoryPath ERROR_REPOSITORY_PATH = MailRepositoryPath.from("var/mail/error");
+
+    MailRepositoryStore repositoryStore();
+
+    void createRepository();
+
+    default EmptyErrorMailRepositoryHealthCheck testee() {
+        createRepository();
+        return new EmptyErrorMailRepositoryHealthCheck(ERROR_REPOSITORY_PATH, repositoryStore());
+    }
+
+    @Test
+    default void componentNameShouldReturnTheRightValue() {
+        assertThat(testee().componentName().getName())
+            .isEqualTo("EmptyErrorMailRepository");
+    }
+
+    @Test
+    default void checkShouldReturnHealthyWhenRepositorySizeIsEmpty() {
+        EmptyErrorMailRepositoryHealthCheck testee = testee();
+        assertThat(testee.check().block())
+            .isEqualTo(Result.healthy(new ComponentName("EmptyErrorMailRepository")));
+    }
+
+    @Test
+    default void checkShouldReturnHealthyWhenRepositoryIsNotCreated() {
+        EmptyErrorMailRepositoryHealthCheck testee = new EmptyErrorMailRepositoryHealthCheck(ERROR_REPOSITORY_PATH, repositoryStore());
+        assertThat(testee.check().block())
+            .isEqualTo(Result.healthy(new ComponentName("EmptyErrorMailRepository")));
+    }
+
+    @Test
+    default void checkShouldReturnDegradedWhenRepositorySizeIsNotEmpty() throws Exception {
+        EmptyErrorMailRepositoryHealthCheck testee = testee();
+        repositoryStore().getByPath(ERROR_REPOSITORY_PATH)
+            .findFirst().orElseThrow()
+            .store(FakeMail.builder()
+                .name("name1")
+                .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
+                    .setText("Any body"))
+                .build());
+
+        assertThat(testee.check().block().isDegraded())
+            .isTrue();
+    }
+
+    @Test
+    default void checkShouldReturnHealthyWhenRepositorySizeReturnEmptyAgain() throws Exception {
+        EmptyErrorMailRepositoryHealthCheck testee = testee();
+        MailRepository mailRepository = repositoryStore().getByPath(ERROR_REPOSITORY_PATH).findFirst().orElseThrow();
+        mailRepository.store(FakeMail.builder()
+            .name("name1")
+            .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
+                .setText("Any body"))
+            .build());
+
+        assertThat(testee.check().block().isDegraded())
+            .isTrue();
+
+        mailRepository.removeAll();
+        assertThat(testee.check().block().isHealthy())
+            .isTrue();
+    }
+}
diff --git a/server/mailrepository/mailrepository-memory/src/test/java/org/apache/james/mailrepository/memory/MemoryEmptyErrorMailRepositoryHealthCheckTest.java b/server/mailrepository/mailrepository-memory/src/test/java/org/apache/james/mailrepository/memory/MemoryEmptyErrorMailRepositoryHealthCheckTest.java
new file mode 100644
index 0000000000..651bb84916
--- /dev/null
+++ b/server/mailrepository/mailrepository-memory/src/test/java/org/apache/james/mailrepository/memory/MemoryEmptyErrorMailRepositoryHealthCheckTest.java
@@ -0,0 +1,65 @@
+/****************************************************************
+ * 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.mailrepository.memory;
+
+import org.apache.james.mailrepository.api.EmptyErrorMailRepositoryHealthCheckContract;
+import org.apache.james.mailrepository.api.MailRepositoryStore;
+import org.apache.james.mailrepository.api.MailRepositoryUrl;
+import org.apache.james.server.core.configuration.Configuration;
+import org.apache.james.server.core.configuration.FileConfigurationProvider;
+import org.apache.james.server.core.filesystem.FileSystemImpl;
+import org.junit.jupiter.api.BeforeEach;
+
+public class MemoryEmptyErrorMailRepositoryHealthCheckTest implements EmptyErrorMailRepositoryHealthCheckContract {
+
+    private MemoryMailRepositoryStore repositoryStore;
+
+    @BeforeEach
+    void setup() throws Exception {
+        Configuration.Basic configuration = Configuration.builder()
+            .workingDirectory("../")
+            .configurationFromClasspath()
+            .build();
+
+        FileSystemImpl fileSystem = new FileSystemImpl(configuration.directories());
+
+        MailRepositoryStoreConfiguration storeConfiguration = MailRepositoryStoreConfiguration.parse(
+            new FileConfigurationProvider(fileSystem, configuration).getConfiguration("mailrepositorystore"));
+
+        repositoryStore = new MemoryMailRepositoryStore(new MemoryMailRepositoryUrlStore(),
+            new SimpleMailRepositoryLoader(),
+            storeConfiguration);
+        repositoryStore.init();
+    }
+
+    @Override
+    public MailRepositoryStore repositoryStore() {
+        return repositoryStore;
+    }
+
+    @Override
+    public void createRepository() {
+        try {
+            repositoryStore.create(MailRepositoryUrl.fromPathAndProtocol(ERROR_REPOSITORY_PATH, "memory1"));
+        } catch (MailRepositoryStore.MailRepositoryStoreException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}


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