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 581594857a43e11d7c1c10f88c19cef773672e83 Author: Benoit Tellier <[email protected]> AuthorDate: Thu Sep 19 15:47:59 2019 +0700 JAMES-2886 Allow passign additional guice modules for extensions instantiation --- .../apache/james/modules/CommonServicesModule.java | 2 + server/container/guice/guice-utils/pom.xml | 4 ++ .../apache/james/utils/ExtensionConfiguration.java | 50 ++++++++++++++++++++++ .../org/apache/james/utils/ExtensionModule.java | 50 ++++++++++++++++++++++ .../org/apache/james/utils/GuiceGenericLoader.java | 36 ++++++++++------ .../james/utils/ExtensionConfigurationTest.java | 24 +++++++++++ .../mailbox/MailboxListenersLoaderImplTest.java | 2 +- .../mailbox/PreDeletionHookLoaderImplTest.java | 3 +- 8 files changed, 155 insertions(+), 16 deletions(-) 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 cac9fa9..28a1da6 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 @@ -33,6 +33,7 @@ import org.apache.james.server.core.configuration.ConfigurationProvider; import org.apache.james.server.core.configuration.FileConfigurationProvider; import org.apache.james.server.core.filesystem.FileSystemImpl; import org.apache.james.utils.DataProbeImpl; +import org.apache.james.utils.ExtensionModule; import org.apache.james.utils.GuiceProbe; import com.google.inject.AbstractModule; @@ -53,6 +54,7 @@ public class CommonServicesModule extends AbstractModule { @Override protected void configure() { + install(new ExtensionModule()); install(new StartUpChecksModule()); install(new StartablesModule()); install(new PreDestroyModule()); diff --git a/server/container/guice/guice-utils/pom.xml b/server/container/guice/guice-utils/pom.xml index 74d3657..adc8f23 100644 --- a/server/container/guice/guice-utils/pom.xml +++ b/server/container/guice/guice-utils/pom.xml @@ -35,6 +35,10 @@ </dependency> <dependency> <groupId>${james.groupId}</groupId> + <artifactId>james-server-guice-configuration</artifactId> + </dependency> + <dependency> + <groupId>${james.groupId}</groupId> <artifactId>james-server-util</artifactId> </dependency> <dependency> diff --git a/server/container/guice/guice-utils/src/main/java/org/apache/james/utils/ExtensionConfiguration.java b/server/container/guice/guice-utils/src/main/java/org/apache/james/utils/ExtensionConfiguration.java new file mode 100644 index 0000000..88069b0 --- /dev/null +++ b/server/container/guice/guice-utils/src/main/java/org/apache/james/utils/ExtensionConfiguration.java @@ -0,0 +1,50 @@ +/**************************************************************** + * 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.utils; + +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.configuration2.Configuration; + +import com.github.steveash.guavate.Guavate; +import com.google.common.collect.ImmutableList; + +public class ExtensionConfiguration { + public static final ExtensionConfiguration DEFAULT = new ExtensionConfiguration(ImmutableList.of()); + + public static ExtensionConfiguration from(Configuration configuration) { + List<String> list = Arrays.asList(configuration.getStringArray("guice.extension.module")); + + return new ExtensionConfiguration(list.stream() + .map(ClassName::new) + .collect(Guavate.toImmutableList())); + } + + private final List<ClassName> additionalGuiceModulesForExtensions; + + private ExtensionConfiguration(List<ClassName> additionalGuiceModulesForExtensions) { + this.additionalGuiceModulesForExtensions = additionalGuiceModulesForExtensions; + } + + public List<ClassName> getAdditionalGuiceModulesForExtensions() { + return additionalGuiceModulesForExtensions; + } +} diff --git a/server/container/guice/guice-utils/src/main/java/org/apache/james/utils/ExtensionModule.java b/server/container/guice/guice-utils/src/main/java/org/apache/james/utils/ExtensionModule.java new file mode 100644 index 0000000..1407151 --- /dev/null +++ b/server/container/guice/guice-utils/src/main/java/org/apache/james/utils/ExtensionModule.java @@ -0,0 +1,50 @@ +/**************************************************************** + * 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.utils; + +import java.io.FileNotFoundException; + +import org.apache.commons.configuration2.Configuration; +import org.apache.commons.configuration2.ex.ConfigurationException; +import org.slf4j.LoggerFactory; + +import com.google.inject.AbstractModule; +import com.google.inject.Provides; +import com.google.inject.Scopes; +import com.google.inject.Singleton; + +public class ExtensionModule extends AbstractModule { + @Override + protected void configure() { + bind(GuiceGenericLoader.class).in(Scopes.SINGLETON); + } + + @Provides + @Singleton + ExtensionConfiguration extensionConfiguration(PropertiesProvider propertiesProvider) { + try { + Configuration configuration = propertiesProvider.getConfiguration("extensions"); + return ExtensionConfiguration.from(configuration); + } catch (FileNotFoundException | ConfigurationException e) { + LoggerFactory.getLogger(ExtensionModule.class).info("No extensions.properties configuration found. No additional Guice module will be used for instantiating extensions."); + return ExtensionConfiguration.DEFAULT; + } + } +} diff --git a/server/container/guice/guice-utils/src/main/java/org/apache/james/utils/GuiceGenericLoader.java b/server/container/guice/guice-utils/src/main/java/org/apache/james/utils/GuiceGenericLoader.java index d9c6943..871c52b 100644 --- a/server/container/guice/guice-utils/src/main/java/org/apache/james/utils/GuiceGenericLoader.java +++ b/server/container/guice/guice-utils/src/main/java/org/apache/james/utils/GuiceGenericLoader.java @@ -19,23 +19,25 @@ package org.apache.james.utils; -import java.util.Optional; import java.util.stream.Stream; +import com.github.fge.lambdas.Throwing; +import com.github.steveash.guavate.Guavate; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Module; +import com.google.inject.util.Modules; public class GuiceGenericLoader { - private static final Optional<Module> NO_CHILD_MODULE = Optional.empty(); + private static final Module NO_CHILD_MODULE = binder -> { }; public static class InvocationPerformer<T> { private final Injector injector; private final ExtendedClassLoader extendedClassLoader; private final NamingScheme namingSheme; - private final Optional<Module> childModule; + private final Module childModule; - private InvocationPerformer(Injector injector, ExtendedClassLoader extendedClassLoader, NamingScheme namingSheme, Optional<Module> childModule) { + private InvocationPerformer(Injector injector, ExtendedClassLoader extendedClassLoader, NamingScheme namingSheme, Module childModule) { this.injector = injector; this.extendedClassLoader = extendedClassLoader; this.namingSheme = namingSheme; @@ -44,11 +46,8 @@ public class GuiceGenericLoader { public T instanciate(ClassName className) throws ClassNotFoundException { Class<T> clazz = locateClass(className, namingSheme); - - Injector resolvedInjector = childModule.map(this.injector::createChildInjector) - .orElse(this.injector); - - return resolvedInjector.getInstance(clazz); + return injector.createChildInjector(childModule) + .getInstance(clazz); } private Class<T> locateClass(ClassName className, NamingScheme namingScheme) throws ClassNotFoundException { @@ -69,23 +68,34 @@ public class GuiceGenericLoader { private final Injector injector; private final ExtendedClassLoader extendedClassLoader; + private final Module additionalExtensionBindings; @Inject - public GuiceGenericLoader(Injector injector, ExtendedClassLoader extendedClassLoader) { + public GuiceGenericLoader(Injector injector, ExtendedClassLoader extendedClassLoader, ExtensionConfiguration extensionConfiguration) { this.injector = injector; this.extendedClassLoader = extendedClassLoader; + + this.additionalExtensionBindings = Modules.combine(extensionConfiguration.getAdditionalGuiceModulesForExtensions() + .stream() + .map(Throwing.function(this::<Module>instanciateNoChildModule)) + .collect(Guavate.toImmutableList())); } - public <T> T instanciate(ClassName className) throws ClassNotFoundException { + private <T> T instanciateNoChildModule(ClassName className) throws ClassNotFoundException { return new InvocationPerformer<T>(injector, extendedClassLoader, NamingScheme.IDENTITY, NO_CHILD_MODULE) .instanciate(className); } + public <T> T instanciate(ClassName className) throws ClassNotFoundException { + return new InvocationPerformer<T>(injector, extendedClassLoader, NamingScheme.IDENTITY, additionalExtensionBindings) + .instanciate(className); + } + public <T> InvocationPerformer<T> withNamingSheme(NamingScheme namingSheme) { - return new InvocationPerformer<T>(injector, extendedClassLoader, namingSheme, NO_CHILD_MODULE); + return new InvocationPerformer<T>(injector, extendedClassLoader, namingSheme, additionalExtensionBindings); } public <T> InvocationPerformer<T> withChildModule(Module childModule) { - return new InvocationPerformer<T>(injector, extendedClassLoader, NamingScheme.IDENTITY, Optional.of(childModule)); + return new InvocationPerformer<T>(injector, extendedClassLoader, NamingScheme.IDENTITY, Modules.combine(additionalExtensionBindings, childModule)); } } diff --git a/server/container/guice/guice-utils/src/test/java/org/apache/james/utils/ExtensionConfigurationTest.java b/server/container/guice/guice-utils/src/test/java/org/apache/james/utils/ExtensionConfigurationTest.java new file mode 100644 index 0000000..515380d --- /dev/null +++ b/server/container/guice/guice-utils/src/test/java/org/apache/james/utils/ExtensionConfigurationTest.java @@ -0,0 +1,24 @@ +/**************************************************************** + * 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.utils; + +public class ExtensionConfigurationTest { + +} \ No newline at end of file diff --git a/server/container/guice/mailbox/src/test/java/org/apache/james/modules/mailbox/MailboxListenersLoaderImplTest.java b/server/container/guice/mailbox/src/test/java/org/apache/james/modules/mailbox/MailboxListenersLoaderImplTest.java index a538053..bc921fb 100644 --- a/server/container/guice/mailbox/src/test/java/org/apache/james/modules/mailbox/MailboxListenersLoaderImplTest.java +++ b/server/container/guice/mailbox/src/test/java/org/apache/james/modules/mailbox/MailboxListenersLoaderImplTest.java @@ -61,7 +61,7 @@ class MailboxListenersLoaderImplTest { eventBus = new InVMEventBus(new InVmEventDelivery(new NoopMetricFactory())); - GuiceGenericLoader genericLoader = new GuiceGenericLoader(Guice.createInjector(), new ExtendedClassLoader(fileSystem)); + GuiceGenericLoader genericLoader = GuiceGenericLoader.forTesting(new ExtendedClassLoader(fileSystem)); testee = new MailboxListenersLoaderImpl(new MailboxListenerFactory(genericLoader), eventBus, ImmutableSet.of()); } diff --git a/server/container/guice/mailbox/src/test/java/org/apache/james/modules/mailbox/PreDeletionHookLoaderImplTest.java b/server/container/guice/mailbox/src/test/java/org/apache/james/modules/mailbox/PreDeletionHookLoaderImplTest.java index 0a898e5..d8adc15 100644 --- a/server/container/guice/mailbox/src/test/java/org/apache/james/modules/mailbox/PreDeletionHookLoaderImplTest.java +++ b/server/container/guice/mailbox/src/test/java/org/apache/james/modules/mailbox/PreDeletionHookLoaderImplTest.java @@ -45,8 +45,7 @@ class PreDeletionHookLoaderImplTest { .thenThrow(new FileNotFoundException()); testee = new PreDeletionHookLoaderImpl( - new GuiceGenericLoader( - Guice.createInjector(), + GuiceGenericLoader.forTesting( new ExtendedClassLoader(fileSystem))); } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
