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