diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/client/node/NodeClientModule.java b/modules/elasticsearch/src/main/java/org/elasticsearch/client/node/NodeClientModule.java index d794bbb06805c..0191582332e3d 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/client/node/NodeClientModule.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/client/node/NodeClientModule.java @@ -24,16 +24,22 @@ import org.elasticsearch.client.ClusterAdminClient; import org.elasticsearch.client.IndicesAdminClient; import org.elasticsearch.common.inject.AbstractModule; +import org.elasticsearch.common.settings.Settings; /** * @author kimchy (shay.banon) */ public class NodeClientModule extends AbstractModule { + private final Settings settings; + + public NodeClientModule(Settings settings) { + this.settings = settings; + } @Override protected void configure() { bind(ClusterAdminClient.class).to(NodeClusterAdminClient.class).asEagerSingleton(); bind(IndicesAdminClient.class).to(NodeIndicesAdminClient.class).asEagerSingleton(); bind(AdminClient.class).to(NodeAdminClient.class).asEagerSingleton(); - bind(Client.class).to(NodeClient.class).asEagerSingleton(); + bind(Client.class).to(settings.getAsClass("client.type", NodeClient.class, "org.elasticsearch.client.node", "Client")).asEagerSingleton(); } } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/node/internal/InternalNode.java b/modules/elasticsearch/src/main/java/org/elasticsearch/node/internal/InternalNode.java index 1ad219befd26f..24cedc9212d99 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/node/internal/InternalNode.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/node/internal/InternalNode.java @@ -141,7 +141,7 @@ public InternalNode(Settings pSettings, boolean loadConfigSettings) throws Elast modules.add(new TransportActionModule()); modules.add(new MonitorModule(settings)); modules.add(new GatewayModule(settings)); - modules.add(new NodeClientModule()); + modules.add(new NodeClientModule(settings)); injector = modules.createInjector(); @@ -320,4 +320,4 @@ public static void main(String[] args) throws Exception { } }); } -} \ No newline at end of file +} diff --git a/plugins/client/lru/build.gradle b/plugins/client/lru/build.gradle new file mode 100644 index 0000000000000..295abe7d869f9 --- /dev/null +++ b/plugins/client/lru/build.gradle @@ -0,0 +1,136 @@ +dependsOn(':elasticsearch') + +apply plugin: 'java' +apply plugin: 'maven' + +archivesBaseName = "elasticsearch-client-lru" + +explodedDistDir = new File(distsDir, 'exploded') + +manifest.mainAttributes("Implementation-Title": "ElasticSearch::Plugins::LruClient", "Implementation-Version": rootProject.version, "Implementation-Date": buildTimeStr) + +configurations.compile.transitive = true +configurations.testCompile.transitive = true + +// no need to use the resource dir +sourceSets.main.resources.srcDirs 'src/main/java' +sourceSets.test.resources.srcDirs 'src/test/java' + +// add the source files to the dist jar +//jar { +// from sourceSets.main.allJava +//} + +configurations { + dists + distLib { + visible = false + transitive = false + } +} + +dependencies { + compile project(':elasticsearch') + + 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"] + //suiteName = project.name + //listeners = ["org.elasticsearch.util.testng.Listeners"] + //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.distLib + into explodedDistDir + } + + // remove elasticsearch files (compile above adds the elasticsearch one) + ant.delete { fileset(dir: explodedDistDir, includes: "elasticsearch-*.jar") } + + copy { + from libsDir + into explodedDistDir + } + + ant.delete { fileset(dir: explodedDistDir, includes: "elasticsearch-*-javadoc.jar") } + ant.delete { fileset(dir: explodedDistDir, includes: "elasticsearch-*-sources.jar") } +} + +task zip(type: Zip, dependsOn: ['explodedDist']) { + from(explodedDistDir) { + } +} + +task release(dependsOn: [zip]) << { + ant.delete(dir: explodedDistDir) + copy { + from distsDir + into(new File(rootProject.distsDir, "plugins")) + } +} + +configurations { + deployerJars +} + +dependencies { + deployerJars "org.apache.maven.wagon:wagon-http:1.0-beta-2" +} + +task sourcesJar(type: Jar, dependsOn: classes) { + classifier = 'sources' + from sourceSets.main.allSource +} + +task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from javadoc.destinationDir +} + +artifacts { + archives sourcesJar + archives javadocJar +} + +uploadArchives { + repositories.mavenDeployer { + configuration = configurations.deployerJars + repository(url: rootProject.mavenRepoUrl) { + authentication(userName: rootProject.mavenRepoUser, password: rootProject.mavenRepoPass) + } + snapshotRepository(url: rootProject.mavenSnapshotRepoUrl) { + authentication(userName: rootProject.mavenRepoUser, password: rootProject.mavenRepoPass) + } + + pom.project { + inceptionYear '2010' + name 'elasticsearch-plugins-lruclient' + description 'Lru Client Plugin for ElasticSearch' + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + scm { + connection 'git://github.com/elasticsearch/elasticsearch.git' + developerConnection 'git@github.com:elasticsearch/elasticsearch.git' + url 'http://github.com/elasticsearch/elasticsearch' + } + } + + pom.whenConfigured {pom -> + pom.dependencies = pom.dependencies.findAll {dep -> dep.scope != 'test' } // removes the test scoped ones + } + } +} diff --git a/plugins/client/lru/src/main/java/es-plugin.properties b/plugins/client/lru/src/main/java/es-plugin.properties new file mode 100644 index 0000000000000..87b8763963874 --- /dev/null +++ b/plugins/client/lru/src/main/java/es-plugin.properties @@ -0,0 +1 @@ +plugin=org.elasticsearch.plugin.lruclient.LruClientPlugin diff --git a/plugins/client/lru/src/main/java/org/elasticsearch/plugin/lruclient/LruClient.java b/plugins/client/lru/src/main/java/org/elasticsearch/plugin/lruclient/LruClient.java new file mode 100644 index 0000000000000..442bf50623a46 --- /dev/null +++ b/plugins/client/lru/src/main/java/org/elasticsearch/plugin/lruclient/LruClient.java @@ -0,0 +1,216 @@ +/* + * 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.lruclient; + +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map.Entry; +import org.elasticsearch.action.ActionFuture; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.bulk.BulkRequest; +import org.elasticsearch.action.bulk.BulkResponse; +import org.elasticsearch.action.bulk.TransportBulkAction; +import org.elasticsearch.action.count.CountRequest; +import org.elasticsearch.action.count.CountResponse; +import org.elasticsearch.action.count.TransportCountAction; +import org.elasticsearch.action.delete.DeleteRequest; +import org.elasticsearch.action.delete.DeleteResponse; +import org.elasticsearch.action.delete.TransportDeleteAction; +import org.elasticsearch.action.deletebyquery.DeleteByQueryRequest; +import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse; +import org.elasticsearch.action.deletebyquery.TransportDeleteByQueryAction; +import org.elasticsearch.action.get.GetRequest; +import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.action.get.TransportGetAction; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.index.TransportIndexAction; +import org.elasticsearch.action.mlt.MoreLikeThisRequest; +import org.elasticsearch.action.mlt.TransportMoreLikeThisAction; +import org.elasticsearch.action.search.*; +import org.elasticsearch.client.node.NodeAdminClient; +import org.elasticsearch.client.node.NodeClient; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.logging.ESLogger; +import org.elasticsearch.common.logging.Loggers; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.indices.IndexMissingException; +import org.elasticsearch.threadpool.ThreadPool; + +public class LruClient extends NodeClient { + + private final ESLogger logger; + private final LruCache cache; + + private class LruCache extends LinkedHashMap { + private int capacity = 1; + public LruCache(int capacity) { + super(capacity,0.75f,true); + this.capacity = capacity; + } + + @Override + protected boolean removeEldestEntry(Entry eldest) { + if(size()>capacity) { + logger.debug("LruCache over capacity: {} removing: {}", this.capacity, eldest.getKey()); + closeIndex(eldest.getKey()); + return true; + } + return false; + } + + } + + @Inject public LruClient(Settings settings, ThreadPool threadPool, NodeAdminClient admin, + TransportIndexAction indexAction, TransportDeleteAction deleteAction, TransportBulkAction bulkAction, + TransportDeleteByQueryAction deleteByQueryAction, TransportGetAction getAction, TransportCountAction countAction, + TransportSearchAction searchAction, TransportSearchScrollAction searchScrollAction, + TransportMoreLikeThisAction moreLikeThisAction) { + super(settings,threadPool,admin,indexAction,deleteAction,bulkAction,deleteByQueryAction,getAction,countAction,searchAction,searchScrollAction,moreLikeThisAction); + this.logger = Loggers.getLogger(getClass()); + this.cache = new LruCache(settings.getAsInt("node.lrucache.size", 1)); + logger.debug("LruClient",new Exception("DEBUG")); + } + + private void ensureOpen(final String index) { + if(!this.cache.containsKey(index)) { + logger.debug("Index {} not found! Try to open...", index); + // force in foreground... + try { + admin().indices().prepareOpen(index).execute().actionGet(); + } + catch(IndexMissingException e) { + // ignore + logger.debug("Index {} does not exist! Can't open.", index); + } + } + this.cache.put(index, new Date()); + } + + private void ensureOpen(final String [] indices) { + for(int i = 0; i listener) { + logger.debug("index"); + ensureOpen(request.index()); + super.index(request,listener); + } + + @Override public ActionFuture delete(DeleteRequest request) { + logger.debug("delete"); + ensureOpen(request.index()); + return super.delete(request); + } + + @Override public void delete(DeleteRequest request, ActionListener listener) { + logger.debug("delete"); + ensureOpen(request.index()); + super.delete(request, listener); + } + + @Override public ActionFuture bulk(BulkRequest request) { + logger.debug("bulk"); + return super.bulk(request); + } + + @Override public void bulk(BulkRequest request, ActionListener listener) { + logger.debug("bulk"); + super.bulk(request,listener); + } + + @Override public ActionFuture deleteByQuery(DeleteByQueryRequest request) { + logger.debug("deleteByQuery"); + ensureOpen(request.indices()); + return super.deleteByQuery(request); + } + + @Override public void deleteByQuery(DeleteByQueryRequest request, ActionListener listener) { + logger.debug("deleteByQuery"); + ensureOpen(request.indices()); + super.deleteByQuery(request,listener); + } + + @Override public ActionFuture get(GetRequest request) { + logger.debug("get"); + ensureOpen(request.index()); + return super.get(request); + } + + @Override public void get(GetRequest request, ActionListener listener) { + logger.debug("get"); + ensureOpen(request.index()); + super.get(request, listener); + } + + @Override public ActionFuture count(CountRequest request) { + logger.debug("count"); + ensureOpen(request.indices()); + return super.count(request); + } + + @Override public void count(CountRequest request, ActionListener listener) { + logger.debug("count"); + ensureOpen(request.indices()); + super.count(request, listener); + } + + @Override public ActionFuture search(SearchRequest request) { + logger.debug("search"); + ensureOpen(request.indices()); + return super.search(request); + } + + @Override public void search(SearchRequest request, ActionListener listener) { + logger.debug("search"); + ensureOpen(request.indices()); + super.search(request, listener); + } + + @Override public ActionFuture searchScroll(SearchScrollRequest request) { + logger.debug("searchScroll"); + return super.searchScroll(request); + } + + @Override public void searchScroll(SearchScrollRequest request, ActionListener listener) { + logger.debug("searchScroll"); + super.searchScroll(request, listener); + } + + @Override public ActionFuture moreLikeThis(MoreLikeThisRequest request) { + logger.debug("moreLikeThis"); + ensureOpen(request.index()); + return super.moreLikeThis(request); + } + + @Override public void moreLikeThis(MoreLikeThisRequest request, ActionListener listener) { + logger.debug("moreLikeThis"); + ensureOpen(request.index()); + super.moreLikeThis(request, listener); + } + +} diff --git a/plugins/client/lru/src/main/java/org/elasticsearch/plugin/lruclient/LruClientPlugin.java b/plugins/client/lru/src/main/java/org/elasticsearch/plugin/lruclient/LruClientPlugin.java new file mode 100644 index 0000000000000..c9cfba407d1b2 --- /dev/null +++ b/plugins/client/lru/src/main/java/org/elasticsearch/plugin/lruclient/LruClientPlugin.java @@ -0,0 +1,40 @@ +/* + * 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.lruclient; + +import java.util.Collection; +import java.util.List; +import org.elasticsearch.common.collect.Lists; +import org.elasticsearch.common.inject.Module; +import org.elasticsearch.plugins.AbstractPlugin; + +/** + * @author matt.hartzler + */ +public class LruClientPlugin extends AbstractPlugin { + + @Override public String name() { + return "lru-client"; + } + + @Override public String description() { + return "Lru Index Support via the NodeClient"; + } +} diff --git a/settings.gradle b/settings.gradle index 40f0e20e2083c..3bc9dec5f1e05 100644 --- a/settings.gradle +++ b/settings.gradle @@ -25,6 +25,8 @@ include 'plugins-river-wikipedia' include 'plugins-river-rabbitmq' include 'plugins-river-couchdb' +include 'plugins-client-lru' + rootProject.name = 'elasticsearch-root' rootProject.children.each {project -> String fileBaseName = project.name.replaceAll("\\p{Upper}") { "-${it.toLowerCase()}" }