Skip to content

Commit

Permalink
implement plugin loader
Browse files Browse the repository at this point in the history
  • Loading branch information
seut committed Apr 28, 2015
1 parent b565a71 commit 58d7d44
Show file tree
Hide file tree
Showing 9 changed files with 539 additions and 28 deletions.
1 change: 1 addition & 0 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ configurations {
dependencies {
compile project(':es')
compile 'commons-codec:commons-codec:1.9'
compile 'org.apache.xbean:xbean-finder:4.2'
testCompile project(':testing')
}

Expand Down
106 changes: 106 additions & 0 deletions core/src/main/java/io/crate/Plugin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Licensed to CRATE Technology GmbH ("Crate") under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. Crate 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.
*
* However, if you have executed another commercial license agreement
* with Crate these terms will supersede the license and you may use the
* software solely pursuant to the terms of the relevant commercial agreement.
*/

package io.crate;

import org.elasticsearch.common.component.LifecycleComponent;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.CloseableIndexComponent;

import java.util.Collection;

/**
* An extension point allowing to plug in custom functionality.
* <p/>
* A plugin may implement a constructor with a {@link Settings} argument, which will be called
* preferred to an empty one.
*/
public interface Plugin {

/**
* The name of the plugin.
*/
public String name();

/**
* The description of the plugin.
*/
public String description();

/**
* Node level modules (classes, will automatically be created).
*/
public Collection<Class<? extends Module>> modules();

/**
* Node level modules (instances)
*
* @param settings The node level settings.
*/
public Collection<? extends Module> modules(Settings settings);

/**
* Node level services that will be automatically started/stopped/closed.
*/
public Collection<Class<? extends LifecycleComponent>> services();

/**
* Per index modules.
*/
public Collection<Class<? extends Module>> indexModules();

/**
* Per index modules.
*/
public Collection<? extends Module> indexModules(Settings settings);

/**
* Per index services that will be automatically closed.
*/
public Collection<Class<? extends CloseableIndexComponent>> indexServices();

/**
* Per index shard module.
*/
public Collection<Class<? extends Module>> shardModules();

/**
* Per index shard module.
*/
public Collection<? extends Module> shardModules(Settings settings);

/**
* Per index shard service that will be automatically closed.
*/
public 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.
*/
public void processModule(Module module);

/**
* Additional node settings loaded by the plugin
*/
public Settings additionalSettings();
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,22 @@
import java.util.List;
import java.util.ServiceLoader;

public class CrateLoader {
public class CrateComponentLoader {

private static CrateLoader INSTANCE;
private static CrateComponentLoader INSTANCE;

private final ArrayList<Plugin> plugins;
private static final ESLogger logger = Loggers.getLogger(CrateLoader.class);
private static final ESLogger logger = Loggers.getLogger(CrateComponentLoader.class);
private final ImmutableMap<Plugin, List<OnModuleReference>> onModuleReferences;

public static synchronized CrateLoader getInstance(Settings settings) {
public static synchronized CrateComponentLoader getInstance(Settings settings) {
if (INSTANCE == null) {
INSTANCE = new CrateLoader(settings);
INSTANCE = new CrateComponentLoader(settings);
}
return INSTANCE;
}

private CrateLoader(Settings settings) {
private CrateComponentLoader(Settings settings) {
ServiceLoader<CrateComponent> crateComponents = ServiceLoader.load(CrateComponent.class);
plugins = new ArrayList<>();
MapBuilder<Plugin, List<OnModuleReference>> onModuleReferences = MapBuilder.newMapBuilder();
Expand Down Expand Up @@ -161,11 +161,11 @@ public Settings additionalSettings() {
return builder.build();
}

static class OnModuleReference {
public static class OnModuleReference {
public final Class<? extends Module> moduleClass;
public final Method onModuleMethod;

OnModuleReference(Class<? extends Module> moduleClass, Method onModuleMethod) {
public OnModuleReference(Class<? extends Module> moduleClass, Method onModuleMethod) {
this.moduleClass = moduleClass;
this.onModuleMethod = onModuleMethod;
}
Expand Down
24 changes: 16 additions & 8 deletions core/src/main/java/io/crate/module/CrateCoreModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
import com.google.common.util.concurrent.SettableFuture;
import io.crate.ClusterIdService;
import io.crate.Version;
import io.crate.core.CrateLoader;
import io.crate.core.CrateComponentLoader;
import io.crate.plugin.PluginLoader;
import io.crate.rest.CrateRestMainAction;
import org.elasticsearch.common.inject.*;
import org.elasticsearch.common.inject.matcher.AbstractMatcher;
Expand All @@ -45,21 +46,25 @@

public class CrateCoreModule extends AbstractModule implements SpawnModules, PreProcessModule {

private static final ESLogger logger = Loggers.getLogger(CrateCoreModule.class);
private final CrateLoader crateLoader;
private final ESLogger logger;
private final CrateComponentLoader crateComponentLoader;
private final PluginLoader pluginLoader;
private final Settings settings;

public CrateCoreModule(Settings settings) {
logger = Loggers.getLogger(getClass().getPackage().getName(), settings);
this.settings = settings;
crateLoader = CrateLoader.getInstance(settings);
crateComponentLoader = CrateComponentLoader.getInstance(settings);
pluginLoader = PluginLoader.getInstance(settings);
}

@Override
protected void configure() {
Version version = Version.CURRENT;
logger.info("configuring crate. version: {}", version);

bind(CrateLoader.class).toInstance(crateLoader);
bind(CrateComponentLoader.class).toInstance(crateComponentLoader);
bind(PluginLoader.class).toInstance(pluginLoader);

/**
* This is a rather hacky method to overwrite the handler for "/"
Expand Down Expand Up @@ -88,17 +93,20 @@ protected void configure() {

@Override
public void processModule(Module module) {
crateLoader.processModule(module);
crateComponentLoader.processModule(module);
pluginLoader.processModule(module);
}

@Override
public Iterable<? extends Module> spawnModules() {
List<Module> modules = new ArrayList<>();
Collection<Class<? extends Module>> moduleClasses = crateLoader.modules();
Collection<Class<? extends Module>> moduleClasses = crateComponentLoader.modules();
moduleClasses.addAll(pluginLoader.modules());
for (Class<? extends Module> moduleClass : moduleClasses) {
modules.add(createModule(moduleClass, settings));
}
modules.addAll(crateLoader.modules(settings));
modules.addAll(crateComponentLoader.modules(settings));
modules.addAll(pluginLoader.modules(settings));
return modules;
}

Expand Down
12 changes: 6 additions & 6 deletions core/src/main/java/io/crate/module/CrateCoreShardModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
package io.crate.module;

import com.google.common.collect.Lists;
import io.crate.core.CrateLoader;
import io.crate.core.CrateComponentLoader;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.inject.PreProcessModule;
Expand All @@ -37,27 +37,27 @@
public class CrateCoreShardModule extends AbstractModule implements SpawnModules, PreProcessModule {

private final Settings settings;
private final CrateLoader crateLoader;
private final CrateComponentLoader crateComponentLoader;

public CrateCoreShardModule(Settings settings) {
this.settings = settings;
crateLoader = CrateLoader.getInstance(settings);
crateComponentLoader = CrateComponentLoader.getInstance(settings);
}

@Override
public Iterable<? extends Module> spawnModules() {
List<Module> modules = Lists.newArrayList();
Collection<Class<? extends Module>> modulesClasses = crateLoader.shardModules();
Collection<Class<? extends Module>> modulesClasses = crateComponentLoader.shardModules();
for (Class<? extends Module> moduleClass : modulesClasses) {
modules.add(createModule(moduleClass, settings));
}
modules.addAll(crateLoader.shardModules(settings));
modules.addAll(crateComponentLoader.shardModules(settings));
return modules;
}

@Override
public void processModule(Module module) {
crateLoader.processModule(module);
crateComponentLoader.processModule(module);
}

@Override
Expand Down
122 changes: 122 additions & 0 deletions core/src/main/java/io/crate/plugin/AbstractPlugin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* Licensed to CRATE Technology GmbH ("Crate") under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. Crate 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.
*
* However, if you have executed another commercial license agreement
* with Crate these terms will supersede the license and you may use the
* software solely pursuant to the terms of the relevant commercial agreement.
*/

package io.crate.plugin;

import com.google.common.collect.ImmutableList;
import io.crate.Plugin;
import org.elasticsearch.common.component.LifecycleComponent;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.CloseableIndexComponent;

import java.util.Collection;

/**
* A base class for a plugin.
*/
public abstract class AbstractPlugin implements Plugin {

/**
* Defaults to return an empty list.
*/
@Override
public Collection<Class<? extends Module>> modules() {
return ImmutableList.of();
}

/**
* Defaults to return an empty list.
*/
@Override
public Collection<Module> modules(Settings settings) {
return ImmutableList.of();
}

/**
* Defaults to return an empty list.
*/
@Override
public Collection<Class<? extends LifecycleComponent>> services() {
return ImmutableList.of();
}

/**
* Defaults to return an empty list.
*/
@Override
public Collection<Class<? extends Module>> indexModules() {
return ImmutableList.of();
}

/**
* Defaults to return an empty list.
*/
@Override
public Collection<Module> indexModules(Settings settings) {
return ImmutableList.of();
}

/**
* Defaults to return an empty list.
*/
@Override
public Collection<Class<? extends CloseableIndexComponent>> indexServices() {
return ImmutableList.of();
}

/**
* Defaults to return an empty list.
*/
@Override
public Collection<Class<? extends Module>> shardModules() {
return ImmutableList.of();
}

/**
* Defaults to return an empty list.
*/
@Override
public Collection<Module> shardModules(Settings settings) {
return ImmutableList.of();
}

/**
* Defaults to return an empty list.
*/
@Override
public Collection<Class<? extends CloseableIndexComponent>> shardServices() {
return ImmutableList.of();
}

@Override
public void processModule(Module module) {
// nothing to do here
}

@Override
public Settings additionalSettings() {
return ImmutableSettings.Builder.EMPTY_SETTINGS;
}


}
Loading

0 comments on commit 58d7d44

Please sign in to comment.