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 2019/05/16 08:48:27 UTC

[james-project] 12/23: JAMES-2763 Plug StartUpChecksPerformer to GuiceJamesServer

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 1be5ce56c3287e63fe899fa69eecbae16dc7606f
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Tue May 14 11:40:53 2019 +0700

    JAMES-2763 Plug StartUpChecksPerformer to GuiceJamesServer
---
 .../apache/james/modules/BlobExportImplChoice.java |   2 +-
 .../java/org/apache/james/GuiceJamesServer.java    |   2 +
 .../apache/james/modules/CommonServicesModule.java |   1 +
 .../apache/james/modules/StartUpChecksModule.java  |  33 ++++
 .../james/GuiceJamesServerStartUpCheckTest.java    | 189 +++++++++++++++++++++
 5 files changed, 226 insertions(+), 1 deletion(-)

diff --git a/server/container/guice/blob-export-guice/src/main/java/org/apache/james/modules/BlobExportImplChoice.java b/server/container/guice/blob-export-guice/src/main/java/org/apache/james/modules/BlobExportImplChoice.java
index 8f4f201..c7c3df4 100644
--- a/server/container/guice/blob-export-guice/src/main/java/org/apache/james/modules/BlobExportImplChoice.java
+++ b/server/container/guice/blob-export-guice/src/main/java/org/apache/james/modules/BlobExportImplChoice.java
@@ -29,7 +29,7 @@ import com.google.common.base.Joiner;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
-enum  BlobExportImplChoice {
+public enum  BlobExportImplChoice {
     LOCAL_FILE("localFile"),
     LINSHARE("linshare");
 
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/GuiceJamesServer.java b/server/container/guice/guice-common/src/main/java/org/apache/james/GuiceJamesServer.java
index d355840..d1d5eed 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/GuiceJamesServer.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/GuiceJamesServer.java
@@ -78,6 +78,8 @@ public class GuiceJamesServer {
     public void start() throws Exception {
         Injector injector = Guice.createInjector(module);
         preDestroy = injector.getInstance(Key.get(new TypeLiteral<Stager<PreDestroy>>() {}));
+        injector.getInstance(StartUpChecksPerformer.class)
+            .performCheck();
         injector.getInstance(ConfigurationsPerformer.class).initModules();
         guiceProbeProvider = injector.getInstance(GuiceProbeProvider.class);
         isStartedProbe.notifyStarted();
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/CommonServicesModule.java b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/CommonServicesModule.java
index 075d905..7ed083e 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/CommonServicesModule.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/CommonServicesModule.java
@@ -54,6 +54,7 @@ public class CommonServicesModule extends AbstractModule {
     
     @Override
     protected void configure() {
+        install(new StartUpChecksModule());
         install(new StartablesModule());
         install(new PreDestroyModule());
         install(new DNSServiceModule());
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/StartUpChecksModule.java b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/StartUpChecksModule.java
new file mode 100644
index 0000000..9f7484d
--- /dev/null
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/StartUpChecksModule.java
@@ -0,0 +1,33 @@
+/****************************************************************
+ * 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 org.apache.james.StartUpChecksPerformer;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.multibindings.Multibinder;
+
+public class StartUpChecksModule extends AbstractModule {
+
+    @Override
+    protected void configure() {
+        Multibinder.newSetBinder(binder(), StartUpChecksPerformer.StartUpCheck.class);
+    }
+}
diff --git a/server/container/guice/memory-guice/src/test/java/org/apache/james/GuiceJamesServerStartUpCheckTest.java b/server/container/guice/memory-guice/src/test/java/org/apache/james/GuiceJamesServerStartUpCheckTest.java
new file mode 100644
index 0000000..08daaf4
--- /dev/null
+++ b/server/container/guice/memory-guice/src/test/java/org/apache/james/GuiceJamesServerStartUpCheckTest.java
@@ -0,0 +1,189 @@
+/****************************************************************
+ * 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.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.apache.james.StartUpChecksPerformer.StartUpCheck;
+import org.apache.james.mailbox.extractor.TextExtractor;
+import org.apache.james.mailbox.store.search.PDFTextExtractor;
+import org.apache.james.modules.BlobExportImplChoice;
+import org.apache.james.modules.TestJMAPServerModule;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import com.google.inject.Inject;
+import com.google.inject.multibindings.Multibinder;
+
+class GuiceJamesServerStartUpCheckTest {
+
+    private static class NoopStartUpCheck implements StartUpCheck {
+
+        private static final String CHECK_NAME = "NoopStartUpCheck";
+
+        @Override
+        public CheckResult check() {
+            return CheckResult.builder()
+                .checkName(CHECK_NAME)
+                .resultType(ResultType.GOOD)
+                .build();
+        }
+    }
+
+    private static class FailingStartUpCheck implements StartUpCheck {
+
+        private static final String CHECK_NAME = "FaillingStartUpCheck";
+
+        @Override
+        public CheckResult check() {
+            return CheckResult.builder()
+                .checkName(CHECK_NAME)
+                .resultType(ResultType.BAD)
+                .description("Failing by intention")
+                .build();
+        }
+    }
+
+    private static class TestBlobExportMechanismStartUpCheck implements StartUpCheck {
+
+        private static final String CHECK_NAME = "TestBlobExportMechanismStartUpCheck";
+
+        private final BlobExportImplChoice blobExportImplChoice;
+
+        @Inject
+        private TestBlobExportMechanismStartUpCheck(BlobExportImplChoice blobExportImplChoice) {
+            // do no thing, just verify that start up checks are able to be injected by guice
+            this.blobExportImplChoice = blobExportImplChoice;
+        }
+
+        @Override
+        public CheckResult check() {
+            return CheckResult.builder()
+                .checkName(CHECK_NAME)
+                .resultType(ResultType.GOOD)
+                .build();
+        }
+    }
+
+    private static final int LIMIT_TO_10_MESSAGES = 10;
+
+    interface StartUpCheckSuccessContract {
+
+        @Test
+        default void serverShouldStartSuccessfully(GuiceJamesServer server) throws Exception {
+            server.start();
+
+            assertThat(server.isStarted()).isTrue();
+        }
+    }
+
+    @Nested
+    class WithStartUpCheckDoesntRequireGuiceComponents implements StartUpCheckSuccessContract {
+
+        @RegisterExtension
+        JamesServerExtension jamesServerExtension = new JamesServerBuilder()
+            .server(configuration -> GuiceJamesServer.forConfiguration(configuration)
+                .combineWith(MemoryJamesServerMain.IN_MEMORY_SERVER_AGGREGATE_MODULE)
+                .overrideWith(new TestJMAPServerModule(LIMIT_TO_10_MESSAGES))
+                .overrideWith(binder -> binder.bind(TextExtractor.class).to(PDFTextExtractor.class))
+                .overrideWith(binder -> Multibinder
+                    .newSetBinder(binder, StartUpCheck.class)
+                    .addBinding().to(NoopStartUpCheck.class)))
+            .disableAutoStart()
+            .build();
+    }
+
+    @Nested
+    class WithStartUpCheckRequireGuiceComponents implements StartUpCheckSuccessContract {
+
+        @RegisterExtension
+        JamesServerExtension jamesServerExtension = new JamesServerBuilder()
+            .server(configuration -> GuiceJamesServer.forConfiguration(configuration)
+                .combineWith(MemoryJamesServerMain.IN_MEMORY_SERVER_AGGREGATE_MODULE)
+                .overrideWith(new TestJMAPServerModule(LIMIT_TO_10_MESSAGES))
+                .overrideWith(binder -> binder.bind(TextExtractor.class).to(PDFTextExtractor.class))
+                .overrideWith(binder -> Multibinder
+                    .newSetBinder(binder, StartUpCheck.class)
+                    .addBinding().to(TestBlobExportMechanismStartUpCheck.class)))
+            .disableAutoStart()
+            .build();
+    }
+
+    @Nested
+    class WithNoStartUpCheck implements StartUpCheckSuccessContract {
+
+        @RegisterExtension
+        JamesServerExtension jamesServerExtension = new JamesServerBuilder()
+            .server(configuration -> GuiceJamesServer.forConfiguration(configuration)
+                .combineWith(MemoryJamesServerMain.IN_MEMORY_SERVER_AGGREGATE_MODULE)
+                .overrideWith(new TestJMAPServerModule(LIMIT_TO_10_MESSAGES))
+                .overrideWith(binder -> binder.bind(TextExtractor.class).to(PDFTextExtractor.class)))
+            .disableAutoStart()
+            .build();
+    }
+
+    @Nested
+    class StartUpCheckFails {
+
+        @RegisterExtension
+        JamesServerExtension jamesServerExtension = new JamesServerBuilder()
+            .server(configuration -> GuiceJamesServer.forConfiguration(configuration)
+                .combineWith(MemoryJamesServerMain.IN_MEMORY_SERVER_AGGREGATE_MODULE)
+                .overrideWith(new TestJMAPServerModule(LIMIT_TO_10_MESSAGES))
+                .overrideWith(binder -> binder.bind(TextExtractor.class).to(PDFTextExtractor.class))
+                .overrideWith(binder -> {
+                    Multibinder<StartUpCheck> setBinder = Multibinder
+                        .newSetBinder(binder, StartUpCheck.class);
+
+                    setBinder.addBinding().to(NoopStartUpCheck.class);
+                    setBinder.addBinding().to(FailingStartUpCheck.class);
+                }))
+            .disableAutoStart()
+            .build();
+
+        @Test
+        void startUpCheckFailsShouldThrowAnExceptionCarryingOnlyBadChecks(GuiceJamesServer server) throws Exception {
+            assertThatThrownBy(server::start)
+                .isInstanceOfSatisfying(
+                    StartUpChecksPerformer.StartUpChecksException.class,
+                    exception -> assertThat(nameOfStartUpChecks(exception.getBadChecks()))
+                        .containsOnly(FailingStartUpCheck.CHECK_NAME));
+        }
+
+        @Test
+        void serverShouldNotStartWhenAStartUpCheckFails(GuiceJamesServer server) throws Exception {
+            assertThatThrownBy(server::start)
+                .isInstanceOf(StartUpChecksPerformer.StartUpChecksException.class);
+
+            assertThat(server.isStarted())
+                .isFalse();
+        }
+
+        private Stream<String> nameOfStartUpChecks(List<StartUpCheck.CheckResult> checkResults) {
+            return checkResults.stream()
+                .map(StartUpCheck.CheckResult::getName);
+        }
+    }
+}


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