Plugins: Allow for plugins to implement onModule method that will be automatically injected with the relevant module type, closes #1613.
This commit is contained in:
parent
e37c0904f0
commit
1d35e27b3b
|
@ -30,8 +30,10 @@ import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base class for a plugin.
|
* A base class for a plugin.
|
||||||
*
|
* <p/>
|
||||||
*
|
* A plugin can be dynamically injected with {@link Module} by implementing <tt>onModule(AnyModule)</tt> method
|
||||||
|
* removing the need to override {@link #processModule(org.elasticsearch.common.inject.Module)} and check using
|
||||||
|
* instanceof.
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractPlugin implements Plugin {
|
public abstract class AbstractPlugin implements Plugin {
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,10 @@ import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An extension point allowing to plug in custom functionality.
|
* An extension point allowing to plug in custom functionality.
|
||||||
*
|
* <p/>
|
||||||
*
|
* A plugin can be dynamically injected with {@link Module} by implementing <tt>onModule(AnyModule)</tt> method
|
||||||
|
* removing the need to override {@link #processModule(org.elasticsearch.common.inject.Module)} and check using
|
||||||
|
* instanceof.
|
||||||
*/
|
*/
|
||||||
public interface Plugin {
|
public interface Plugin {
|
||||||
|
|
||||||
|
@ -73,6 +75,10 @@ public interface Plugin {
|
||||||
*/
|
*/
|
||||||
Collection<Class<? extends CloseableIndexComponent>> shardServices();
|
Collection<Class<? extends CloseableIndexComponent>> shardServices();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a specific module. Note, its simpler to implement a custom <tt>onModule(AnyModule module)</tt>
|
||||||
|
* method, which will be automatically be called by the relevant type.
|
||||||
|
*/
|
||||||
void processModule(Module module);
|
void processModule(Module module);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -24,6 +24,7 @@ import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import org.elasticsearch.ElasticSearchException;
|
import org.elasticsearch.ElasticSearchException;
|
||||||
|
import org.elasticsearch.common.collect.MapBuilder;
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
import org.elasticsearch.common.component.AbstractComponent;
|
||||||
import org.elasticsearch.common.component.LifecycleComponent;
|
import org.elasticsearch.common.component.LifecycleComponent;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
@ -51,6 +52,18 @@ public class PluginsService extends AbstractComponent {
|
||||||
|
|
||||||
private final ImmutableMap<String, Plugin> plugins;
|
private final ImmutableMap<String, Plugin> plugins;
|
||||||
|
|
||||||
|
private final ImmutableMap<Plugin, List<OnModuleReference>> onModuleReferences;
|
||||||
|
|
||||||
|
static class OnModuleReference {
|
||||||
|
public final Class<? extends Module> moduleClass;
|
||||||
|
public final Method onModuleMethod;
|
||||||
|
|
||||||
|
OnModuleReference(Class<? extends Module> moduleClass, Method onModuleMethod) {
|
||||||
|
this.moduleClass = moduleClass;
|
||||||
|
this.onModuleMethod = onModuleMethod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public PluginsService(Settings settings, Environment environment) {
|
public PluginsService(Settings settings, Environment environment) {
|
||||||
super(settings);
|
super(settings);
|
||||||
|
@ -65,6 +78,31 @@ public class PluginsService extends AbstractComponent {
|
||||||
logger.info("loaded {}, sites {}", plugins.keySet(), sitePlugins());
|
logger.info("loaded {}, sites {}", plugins.keySet(), sitePlugins());
|
||||||
|
|
||||||
this.plugins = ImmutableMap.copyOf(plugins);
|
this.plugins = ImmutableMap.copyOf(plugins);
|
||||||
|
|
||||||
|
MapBuilder<Plugin, List<OnModuleReference>> onModuleReferences = MapBuilder.newMapBuilder();
|
||||||
|
for (Plugin plugin : plugins.values()) {
|
||||||
|
List<OnModuleReference> list = Lists.newArrayList();
|
||||||
|
for (Method method : plugin.getClass().getDeclaredMethods()) {
|
||||||
|
if (!method.getName().equals("onModule")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (method.getParameterTypes().length == 0 || method.getParameterTypes().length > 1) {
|
||||||
|
logger.warn("Plugin: {} implementing onModule with no parameters or more than one parameter", plugin.name());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Class moduleClass = method.getParameterTypes()[0];
|
||||||
|
if (!Module.class.isAssignableFrom(moduleClass)) {
|
||||||
|
logger.warn("Plugin: {} implementing onModule by the type is not of Module type {}", plugin.name(), moduleClass);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
list.add(new OnModuleReference(moduleClass, method));
|
||||||
|
}
|
||||||
|
if (!list.isEmpty()) {
|
||||||
|
onModuleReferences.put(plugin, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.onModuleReferences = onModuleReferences.immutableMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImmutableMap<String, Plugin> plugins() {
|
public ImmutableMap<String, Plugin> plugins() {
|
||||||
|
@ -80,6 +118,19 @@ public class PluginsService extends AbstractComponent {
|
||||||
public void processModule(Module module) {
|
public void processModule(Module module) {
|
||||||
for (Plugin plugin : plugins().values()) {
|
for (Plugin plugin : plugins().values()) {
|
||||||
plugin.processModule(module);
|
plugin.processModule(module);
|
||||||
|
// see if there are onModule references
|
||||||
|
List<OnModuleReference> references = onModuleReferences.get(plugin);
|
||||||
|
if (references != null) {
|
||||||
|
for (OnModuleReference reference : references) {
|
||||||
|
if (reference.moduleClass.isAssignableFrom(module.getClass())) {
|
||||||
|
try {
|
||||||
|
reference.onModuleMethod.invoke(plugin, module);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.warn("plugin {}, failed to invoke custom onModule method", e, plugin.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue