plugins support + start work on attachments plugin
This commit is contained in:
parent
73daff1584
commit
b799b7a9d7
|
@ -40,6 +40,7 @@
|
|||
<w>ngram</w>
|
||||
<w>param</w>
|
||||
<w>params</w>
|
||||
<w>plugins</w>
|
||||
<w>porterstem</w>
|
||||
<w>rebalance</w>
|
||||
<w>searchable</w>
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<component name="libraryTable">
|
||||
<library name="tika">
|
||||
<CLASSES>
|
||||
<root url="jar://$GRADLE_REPOSITORY$/org.apache.tika/tika-app/bundles/tika-app-0.6.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
|
@ -5,6 +5,7 @@
|
|||
<module fileurl="file://$PROJECT_DIR$/.idea/modules//benchmark-micro.iml" filepath="$PROJECT_DIR$/.idea/modules//benchmark-micro.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/elasticsearch.iml" filepath="$PROJECT_DIR$/.idea/modules/elasticsearch.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/elasticsearch-root.iml" filepath="$PROJECT_DIR$/.idea/modules/elasticsearch-root.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules//plugin-attachments.iml" filepath="$PROJECT_DIR$/.idea/modules//plugin-attachments.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules//test-integration.iml" filepath="$PROJECT_DIR$/.idea/modules//test-integration.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules//test-testng.iml" filepath="$PROJECT_DIR$/.idea/modules//test-testng.iml" />
|
||||
</modules>
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="elasticsearch" />
|
||||
<orderEntry type="module" module-name="plugin-attachments" />
|
||||
<orderEntry type="module" module-name="test-integration" />
|
||||
</component>
|
||||
</module>
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/../../plugins/attachments/build/classes/main" />
|
||||
<output-test url="file://$MODULE_DIR$/../../plugins/attachments/build/classes/test" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$/../../plugins/attachments">
|
||||
<sourceFolder url="file://$MODULE_DIR$/../../plugins/attachments/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/../../plugins/attachments/src/test/java" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/../../plugins/attachments/build" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="elasticsearch" />
|
||||
<orderEntry type="library" name="tika" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
<option name="ENABLE_SWING_INSPECTOR" value="false" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<module name="elasticsearch" />
|
||||
<module name="elasticsearch-root" />
|
||||
<envs />
|
||||
<RunnerSettings RunnerId="Debug">
|
||||
<option name="DEBUG_PORT" value="61134" />
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Bootstrap [No Plugins]" type="Application" factoryName="Application">
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea">
|
||||
<pattern>
|
||||
<option name="PATTERN" value="org.elasticsearch.bootstrap.*" />
|
||||
<option name="ENABLED" value="true" />
|
||||
</pattern>
|
||||
</extension>
|
||||
<extension name="snapshooter" />
|
||||
<option name="MAIN_CLASS_NAME" value="org.elasticsearch.bootstrap.Bootstrap" />
|
||||
<option name="VM_PARAMETERS" value="-server -Xmx1g -Des-foreground=yes -Djava.net.preferIPv4Stack=true" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="" />
|
||||
<option name="ENABLE_SWING_INSPECTOR" value="false" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<module name="elasticsearch" />
|
||||
<envs />
|
||||
<RunnerSettings RunnerId="Profile ">
|
||||
<option name="myExternalizedOptions" value=" snapshots-dir= additional-options2=onexit\=snapshot " />
|
||||
</RunnerSettings>
|
||||
<RunnerSettings RunnerId="Run" />
|
||||
<ConfigurationWrapper RunnerId="Run" />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
|
@ -90,7 +90,8 @@ zip.doFirst {task ->
|
|||
}
|
||||
}
|
||||
|
||||
task release(dependsOn: [zip]) {
|
||||
task release(dependsOn: [zip, ":plugins-attachments:release"]) << {
|
||||
ant.delete(dir: explodedDistDir)
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
|
|
|
@ -31,7 +31,9 @@ import static org.elasticsearch.util.Strings.*;
|
|||
import static org.elasticsearch.util.settings.ImmutableSettings.Builder.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
* The environment of where things exists.
|
||||
*
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class Environment {
|
||||
|
||||
|
@ -43,6 +45,8 @@ public class Environment {
|
|||
|
||||
private final File configFile;
|
||||
|
||||
private final File pluginsFile;
|
||||
|
||||
private final File logsFile;
|
||||
|
||||
public Environment() {
|
||||
|
@ -63,6 +67,12 @@ public class Environment {
|
|||
configFile = new File(homeFile, "config");
|
||||
}
|
||||
|
||||
if (settings.get("path.plugins") != null) {
|
||||
pluginsFile = new File(cleanPath(settings.get("path.plugins")));
|
||||
} else {
|
||||
pluginsFile = new File(homeFile, "plugins");
|
||||
}
|
||||
|
||||
if (settings.get("path.work") != null) {
|
||||
workFile = new File(cleanPath(settings.get("path.work")));
|
||||
} else {
|
||||
|
@ -79,18 +89,31 @@ public class Environment {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The home of the installation.
|
||||
*/
|
||||
public File homeFile() {
|
||||
return homeFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* The work location.
|
||||
*/
|
||||
public File workFile() {
|
||||
return workFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* The config location.
|
||||
*/
|
||||
public File configFile() {
|
||||
return configFile;
|
||||
}
|
||||
|
||||
public File pluginsFile() {
|
||||
return pluginsFile;
|
||||
}
|
||||
|
||||
public File workWithClusterFile() {
|
||||
return workWithClusterFile;
|
||||
}
|
||||
|
|
|
@ -25,13 +25,14 @@ import org.elasticsearch.index.settings.IndexSettings;
|
|||
import org.elasticsearch.jmx.JmxService;
|
||||
import org.elasticsearch.jmx.MBean;
|
||||
import org.elasticsearch.jmx.ManagedAttribute;
|
||||
import org.elasticsearch.util.component.CloseableComponent;
|
||||
import org.elasticsearch.util.settings.Settings;
|
||||
|
||||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
*/
|
||||
@MBean(objectName = "", description = "")
|
||||
public class IndexServiceManagement extends AbstractIndexComponent {
|
||||
public class IndexServiceManagement extends AbstractIndexComponent implements CloseableComponent {
|
||||
|
||||
public static String buildIndexGroupName(Index index) {
|
||||
return "service=indices,index=" + index.name();
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.elasticsearch.index.Index;
|
|||
import org.elasticsearch.index.IndexLifecycle;
|
||||
import org.elasticsearch.index.settings.IndexSettings;
|
||||
import org.elasticsearch.util.Nullable;
|
||||
import org.elasticsearch.util.component.CloseableComponent;
|
||||
import org.elasticsearch.util.settings.ImmutableSettings;
|
||||
import org.elasticsearch.util.settings.Settings;
|
||||
|
||||
|
@ -38,7 +39,7 @@ import static com.google.common.collect.Maps.*;
|
|||
* @author kimchy (Shay Banon)
|
||||
*/
|
||||
@IndexLifecycle
|
||||
public class AnalysisService extends AbstractIndexComponent {
|
||||
public class AnalysisService extends AbstractIndexComponent implements CloseableComponent {
|
||||
|
||||
private final ImmutableMap<String, AnalyzerProvider> analyzerProviders;
|
||||
|
||||
|
|
|
@ -21,13 +21,12 @@ package org.elasticsearch.index.cache.filter;
|
|||
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.elasticsearch.index.IndexComponent;
|
||||
import org.elasticsearch.util.component.CloseableComponent;
|
||||
|
||||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
*/
|
||||
public interface FilterCache extends IndexComponent {
|
||||
public interface FilterCache extends IndexComponent, CloseableComponent {
|
||||
|
||||
Filter cache(Filter filterToCache);
|
||||
|
||||
void close();
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.elasticsearch.index.shard.IndexShardLifecycle;
|
|||
import org.elasticsearch.index.translog.Translog;
|
||||
import org.elasticsearch.util.Nullable;
|
||||
import org.elasticsearch.util.SizeValue;
|
||||
import org.elasticsearch.util.component.CloseableComponent;
|
||||
import org.elasticsearch.util.concurrent.ThreadSafe;
|
||||
import org.elasticsearch.util.lease.Releasable;
|
||||
|
||||
|
@ -40,7 +41,7 @@ import org.elasticsearch.util.lease.Releasable;
|
|||
*/
|
||||
@ThreadSafe
|
||||
@IndexShardLifecycle
|
||||
public interface Engine extends IndexShardComponent {
|
||||
public interface Engine extends IndexShardComponent, CloseableComponent {
|
||||
|
||||
/**
|
||||
* Starts the Engine.
|
||||
|
@ -83,8 +84,6 @@ public interface Engine extends IndexShardComponent {
|
|||
*/
|
||||
SizeValue estimateFlushableMemorySize();
|
||||
|
||||
void close() throws ElasticSearchException;
|
||||
|
||||
/**
|
||||
* Recovery allow to start the recovery process. It is built of three phases.
|
||||
*
|
||||
|
|
|
@ -20,11 +20,12 @@
|
|||
package org.elasticsearch.index.gateway;
|
||||
|
||||
import org.elasticsearch.index.IndexComponent;
|
||||
import org.elasticsearch.util.component.CloseableComponent;
|
||||
|
||||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
*/
|
||||
public interface IndexGateway extends IndexComponent {
|
||||
public interface IndexGateway extends IndexComponent, CloseableComponent {
|
||||
|
||||
Class<? extends IndexShardGateway> shardGatewayClass();
|
||||
|
||||
|
@ -32,9 +33,4 @@ public interface IndexGateway extends IndexComponent {
|
|||
* Deletes the content of the index gateway.
|
||||
*/
|
||||
void delete();
|
||||
|
||||
/**
|
||||
* Closes the index gateway.
|
||||
*/
|
||||
void close();
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.elasticsearch.index.translog.Translog;
|
|||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.util.StopWatch;
|
||||
import org.elasticsearch.util.TimeValue;
|
||||
import org.elasticsearch.util.component.CloseableComponent;
|
||||
import org.elasticsearch.util.settings.Settings;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -45,7 +46,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
*/
|
||||
public class IndexShardGatewayService extends AbstractIndexShardComponent {
|
||||
public class IndexShardGatewayService extends AbstractIndexShardComponent implements CloseableComponent {
|
||||
|
||||
private final boolean snapshotOnClose;
|
||||
|
||||
|
|
|
@ -47,6 +47,9 @@ import org.elasticsearch.index.similarity.SimilarityService;
|
|||
import org.elasticsearch.index.store.Store;
|
||||
import org.elasticsearch.index.store.StoreModule;
|
||||
import org.elasticsearch.index.translog.TranslogModule;
|
||||
import org.elasticsearch.plugins.PluginsService;
|
||||
import org.elasticsearch.plugins.ShardsPluginsModule;
|
||||
import org.elasticsearch.util.component.CloseableComponent;
|
||||
import org.elasticsearch.util.guice.Injectors;
|
||||
import org.elasticsearch.util.settings.Settings;
|
||||
|
||||
|
@ -68,6 +71,8 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
|
|||
|
||||
private final Settings indexSettings;
|
||||
|
||||
private final PluginsService pluginsService;
|
||||
|
||||
private final MapperService mapperService;
|
||||
|
||||
private final IndexQueryParserService queryParserService;
|
||||
|
@ -93,6 +98,8 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
|
|||
this.similarityService = similarityService;
|
||||
this.filterCache = filterCache;
|
||||
this.operationRouting = operationRouting;
|
||||
|
||||
this.pluginsService = injector.getInstance(PluginsService.class);
|
||||
}
|
||||
|
||||
@Override public int numberOfShards() {
|
||||
|
@ -174,6 +181,7 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
|
|||
logger.debug("Creating Shard Id [{}]", shardId.id());
|
||||
|
||||
Injector shardInjector = injector.createChildInjector(
|
||||
new ShardsPluginsModule(indexSettings, pluginsService),
|
||||
new IndexShardModule(shardId),
|
||||
new StoreModule(indexSettings),
|
||||
new DeletionPolicyModule(indexSettings),
|
||||
|
@ -222,6 +230,11 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
|
|||
IndexShard indexShard = tmpShardsMap.remove(shardId);
|
||||
shards = ImmutableMap.copyOf(tmpShardsMap);
|
||||
|
||||
|
||||
for (Class<? extends CloseableComponent> closeable : pluginsService.shardServices()) {
|
||||
shardInjector.getInstance(closeable).close();
|
||||
}
|
||||
|
||||
// close shard actions
|
||||
shardInjector.getInstance(IndexShardManagement.class).close();
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.elasticsearch.index.translog.Translog;
|
|||
import org.elasticsearch.jmx.JmxService;
|
||||
import org.elasticsearch.jmx.MBean;
|
||||
import org.elasticsearch.jmx.ManagedAttribute;
|
||||
import org.elasticsearch.util.component.CloseableComponent;
|
||||
import org.elasticsearch.util.settings.Settings;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -38,7 +39,7 @@ import static org.elasticsearch.index.IndexServiceManagement.*;
|
|||
* @author kimchy (Shay Banon)
|
||||
*/
|
||||
@MBean(objectName = "", description = "")
|
||||
public class IndexShardManagement extends AbstractIndexShardComponent {
|
||||
public class IndexShardManagement extends AbstractIndexShardComponent implements CloseableComponent {
|
||||
|
||||
public static String buildShardGroupName(ShardId shardId) {
|
||||
return buildIndexGroupName(shardId.index()) + ",subService=shards,shard=" + shardId.id();
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.elasticsearch.util.SizeUnit;
|
|||
import org.elasticsearch.util.SizeValue;
|
||||
import org.elasticsearch.util.StopWatch;
|
||||
import org.elasticsearch.util.TimeValue;
|
||||
import org.elasticsearch.util.component.CloseableComponent;
|
||||
import org.elasticsearch.util.io.VoidStreamable;
|
||||
import org.elasticsearch.util.io.stream.StreamInput;
|
||||
import org.elasticsearch.util.io.stream.StreamOutput;
|
||||
|
@ -63,7 +64,7 @@ import static org.elasticsearch.util.concurrent.ConcurrentMaps.*;
|
|||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class RecoveryAction extends AbstractIndexShardComponent {
|
||||
public class RecoveryAction extends AbstractIndexShardComponent implements CloseableComponent {
|
||||
|
||||
private final SizeValue fileChunkSize;
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.elasticsearch.index.shard.IndexShardLifecycle;
|
|||
import org.elasticsearch.index.shard.IndexShardState;
|
||||
import org.elasticsearch.util.Nullable;
|
||||
import org.elasticsearch.util.SizeValue;
|
||||
import org.elasticsearch.util.component.CloseableComponent;
|
||||
import org.elasticsearch.util.concurrent.ThreadSafe;
|
||||
|
||||
/**
|
||||
|
@ -37,7 +38,7 @@ import org.elasticsearch.util.concurrent.ThreadSafe;
|
|||
*/
|
||||
@IndexShardLifecycle
|
||||
@ThreadSafe
|
||||
public interface IndexShard extends IndexShardComponent {
|
||||
public interface IndexShard extends IndexShardComponent, CloseableComponent {
|
||||
|
||||
ShardRouting routingEntry();
|
||||
|
||||
|
@ -74,8 +75,6 @@ public interface IndexShard extends IndexShardComponent {
|
|||
|
||||
Engine.Searcher searcher();
|
||||
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this shard can ignore a recovery attempt made to it (since the already doing/done it)
|
||||
*/
|
||||
|
|
|
@ -41,7 +41,10 @@ import org.elasticsearch.index.service.IndexService;
|
|||
import org.elasticsearch.index.settings.IndexSettingsModule;
|
||||
import org.elasticsearch.index.similarity.SimilarityModule;
|
||||
import org.elasticsearch.indices.cluster.IndicesClusterStateService;
|
||||
import org.elasticsearch.plugins.IndicesPluginsModule;
|
||||
import org.elasticsearch.plugins.PluginsService;
|
||||
import org.elasticsearch.util.component.AbstractLifecycleComponent;
|
||||
import org.elasticsearch.util.component.CloseableComponent;
|
||||
import org.elasticsearch.util.concurrent.ThreadSafe;
|
||||
import org.elasticsearch.util.guice.Injectors;
|
||||
import org.elasticsearch.util.settings.Settings;
|
||||
|
@ -66,6 +69,8 @@ public class InternalIndicesService extends AbstractLifecycleComponent<IndicesSe
|
|||
|
||||
private final Injector injector;
|
||||
|
||||
private final PluginsService pluginsService;
|
||||
|
||||
private final Map<String, Injector> indicesInjectors = new HashMap<String, Injector>();
|
||||
|
||||
private volatile ImmutableMap<String, IndexService> indices = ImmutableMap.of();
|
||||
|
@ -74,6 +79,8 @@ public class InternalIndicesService extends AbstractLifecycleComponent<IndicesSe
|
|||
super(settings);
|
||||
this.clusterStateService = clusterStateService;
|
||||
this.injector = injector;
|
||||
|
||||
this.pluginsService = injector.getInstance(PluginsService.class);
|
||||
}
|
||||
|
||||
@Override protected void doStart() throws ElasticSearchException {
|
||||
|
@ -155,6 +162,7 @@ public class InternalIndicesService extends AbstractLifecycleComponent<IndicesSe
|
|||
new IndexNameModule(index),
|
||||
new LocalNodeIdModule(localNodeId),
|
||||
new IndexSettingsModule(indexSettings),
|
||||
new IndicesPluginsModule(indexSettings, pluginsService),
|
||||
new AnalysisModule(indexSettings),
|
||||
new SimilarityModule(indexSettings),
|
||||
new FilterCacheModule(indexSettings),
|
||||
|
@ -193,6 +201,10 @@ public class InternalIndicesService extends AbstractLifecycleComponent<IndicesSe
|
|||
IndexService indexService = tmpMap.remove(index);
|
||||
indices = ImmutableMap.copyOf(tmpMap);
|
||||
|
||||
for (Class<? extends CloseableComponent> closeable : pluginsService.indexServices()) {
|
||||
indexInjector.getInstance(closeable).close();
|
||||
}
|
||||
|
||||
indexService.close();
|
||||
|
||||
indexInjector.getInstance(FilterCache.class).close();
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.elasticsearch.plugins;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.inject.Module;
|
||||
import org.elasticsearch.util.component.CloseableComponent;
|
||||
import org.elasticsearch.util.component.LifecycleComponent;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public abstract class AbstractPlugin implements Plugin {
|
||||
|
||||
@Override public Collection<Class<? extends Module>> modules() {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
@Override public Collection<Class<? extends LifecycleComponent>> services() {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
@Override public Collection<Class<? extends Module>> indexModules() {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
@Override public Collection<Class<? extends CloseableComponent>> indexServices() {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
@Override public Collection<Class<? extends Module>> shardModules() {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
@Override public Collection<Class<? extends CloseableComponent>> shardServices() {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.elasticsearch.plugins;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Module;
|
||||
import org.elasticsearch.util.settings.Settings;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.elasticsearch.util.guice.ModulesFactory.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class IndicesPluginsModule extends AbstractModule {
|
||||
|
||||
private final Settings settings;
|
||||
|
||||
private final PluginsService pluginsService;
|
||||
|
||||
public IndicesPluginsModule(Settings settings, PluginsService pluginsService) {
|
||||
this.settings = settings;
|
||||
this.pluginsService = pluginsService;
|
||||
}
|
||||
|
||||
@Override protected void configure() {
|
||||
Collection<Class<? extends Module>> modules = pluginsService.indexModules();
|
||||
for (Class<? extends Module> module : modules) {
|
||||
createModule(module, settings).configure(binder());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.elasticsearch.plugins;
|
||||
|
||||
import com.google.inject.Module;
|
||||
import org.elasticsearch.util.component.CloseableComponent;
|
||||
import org.elasticsearch.util.component.LifecycleComponent;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public interface Plugin {
|
||||
|
||||
String name();
|
||||
|
||||
Collection<Class<? extends Module>> modules();
|
||||
|
||||
Collection<Class<? extends LifecycleComponent>> services();
|
||||
|
||||
Collection<Class<? extends Module>> indexModules();
|
||||
|
||||
Collection<Class<? extends CloseableComponent>> indexServices();
|
||||
|
||||
Collection<Class<? extends Module>> shardModules();
|
||||
|
||||
Collection<Class<? extends CloseableComponent>> shardServices();
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.elasticsearch.plugins;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Module;
|
||||
import org.elasticsearch.util.settings.Settings;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.elasticsearch.util.guice.ModulesFactory.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class PluginsModule extends AbstractModule {
|
||||
|
||||
private final Settings settings;
|
||||
|
||||
private final PluginsService pluginsService;
|
||||
|
||||
public PluginsModule(Settings settings, PluginsService pluginsService) {
|
||||
this.settings = settings;
|
||||
this.pluginsService = pluginsService;
|
||||
}
|
||||
|
||||
@Override protected void configure() {
|
||||
bind(PluginsService.class).toInstance(pluginsService);
|
||||
|
||||
Collection<Class<? extends Module>> modules = pluginsService.modules();
|
||||
for (Class<? extends Module> module : modules) {
|
||||
createModule(module, settings).configure(binder());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.elasticsearch.plugins;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Module;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.util.component.AbstractComponent;
|
||||
import org.elasticsearch.util.component.CloseableComponent;
|
||||
import org.elasticsearch.util.component.LifecycleComponent;
|
||||
import org.elasticsearch.util.io.Streams;
|
||||
import org.elasticsearch.util.settings.Settings;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import static com.google.common.collect.Maps.*;
|
||||
import static org.elasticsearch.util.io.FileSystemUtils.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class PluginsService extends AbstractComponent {
|
||||
|
||||
private final Environment environment;
|
||||
|
||||
private final ImmutableMap<String, Plugin> plugins;
|
||||
|
||||
@Inject public PluginsService(Settings settings, Environment environment) {
|
||||
super(settings);
|
||||
this.environment = environment;
|
||||
|
||||
loadPluginsIntoClassLoader();
|
||||
|
||||
// first, find all the ones that are in the classpath
|
||||
Map<String, Plugin> plugins = Maps.newHashMap();
|
||||
plugins.putAll(loadPluginsFromClasspath(settings));
|
||||
|
||||
logger.info("Loaded {}", plugins.keySet());
|
||||
|
||||
this.plugins = ImmutableMap.copyOf(plugins);
|
||||
}
|
||||
|
||||
public Settings updatedSettings() {
|
||||
return this.settings;
|
||||
}
|
||||
|
||||
public Collection<Class<? extends Module>> modules() {
|
||||
List<Class<? extends Module>> modules = Lists.newArrayList();
|
||||
for (Plugin plugin : plugins.values()) {
|
||||
modules.addAll(plugin.modules());
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
|
||||
public Collection<Class<? extends LifecycleComponent>> services() {
|
||||
List<Class<? extends LifecycleComponent>> services = Lists.newArrayList();
|
||||
for (Plugin plugin : plugins.values()) {
|
||||
services.addAll(plugin.services());
|
||||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
public Collection<Class<? extends Module>> indexModules() {
|
||||
List<Class<? extends Module>> modules = Lists.newArrayList();
|
||||
for (Plugin plugin : plugins.values()) {
|
||||
modules.addAll(plugin.indexModules());
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
|
||||
public Collection<Class<? extends CloseableComponent>> indexServices() {
|
||||
List<Class<? extends CloseableComponent>> services = Lists.newArrayList();
|
||||
for (Plugin plugin : plugins.values()) {
|
||||
services.addAll(plugin.indexServices());
|
||||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
public Collection<Class<? extends Module>> shardModules() {
|
||||
List<Class<? extends Module>> modules = Lists.newArrayList();
|
||||
for (Plugin plugin : plugins.values()) {
|
||||
modules.addAll(plugin.shardModules());
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
|
||||
public Collection<Class<? extends CloseableComponent>> shardServices() {
|
||||
List<Class<? extends CloseableComponent>> services = Lists.newArrayList();
|
||||
for (Plugin plugin : plugins.values()) {
|
||||
services.addAll(plugin.shardServices());
|
||||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
private void loadPluginsIntoClassLoader() {
|
||||
File pluginsFile = environment.pluginsFile();
|
||||
if (!pluginsFile.exists()) {
|
||||
return;
|
||||
}
|
||||
if (!pluginsFile.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ClassLoader classLoader = settings.getClassLoader();
|
||||
Class classLoaderClass = classLoader.getClass();
|
||||
Method addURL = null;
|
||||
while (!classLoaderClass.equals(Object.class)) {
|
||||
try {
|
||||
addURL = classLoaderClass.getDeclaredMethod("addURL", URL.class);
|
||||
addURL.setAccessible(true);
|
||||
break;
|
||||
} catch (NoSuchMethodException e) {
|
||||
// no method, try the parent
|
||||
classLoaderClass = classLoaderClass.getSuperclass();
|
||||
}
|
||||
}
|
||||
if (addURL == null) {
|
||||
logger.debug("Failed to find addURL method on classLoader [" + classLoader + "] to add methods");
|
||||
return;
|
||||
}
|
||||
|
||||
File[] pluginsFiles = pluginsFile.listFiles();
|
||||
for (File pluginFile : pluginsFiles) {
|
||||
if (!pluginFile.getName().endsWith(".zip")) {
|
||||
continue;
|
||||
}
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Processing [{}]", pluginFile);
|
||||
}
|
||||
|
||||
String pluginNameNoExtension = pluginFile.getName().substring(0, pluginFile.getName().lastIndexOf('.'));
|
||||
File extractedPluginDir = new File(new File(environment.workFile(), "plugins"), pluginNameNoExtension);
|
||||
extractedPluginDir.mkdirs();
|
||||
|
||||
File stampsDir = new File(new File(environment.workFile(), "plugins"), "_stamps");
|
||||
stampsDir.mkdirs();
|
||||
|
||||
boolean extractPlugin = true;
|
||||
File stampFile = new File(stampsDir, pluginNameNoExtension + ".stamp");
|
||||
if (stampFile.exists()) {
|
||||
// read it, and check if its the same size as the pluginFile
|
||||
RandomAccessFile raf = null;
|
||||
try {
|
||||
raf = new RandomAccessFile(stampFile, "r");
|
||||
long size = raf.readLong();
|
||||
if (size == pluginFile.length()) {
|
||||
extractPlugin = false;
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("--- No need to extract plugin, same size [" + size + "]");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// ignore and extract the plugin
|
||||
} finally {
|
||||
if (raf != null) {
|
||||
try {
|
||||
raf.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (extractPlugin) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("--- Extracting plugin to [" + extractedPluginDir + "]");
|
||||
}
|
||||
deleteRecursively(extractedPluginDir, false);
|
||||
|
||||
ZipFile zipFile = null;
|
||||
try {
|
||||
zipFile = new ZipFile(pluginFile);
|
||||
Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
|
||||
while (zipEntries.hasMoreElements()) {
|
||||
ZipEntry zipEntry = zipEntries.nextElement();
|
||||
if (!(zipEntry.getName().endsWith(".jar") || zipEntry.getName().endsWith(".zip"))) {
|
||||
continue;
|
||||
}
|
||||
String name = zipEntry.getName().replace('\\', '/');
|
||||
File target = new File(extractedPluginDir, name);
|
||||
Streams.copy(zipFile.getInputStream(zipEntry), new FileOutputStream(target));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to extract plugin [" + pluginFile + "], ignoring...", e);
|
||||
continue;
|
||||
} finally {
|
||||
if (zipFile != null) {
|
||||
try {
|
||||
zipFile.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
RandomAccessFile raf = new RandomAccessFile(stampFile, "rw");
|
||||
raf.writeLong(pluginFile.length());
|
||||
raf.close();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
for (File jarToAdd : extractedPluginDir.listFiles()) {
|
||||
if (!(jarToAdd.getName().endsWith(".jar") || jarToAdd.getName().endsWith(".zip"))) {
|
||||
continue;
|
||||
}
|
||||
addURL.invoke(classLoader, jarToAdd.toURI().toURL());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to add plugin [" + pluginFile + "]", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Plugin> loadPluginsFromClasspath(Settings settings) {
|
||||
Map<String, Plugin> plugins = newHashMap();
|
||||
Enumeration<URL> pluginUrls = null;
|
||||
try {
|
||||
pluginUrls = settings.getClassLoader().getResources("es-plugin.properties");
|
||||
} catch (IOException e) {
|
||||
logger.warn("Failed to find plugins from classpath", e);
|
||||
}
|
||||
while (pluginUrls.hasMoreElements()) {
|
||||
URL pluginUrl = pluginUrls.nextElement();
|
||||
Properties pluginProps = new Properties();
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = pluginUrl.openStream();
|
||||
pluginProps.load(is);
|
||||
String sPluginClass = pluginProps.getProperty("plugin");
|
||||
Class<?> pluginClass = settings.getClassLoader().loadClass(sPluginClass);
|
||||
Plugin plugin = (Plugin) pluginClass.newInstance();
|
||||
plugins.put(plugin.name(), plugin);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to load plugin from [" + pluginUrl + "]", e);
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return plugins;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.elasticsearch.plugins;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Module;
|
||||
import org.elasticsearch.util.settings.Settings;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.elasticsearch.util.guice.ModulesFactory.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class ShardsPluginsModule extends AbstractModule {
|
||||
|
||||
private final Settings settings;
|
||||
|
||||
private final PluginsService pluginsService;
|
||||
|
||||
public ShardsPluginsModule(Settings settings, PluginsService pluginsService) {
|
||||
this.settings = settings;
|
||||
this.pluginsService = pluginsService;
|
||||
}
|
||||
|
||||
@Override protected void configure() {
|
||||
Collection<Class<? extends Module>> modules = pluginsService.shardModules();
|
||||
for (Class<? extends Module> module : modules) {
|
||||
createModule(module, settings).configure(binder());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -46,6 +46,8 @@ import org.elasticsearch.jmx.JmxModule;
|
|||
import org.elasticsearch.jmx.JmxService;
|
||||
import org.elasticsearch.monitor.MonitorModule;
|
||||
import org.elasticsearch.monitor.MonitorService;
|
||||
import org.elasticsearch.plugins.PluginsModule;
|
||||
import org.elasticsearch.plugins.PluginsService;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestModule;
|
||||
import org.elasticsearch.search.SearchModule;
|
||||
|
@ -60,6 +62,7 @@ import org.elasticsearch.transport.TransportService;
|
|||
import org.elasticsearch.util.ThreadLocals;
|
||||
import org.elasticsearch.util.Tuple;
|
||||
import org.elasticsearch.util.component.Lifecycle;
|
||||
import org.elasticsearch.util.component.LifecycleComponent;
|
||||
import org.elasticsearch.util.guice.Injectors;
|
||||
import org.elasticsearch.util.io.FileSystemUtils;
|
||||
import org.elasticsearch.util.logging.Loggers;
|
||||
|
@ -86,6 +89,8 @@ public final class InternalServer implements Server {
|
|||
|
||||
private final Environment environment;
|
||||
|
||||
private final PluginsService pluginsService;
|
||||
|
||||
private final Client client;
|
||||
|
||||
public InternalServer() throws ElasticSearchException {
|
||||
|
@ -94,13 +99,16 @@ public final class InternalServer implements Server {
|
|||
|
||||
public InternalServer(Settings pSettings, boolean loadConfigSettings) throws ElasticSearchException {
|
||||
Tuple<Settings, Environment> tuple = InternalSettingsPerparer.prepareSettings(pSettings, loadConfigSettings);
|
||||
this.settings = tuple.v1();
|
||||
this.environment = tuple.v2();
|
||||
|
||||
Logger logger = Loggers.getLogger(Server.class, settings.get("name"));
|
||||
Logger logger = Loggers.getLogger(Server.class, tuple.v1().get("name"));
|
||||
logger.info("{{}}: Initializing ...", Version.full());
|
||||
|
||||
this.pluginsService = new PluginsService(tuple.v1(), tuple.v2());
|
||||
this.settings = pluginsService.updatedSettings();
|
||||
this.environment = tuple.v2();
|
||||
|
||||
ArrayList<Module> modules = new ArrayList<Module>();
|
||||
modules.add(new PluginsModule(settings, pluginsService));
|
||||
modules.add(new ServerModule(this));
|
||||
modules.add(new JmxModule(settings));
|
||||
modules.add(new EnvironmentModule(environment));
|
||||
|
@ -146,6 +154,10 @@ public final class InternalServer implements Server {
|
|||
Logger logger = Loggers.getLogger(Server.class, settings.get("name"));
|
||||
logger.info("{{}}: Starting ...", Version.full());
|
||||
|
||||
for (Class<? extends LifecycleComponent> plugin : pluginsService.services()) {
|
||||
injector.getInstance(plugin).start();
|
||||
}
|
||||
|
||||
injector.getInstance(IndicesService.class).start();
|
||||
injector.getInstance(GatewayService.class).start();
|
||||
injector.getInstance(ClusterService.class).start();
|
||||
|
@ -186,6 +198,10 @@ public final class InternalServer implements Server {
|
|||
injector.getInstance(TransportService.class).stop();
|
||||
injector.getInstance(JmxService.class).close();
|
||||
|
||||
for (Class<? extends LifecycleComponent> plugin : pluginsService.services()) {
|
||||
injector.getInstance(plugin).stop();
|
||||
}
|
||||
|
||||
// Not pretty, but here we go
|
||||
try {
|
||||
FileSystemUtils.deleteRecursively(new File(new File(environment.workWithClusterFile(), FsStores.DEFAULT_INDICES_LOCATION),
|
||||
|
@ -226,6 +242,10 @@ public final class InternalServer implements Server {
|
|||
injector.getInstance(RestController.class).close();
|
||||
injector.getInstance(TransportService.class).close();
|
||||
|
||||
for (Class<? extends LifecycleComponent> plugin : pluginsService.services()) {
|
||||
injector.getInstance(plugin).close();
|
||||
}
|
||||
|
||||
injector.getInstance(TimerService.class).close();
|
||||
injector.getInstance(ThreadPool.class).shutdown();
|
||||
try {
|
||||
|
|
|
@ -22,6 +22,9 @@ package org.elasticsearch.util.component;
|
|||
import org.elasticsearch.ElasticSearchException;
|
||||
import org.elasticsearch.util.settings.Settings;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
|
@ -29,6 +32,8 @@ public abstract class AbstractLifecycleComponent<T> extends AbstractComponent im
|
|||
|
||||
protected final Lifecycle lifecycle = new Lifecycle();
|
||||
|
||||
private final List<LifecycleListener> listeners = new CopyOnWriteArrayList<LifecycleListener>();
|
||||
|
||||
protected AbstractLifecycleComponent(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
@ -45,11 +50,25 @@ public abstract class AbstractLifecycleComponent<T> extends AbstractComponent im
|
|||
return this.lifecycle.state();
|
||||
}
|
||||
|
||||
@Override public void addLifecycleListener(LifecycleListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override public void removeLifecycleListener(LifecycleListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"}) @Override public T start() throws ElasticSearchException {
|
||||
if (!lifecycle.moveToStarted()) {
|
||||
return (T) this;
|
||||
}
|
||||
for (LifecycleListener listener : listeners) {
|
||||
listener.beforeStart();
|
||||
}
|
||||
doStart();
|
||||
for (LifecycleListener listener : listeners) {
|
||||
listener.afterStart();
|
||||
}
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
|
@ -59,7 +78,13 @@ public abstract class AbstractLifecycleComponent<T> extends AbstractComponent im
|
|||
if (!lifecycle.moveToStopped()) {
|
||||
return (T) this;
|
||||
}
|
||||
for (LifecycleListener listener : listeners) {
|
||||
listener.beforeStop();
|
||||
}
|
||||
doStop();
|
||||
for (LifecycleListener listener : listeners) {
|
||||
listener.afterStop();
|
||||
}
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
|
@ -72,7 +97,13 @@ public abstract class AbstractLifecycleComponent<T> extends AbstractComponent im
|
|||
if (!lifecycle.moveToClosed()) {
|
||||
return;
|
||||
}
|
||||
for (LifecycleListener listener : listeners) {
|
||||
listener.beforeClose();
|
||||
}
|
||||
doClose();
|
||||
for (LifecycleListener listener : listeners) {
|
||||
listener.afterClose();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void doClose() throws ElasticSearchException;
|
||||
|
|
|
@ -28,6 +28,10 @@ public interface LifecycleComponent<T> extends CloseableComponent {
|
|||
|
||||
Lifecycle.State lifecycleState();
|
||||
|
||||
void addLifecycleListener(LifecycleListener listener);
|
||||
|
||||
void removeLifecycleListener(LifecycleListener listener);
|
||||
|
||||
T start() throws ElasticSearchException;
|
||||
|
||||
T stop() throws ElasticSearchException;
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.elasticsearch.util.component;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public interface LifecycleListener {
|
||||
|
||||
void beforeStart();
|
||||
|
||||
void afterStart();
|
||||
|
||||
void beforeStop();
|
||||
|
||||
void afterStop();
|
||||
|
||||
void beforeClose();
|
||||
|
||||
void afterClose();
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
dependsOn(':elasticsearch')
|
||||
|
||||
usePlugin 'java'
|
||||
|
||||
archivesBaseName = "elasticsearch-attachments"
|
||||
|
||||
explodedDistDir = new File(distsDir, 'exploded')
|
||||
|
||||
manifest.mainAttributes("Implementation-Title": "ElasticSearch::Plugins::Attachments", "Implementation-Version": rootProject.version, "Implementation-Date": buildTimeStr)
|
||||
|
||||
// no need to use the resource dir
|
||||
sourceSets.main.resources.srcDir 'src/main/java'
|
||||
sourceSets.test.resources.srcDir 'src/test/java'
|
||||
|
||||
dependencies {
|
||||
compile project(':elasticsearch')
|
||||
|
||||
compile('org.apache.tika:tika-app:0.6') { transitive = false }
|
||||
|
||||
|
||||
testCompile project(':test-testng')
|
||||
testCompile('org.testng:testng:5.10:jdk15') { transitive = false }
|
||||
testCompile 'org.hamcrest:hamcrest-all:1.1'
|
||||
}
|
||||
|
||||
test {
|
||||
useTestNG()
|
||||
jmvArgs = ["-ea", "-Xmx1024m"]
|
||||
options.suiteName = project.name
|
||||
options.listeners = ["org.elasticsearch.util.testng.Listeners"]
|
||||
options.systemProperties = [
|
||||
"es.test.log.conf": System.getProperty("es.test.log.conf", "log4j-gradle.properties")
|
||||
]
|
||||
}
|
||||
|
||||
task explodedDist(dependsOn: [jar], description: 'Builds the plugin zip file') << {
|
||||
[explodedDistDir]*.mkdirs()
|
||||
|
||||
copy {
|
||||
from configurations.compile
|
||||
into explodedDistDir
|
||||
}
|
||||
|
||||
// remove elasticsearch files (compile above adds the elasticsearch one)
|
||||
ant.delete { fileset(dir: explodedDistDir, includes: "elasticsearch-*.jar") }
|
||||
|
||||
copy {
|
||||
from libsDir
|
||||
into explodedDistDir
|
||||
}
|
||||
}
|
||||
|
||||
task zip(type: Zip) {
|
||||
dependsOn explodedDist
|
||||
// classifier = 'all'
|
||||
}
|
||||
|
||||
zip.doFirst {task ->
|
||||
zipRootFolder = "" // its the plugin, don't create it under a specific name
|
||||
task.configure {
|
||||
zipFileSet(dir: explodedDistDir, prefix: zipRootFolder) {
|
||||
// just copy over everything
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task release(dependsOn: [zip]) << {
|
||||
ant.delete(dir: explodedDistDir)
|
||||
copy {
|
||||
from distsDir
|
||||
into(new File(rootProject.distsDir, "plugins"))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
plugin=org.elasticsearch.plugin.attachments.AttachmentsPlugin
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search 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.elasticsearch.plugin.attachments;
|
||||
|
||||
import org.elasticsearch.plugins.AbstractPlugin;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class AttachmentsPlugin extends AbstractPlugin {
|
||||
|
||||
@Override public String name() {
|
||||
return "attachments";
|
||||
}
|
||||
}
|
|
@ -6,9 +6,15 @@ include 'test-integration'
|
|||
|
||||
include 'benchmark-micro'
|
||||
|
||||
include 'plugins-attachments'
|
||||
|
||||
rootProject.name = 'elasticsearch-root'
|
||||
rootProject.children.each {project ->
|
||||
String fileBaseName = project.name.replaceAll("\\p{Upper}") { "-${it.toLowerCase()}" }
|
||||
fileBaseName = fileBaseName.replace('-', '/');
|
||||
project.projectDir = new File(settingsDir, "modules/$fileBaseName")
|
||||
if (fileBaseName.startsWith("plugins")) {
|
||||
project.projectDir = new File(settingsDir, "$fileBaseName")
|
||||
} else {
|
||||
project.projectDir = new File(settingsDir, "modules/$fileBaseName")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue