From 6abc69c488bbcee362fee43a477cca9850051bf8 Mon Sep 17 00:00:00 2001 From: Colin Goodheart-Smithe Date: Mon, 10 Aug 2015 13:18:39 +0100 Subject: [PATCH 01/10] Packaging: Makes sure all POMs contain a description Adds an explicit description the RPM package so it doesn't inherit the description from the POM. Closes #12550 Also, modified descriptions for deb and rpm packages to be the same and to reference the documentation rather than listing features that are out of date. --- dev-tools/pom.xml | 1 + distribution/deb/pom.xml | 1 + .../deb/src/main/packaging/scripts/control | 31 +------------------ distribution/rpm/pom.xml | 2 ++ distribution/tar/pom.xml | 1 + distribution/zip/pom.xml | 1 + plugins/pom.xml | 1 + rest-api-spec/pom.xml | 1 + 8 files changed, 9 insertions(+), 30 deletions(-) diff --git a/dev-tools/pom.xml b/dev-tools/pom.xml index 369c003beee..03486764bb4 100644 --- a/dev-tools/pom.xml +++ b/dev-tools/pom.xml @@ -4,6 +4,7 @@ elasticsearch-dev-tools 2.0.0-beta1-SNAPSHOT Elasticsearch Build Resources + Tools to assist in building and developing in the Elasticsearch project org.sonatype.oss oss-parent diff --git a/distribution/deb/pom.xml b/distribution/deb/pom.xml index 46173b033f1..677364b42a8 100644 --- a/distribution/deb/pom.xml +++ b/distribution/deb/pom.xml @@ -17,6 +17,7 @@ But if you do this, then maven lifecycle does not execute any test (nor compile any test) --> + The Debian distribution of Elasticsearch false diff --git a/distribution/deb/src/main/packaging/scripts/control b/distribution/deb/src/main/packaging/scripts/control index b98ce2066c0..1913de78738 100644 --- a/distribution/deb/src/main/packaging/scripts/control +++ b/distribution/deb/src/main/packaging/scripts/control @@ -6,33 +6,4 @@ Depends: libc6, adduser Section: web Priority: optional Homepage: https://www.elastic.co/ -Description: Open Source, Distributed, RESTful Search Engine - Elasticsearch is a distributed RESTful search engine built for the cloud. - . - Features include: - . - + Distributed and Highly Available Search Engine. - - Each index is fully sharded with a configurable number of shards. - - Each shard can have one or more replicas. - - Read / Search operations performed on either one of the replica shard. - + Multi Tenant with Multi Types. - - Support for more than one index. - - Support for more than one type per index. - - Index level configuration (number of shards, index storage, ...). - + Various set of APIs - - HTTP RESTful API - - Native Java API. - - All APIs perform automatic node operation rerouting. - + Document oriented - - No need for upfront schema definition. - - Schema can be defined per type for customization of the indexing process. - + Reliable, Asynchronous Write Behind for long term persistency. - + (Near) Real Time Search. - + Built on top of Lucene - - Each shard is a fully functional Lucene index - - All the power of Lucene easily exposed through simple - configuration/plugins. - + Per operation consistency - - Single document level operations are atomic, consistent, isolated and - durable. - + Open Source under the Apache License, version 2 ("ALv2"). +Description: Elasticsearch is a distributed RESTful search engine built for the cloud. Reference documentation can be found at https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html and the 'Elasticsearch: The Definitive Guide' book can be found at https://www.elastic.co/guide/en/elasticsearch/guide/current/index.html diff --git a/distribution/rpm/pom.xml b/distribution/rpm/pom.xml index cf00809aa5a..f679ba615e9 100644 --- a/distribution/rpm/pom.xml +++ b/distribution/rpm/pom.xml @@ -13,6 +13,7 @@ elasticsearch Elasticsearch RPM Distribution rpm + The RPM distribution of Elasticsearch @@ -122,6 +123,7 @@ root root ${project.basedir}/src/main/resources/logo/elastic.gif + Elasticsearch is a distributed RESTful search engine built for the cloud. Reference documentation can be found at https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html and the 'Elasticsearch: The Definitive Guide' book can be found at https://www.elastic.co/guide/en/elasticsearch/guide/current/index.html diff --git a/distribution/tar/pom.xml b/distribution/tar/pom.xml index 3c1ec9ecfff..443480548a7 100644 --- a/distribution/tar/pom.xml +++ b/distribution/tar/pom.xml @@ -17,6 +17,7 @@ But if you do this, then maven lifecycle does not execute any test (nor compile any test) --> + The TAR distribution of Elasticsearch diff --git a/distribution/zip/pom.xml b/distribution/zip/pom.xml index 0546fb94343..854036c217a 100644 --- a/distribution/zip/pom.xml +++ b/distribution/zip/pom.xml @@ -17,6 +17,7 @@ But if you do this, then maven lifecycle does not execute any test (nor compile any test) --> + The ZIP distribution of Elasticsearch diff --git a/plugins/pom.xml b/plugins/pom.xml index 5ec47e7e7e9..f0c7d22a10c 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -11,6 +11,7 @@ pom Elasticsearch Plugin POM 2009 + A parent project for Elasticsearch plugins org.elasticsearch diff --git a/rest-api-spec/pom.xml b/rest-api-spec/pom.xml index 178c55b8770..0ba536633b3 100644 --- a/rest-api-spec/pom.xml +++ b/rest-api-spec/pom.xml @@ -4,6 +4,7 @@ elasticsearch-rest-api-spec 2.0.0-beta1-SNAPSHOT Elasticsearch Rest API Spec + REST API Specification and tests for use with the Elasticsearch REST Test framework org.sonatype.oss oss-parent From 13a347239a48d71486692a72c066e940dec8921b Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Mon, 10 Aug 2015 16:29:19 +0200 Subject: [PATCH 02/10] Don't run shaded tests as unit tests If we run the tests as a reactor build we reference the dependencies before they are shaded. This causes problems since we verify that unshaded versions of a transitive dependency is not present. This commit moves the verification tests into the integration test that always runs with the shaded version of the jar. --- qa/smoke-test-shaded/pom.xml | 1 + .../elasticsearch/shaded/test/ShadedIT.java | 23 +++++++++ .../elasticsearch/shaded/test/ShadedTest.java | 49 ------------------- 3 files changed, 24 insertions(+), 49 deletions(-) delete mode 100644 qa/smoke-test-shaded/src/test/java/org/elasticsearch/shaded/test/ShadedTest.java diff --git a/qa/smoke-test-shaded/pom.xml b/qa/smoke-test-shaded/pom.xml index 0f701d06034..309b04e0dea 100644 --- a/qa/smoke-test-shaded/pom.xml +++ b/qa/smoke-test-shaded/pom.xml @@ -16,6 +16,7 @@ shaded + true diff --git a/qa/smoke-test-shaded/src/test/java/org/elasticsearch/shaded/test/ShadedIT.java b/qa/smoke-test-shaded/src/test/java/org/elasticsearch/shaded/test/ShadedIT.java index 13a6804ab20..0befbf440fa 100644 --- a/qa/smoke-test-shaded/src/test/java/org/elasticsearch/shaded/test/ShadedIT.java +++ b/qa/smoke-test-shaded/src/test/java/org/elasticsearch/shaded/test/ShadedIT.java @@ -25,6 +25,7 @@ import org.elasticsearch.common.logging.ESLoggerFactory; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.node.Node; import org.elasticsearch.node.NodeBuilder; +import org.junit.Test; import java.nio.file.Path; @@ -51,4 +52,26 @@ public class ShadedIT extends LuceneTestCase { } } + + @Test + public void testLoadShadedClasses() throws ClassNotFoundException { + Class.forName("org.elasticsearch.common.collect.ImmutableList"); + Class.forName("org.elasticsearch.common.joda.time.DateTime"); + Class.forName("org.elasticsearch.common.util.concurrent.jsr166e.LongAdder"); + } + + @Test(expected = ClassNotFoundException.class) + public void testGuavaIsNotOnTheCP() throws ClassNotFoundException { + Class.forName("com.google.common.collect.ImmutableList"); + } + + @Test(expected = ClassNotFoundException.class) + public void testJodaIsNotOnTheCP() throws ClassNotFoundException { + Class.forName("org.joda.time.DateTime"); + } + + @Test(expected = ClassNotFoundException.class) + public void testjsr166eIsNotOnTheCP() throws ClassNotFoundException { + Class.forName("com.twitter.jsr166e.LongAdder"); + } } diff --git a/qa/smoke-test-shaded/src/test/java/org/elasticsearch/shaded/test/ShadedTest.java b/qa/smoke-test-shaded/src/test/java/org/elasticsearch/shaded/test/ShadedTest.java deleted file mode 100644 index d2d8c2422be..00000000000 --- a/qa/smoke-test-shaded/src/test/java/org/elasticsearch/shaded/test/ShadedTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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.shaded.test; - -import org.apache.lucene.util.LuceneTestCase; -import org.junit.Test; - -/** - */ -public class ShadedTest extends LuceneTestCase { - - @Test - public void testLoadShadedClasses() throws ClassNotFoundException { - Class.forName("org.elasticsearch.common.collect.ImmutableList"); - Class.forName("org.elasticsearch.common.joda.time.DateTime"); - Class.forName("org.elasticsearch.common.util.concurrent.jsr166e.LongAdder"); - } - - @Test(expected = ClassNotFoundException.class) - public void testGuavaIsNotOnTheCP() throws ClassNotFoundException { - Class.forName("com.google.common.collect.ImmutableList"); - } - - @Test(expected = ClassNotFoundException.class) - public void testJodaIsNotOnTheCP() throws ClassNotFoundException { - Class.forName("org.joda.time.DateTime"); - } - - @Test(expected = ClassNotFoundException.class) - public void testjsr166eIsNotOnTheCP() throws ClassNotFoundException { - Class.forName("com.twitter.jsr166e.LongAdder"); - } -} From 40f119d85a4eaa39d0a6e594e46f70de725557f0 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Mon, 10 Aug 2015 14:04:45 -0700 Subject: [PATCH 03/10] This method on settings loaded a class, based on a setting value, using the default classloader. It had all kinds of leniency in how the classname was found, and simply cannot work with plugins having isolated classloaders. This change removes that method. Some of the uses of it were for custom extension points, like custom repository or discovery types. A lot were just there to plugin mock implementations for tests. For the settings that were legitimate, all now support plugins adding the given setting via onModule. For those that were specific to tests for mocks, they now use Classes.loadClass (a helper around Class.forName). This is a temporary measure until (in a future PR) tests can change the implementation via package private statics. I also removed a number of unnecessary intermediate modules, added a "jvm-example" plugin that can be filled in in the future as a smoke test for breaking plugins, and gave some documentation to "spawn" modules interface. closes #12643 closes #12656 --- .../recycler/PageCacheRecyclerModule.java | 20 +- .../elasticsearch/cluster/ClusterModule.java | 8 +- .../cluster/metadata/IndexMetaData.java | 6 +- .../metadata/MetaDataIndexUpgradeService.java | 7 +- .../allocator/ShardsAllocatorModule.java | 4 +- .../org/elasticsearch/common/Classes.java | 56 +---- .../common/inject/SpawnModules.java | 8 + .../common/settings/Settings.java | 129 +++++------ .../common/util/BigArraysModule.java | 18 +- .../common/util/DefaultBigArraysModule.java | 39 ---- .../discovery/DiscoveryModule.java | 67 ++++-- .../discovery/local/LocalDiscoveryModule.java | 34 --- .../discovery/zen/ZenDiscoveryModule.java | 60 ------ .../elasticsearch/http/HttpServerModule.java | 18 +- .../org/elasticsearch/index/IndexService.java | 2 +- .../index/analysis/AnalysisModule.java | 140 ++++-------- .../index/cache/query/QueryCacheModule.java | 12 +- .../deletionpolicy/DeletionPolicyModule.java | 18 +- .../index/shard/IndexShardModule.java | 14 +- .../index/similarity/SimilarityModule.java | 29 +-- .../index/store/IndexStoreModule.java | 35 +-- .../indices/breaker/CircuitBreakerModule.java | 13 +- .../repositories/RepositoryModule.java | 18 +- .../elasticsearch/script/ScriptModule.java | 11 - .../search/DefaultSearchServiceModule.java | 31 --- .../elasticsearch/search/SearchModule.java | 8 - .../search/SearchServiceModule.java | 21 +- .../aggregations/AggregationModule.java | 2 +- .../transport/TransportModule.java | 46 +++- .../action/IndicesRequestIT.java | 21 +- .../TransportClientHeadersTests.java | 25 ++- .../cluster/ClusterInfoServiceIT.java | 3 +- .../allocation/ShardsAllocatorModuleIT.java | 9 - .../common/settings/SettingsTests.java | 36 ---- .../DiscoveryWithServiceDisruptionsIT.java | 2 +- .../index/IndexWithShadowReplicasIT.java | 2 +- .../index/TransportIndexFailuresIT.java | 2 +- .../index/analysis/AnalysisModuleTests.java | 6 +- .../AnalyzerBackwardsCompatTests.java | 1 + .../index/analysis/CompoundAnalysisTests.java | 9 +- .../elasticsearch/index/analysis/test1.json | 2 +- .../elasticsearch/index/analysis/test1.yml | 2 +- .../index/query/TemplateQueryParserTest.java | 3 +- .../index/store/CorruptedFileIT.java | 2 +- .../index/store/CorruptedTranslogIT.java | 2 +- .../index/store/ExceptionRetryIT.java | 2 +- .../indices/recovery/IndexRecoveryIT.java | 2 +- .../store/IndicesStoreIntegrationIT.java | 2 +- .../elasticsearch/recovery/RelocationIT.java | 2 +- .../recovery/TruncatedRecoveryIT.java | 2 +- .../script/NativeScriptTests.java | 6 +- .../AbstractSnapshotIntegTestCase.java | 8 + .../DedicatedClusterSnapshotRestoreIT.java | 4 +- .../snapshots/RepositoriesIT.java | 14 +- .../SharedClusterSnapshotRestoreIT.java | 18 +- .../test/ESBackcompatTestCase.java | 10 +- .../test/InternalTestCluster.java | 50 +++-- .../cache/recycler/MockBigArraysModule.java | 32 --- .../recycler/MockPageCacheRecyclerModule.java | 32 --- .../test/disruption/NetworkPartitionIT.java | 2 +- .../test/engine/MockEngineSupport.java | 9 +- .../test/search/MockSearchServiceModule.java | 32 --- .../test/store/MockFSIndexStore.java | 20 ++ .../transport/AssertingLocalTransport.java | 22 +- .../test/transport/MockTransportService.java | 19 ++ .../transport/netty/NettyTransportIT.java | 21 +- .../NettyTransportMultiPortIntegrationIT.java | 4 +- .../update/UpdateByNativeScriptIT.java | 19 +- .../src/main/resources/config/logging.yml | 4 + .../elasticsearch/cloud/aws/AwsModule.java | 18 +- .../discovery/ec2/Ec2DiscoveryModule.java | 43 ---- .../plugin/cloud/aws/CloudAwsPlugin.java | 10 +- .../cloud/aws/AbstractAwsTest.java | 3 +- .../cloud/aws/TestAwsS3Service.java | 17 +- .../cloud/azure/AzureModule.java | 22 +- .../discovery/azure/AzureDiscoveryModule.java | 56 ----- .../smbmmapfs/SmbMmapFsIndexStoreModule.java | 31 --- .../SmbSimpleFsIndexStoreModule.java | 31 --- .../plugin/cloud/azure/CloudAzurePlugin.java | 14 ++ .../AbstractAzureComputeServiceTest.java | 46 ++-- .../AbstractAzureRepositoryServiceTest.java | 28 ++- .../AzureComputeServiceSimpleMock.java | 18 +- .../AzureComputeServiceTwoNodesMock.java | 19 +- .../azure/AzureMinimumMasterNodesTest.java | 15 +- .../discovery/azure/AzureSimpleTest.java | 14 +- .../azure/AzureTwoStartedNodesTest.java | 11 +- .../index/store/AbstractAzureFsTest.java | 9 + .../index/store/SmbMMapFsTest.java | 1 + .../index/store/SmbSimpleFsTest.java | 1 + .../azure/AzureSnapshotRestoreTest.java | 3 +- .../cloud/gce/GceComputeService.java | 4 +- .../cloud/gce/GceComputeServiceImpl.java | 2 +- .../elasticsearch/cloud/gce/GceModule.java | 15 +- .../discovery/gce/GceDiscoveryModule.java | 34 --- .../plugin/cloud/gce/CloudGcePlugin.java | 8 +- ...mputeServiceTwoNodesDifferentTagsMock.java | 20 +- .../GceComputeServiceTwoNodesOneZoneMock.java | 21 +- ...GceComputeServiceTwoNodesSameTagsMock.java | 21 +- ...GceComputeServiceTwoNodesTwoZonesMock.java | 21 +- .../gce}/GceComputeServiceZeroNodeMock.java | 20 +- .../discovery/gce/GceComputeEngineTest.java | 75 +++---- .../mock/GceComputeServiceAbstractMock.java | 2 +- plugins/jvm-example/LICENSE.txt | 202 ++++++++++++++++++ plugins/jvm-example/NOTICE.txt | 8 + plugins/jvm-example/README.md | 5 + plugins/jvm-example/pom.xml | 33 +++ .../test/jvm_example/10_basic.yaml | 14 ++ .../plugin/example/JvmExamplePlugin.java | 115 ++++++++++ .../plugin/example/JvmExampleRestIT.java | 26 +-- plugins/pom.xml | 1 + qa/smoke-test-plugins/pom.xml | 8 + 111 files changed, 1282 insertions(+), 1120 deletions(-) delete mode 100644 core/src/main/java/org/elasticsearch/common/util/DefaultBigArraysModule.java delete mode 100644 core/src/main/java/org/elasticsearch/discovery/local/LocalDiscoveryModule.java delete mode 100644 core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscoveryModule.java delete mode 100644 core/src/main/java/org/elasticsearch/search/DefaultSearchServiceModule.java delete mode 100644 core/src/test/java/org/elasticsearch/test/cache/recycler/MockBigArraysModule.java delete mode 100644 core/src/test/java/org/elasticsearch/test/cache/recycler/MockPageCacheRecyclerModule.java delete mode 100644 core/src/test/java/org/elasticsearch/test/search/MockSearchServiceModule.java delete mode 100644 plugins/cloud-aws/src/main/java/org/elasticsearch/discovery/ec2/Ec2DiscoveryModule.java delete mode 100644 plugins/cloud-azure/src/main/java/org/elasticsearch/discovery/azure/AzureDiscoveryModule.java delete mode 100644 plugins/cloud-azure/src/main/java/org/elasticsearch/index/store/smbmmapfs/SmbMmapFsIndexStoreModule.java delete mode 100644 plugins/cloud-azure/src/main/java/org/elasticsearch/index/store/smbsimplefs/SmbSimpleFsIndexStoreModule.java rename plugins/cloud-azure/src/test/java/org/elasticsearch/{discovery => cloud}/azure/AbstractAzureComputeServiceTest.java (70%) rename plugins/cloud-azure/src/test/java/org/elasticsearch/{repositories => cloud}/azure/AbstractAzureRepositoryServiceTest.java (83%) rename plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/{management => }/AzureComputeServiceSimpleMock.java (80%) rename plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/{management => }/AzureComputeServiceTwoNodesMock.java (82%) delete mode 100644 plugins/cloud-gce/src/main/java/org/elasticsearch/discovery/gce/GceDiscoveryModule.java rename plugins/cloud-gce/src/test/java/org/elasticsearch/{discovery/gce/mock => cloud/gce}/GceComputeServiceTwoNodesDifferentTagsMock.java (70%) rename plugins/cloud-gce/src/test/java/org/elasticsearch/{discovery/gce/mock => cloud/gce}/GceComputeServiceTwoNodesOneZoneMock.java (70%) rename plugins/cloud-gce/src/test/java/org/elasticsearch/{discovery/gce/mock => cloud/gce}/GceComputeServiceTwoNodesSameTagsMock.java (71%) rename plugins/cloud-gce/src/test/java/org/elasticsearch/{discovery/gce/mock => cloud/gce}/GceComputeServiceTwoNodesTwoZonesMock.java (70%) rename plugins/cloud-gce/src/test/java/org/elasticsearch/{discovery/gce/mock => cloud/gce}/GceComputeServiceZeroNodeMock.java (80%) create mode 100644 plugins/jvm-example/LICENSE.txt create mode 100644 plugins/jvm-example/NOTICE.txt create mode 100644 plugins/jvm-example/README.md create mode 100644 plugins/jvm-example/pom.xml create mode 100644 plugins/jvm-example/rest-api-spec/test/jvm_example/10_basic.yaml create mode 100644 plugins/jvm-example/src/main/java/org/elasticsearch/plugin/example/JvmExamplePlugin.java rename core/src/main/java/org/elasticsearch/cache/recycler/DefaultPageCacheRecyclerModule.java => plugins/jvm-example/src/test/java/org/elasticsearch/plugin/example/JvmExampleRestIT.java (53%) diff --git a/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecyclerModule.java b/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecyclerModule.java index 4e42c483dc7..be2e6ffd7b8 100644 --- a/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecyclerModule.java +++ b/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecyclerModule.java @@ -19,17 +19,13 @@ package org.elasticsearch.cache.recycler; -import com.google.common.collect.ImmutableList; +import org.elasticsearch.common.Classes; import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.inject.Module; -import org.elasticsearch.common.inject.SpawnModules; import org.elasticsearch.common.settings.Settings; -import static org.elasticsearch.common.inject.Modules.createModule; - /** */ -public class PageCacheRecyclerModule extends AbstractModule implements SpawnModules { +public class PageCacheRecyclerModule extends AbstractModule { public static final String CACHE_IMPL = "cache.recycler.page_cache_impl"; @@ -41,10 +37,12 @@ public class PageCacheRecyclerModule extends AbstractModule implements SpawnModu @Override protected void configure() { - } - - @Override - public Iterable spawnModules() { - return ImmutableList.of(createModule(settings.getAsClass(CACHE_IMPL, DefaultPageCacheRecyclerModule.class), settings)); + String impl = settings.get(CACHE_IMPL); + if (impl == null) { + bind(PageCacheRecycler.class).asEagerSingleton(); + } else { + Class implClass = Classes.loadClass(getClass().getClassLoader(), impl); + bind(PageCacheRecycler.class).to(implClass).asEagerSingleton(); + } } } diff --git a/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java b/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java index b0b3c120c95..a97eab0aa68 100644 --- a/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java +++ b/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java @@ -31,6 +31,7 @@ import org.elasticsearch.cluster.routing.RoutingService; import org.elasticsearch.cluster.routing.allocation.AllocationModule; import org.elasticsearch.cluster.service.InternalClusterService; import org.elasticsearch.cluster.settings.ClusterDynamicSettingsModule; +import org.elasticsearch.common.Classes; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.inject.SpawnModules; @@ -88,7 +89,12 @@ public class ClusterModule extends AbstractModule implements SpawnModules { bind(NodeMappingRefreshAction.class).asEagerSingleton(); bind(MappingUpdatedAction.class).asEagerSingleton(); - bind(ClusterInfoService.class).to(settings.getAsClass(CLUSTER_SERVICE_IMPL, InternalClusterInfoService.class)).asEagerSingleton(); + String impl = settings.get(CLUSTER_SERVICE_IMPL); + Class implClass = InternalClusterInfoService.class; + if (impl != null) { + implClass = Classes.loadClass(getClass().getClassLoader(), impl); + } + bind(ClusterInfoService.class).to(implClass).asEagerSingleton(); Multibinder mbinder = Multibinder.newSetBinder(binder(), IndexTemplateFilter.class); for (Class indexTemplateFilter : indexTemplateFilters) { diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java b/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java index deea1cec308..83fbf039414 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java @@ -32,6 +32,7 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.cluster.node.DiscoveryNodeFilters; import org.elasticsearch.cluster.routing.HashFunction; import org.elasticsearch.cluster.routing.Murmur3HashFunction; +import org.elasticsearch.common.Classes; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.collect.ImmutableOpenMap; @@ -245,10 +246,11 @@ public class IndexMetaData implements Diffable, FromXContentBuild } else { this.minimumCompatibleLuceneVersion = null; } - final Class hashFunctionClass = settings.getAsClass(SETTING_LEGACY_ROUTING_HASH_FUNCTION, null); - if (hashFunctionClass == null) { + final String hashFunction = settings.get(SETTING_LEGACY_ROUTING_HASH_FUNCTION); + if (hashFunction == null) { routingHashFunction = MURMUR3_HASH_FUNCTION; } else { + final Class hashFunctionClass = Classes.loadClass(getClass().getClassLoader(), hashFunction); try { routingHashFunction = hashFunctionClass.newInstance(); } catch (InstantiationException | IllegalAccessException e) { diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataIndexUpgradeService.java b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataIndexUpgradeService.java index 7481f34d38a..08f5dbe7e53 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataIndexUpgradeService.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataIndexUpgradeService.java @@ -25,6 +25,7 @@ import org.elasticsearch.cluster.routing.DjbHashFunction; import org.elasticsearch.cluster.routing.HashFunction; import org.elasticsearch.cluster.routing.SimpleHashFunction; import org.elasticsearch.cluster.routing.UnassignedInfo; +import org.elasticsearch.common.Classes; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; @@ -66,14 +67,18 @@ public class MetaDataIndexUpgradeService extends AbstractComponent { // the hash function package has changed we replace the two hash functions if their fully qualified name is used. if (hasCustomPre20HashFunction) { switch (pre20HashFunctionName) { + case "Simple": + case "simple": case "org.elasticsearch.cluster.routing.operation.hash.simple.SimpleHashFunction": pre20HashFunction = SimpleHashFunction.class; break; + case "Djb": + case "djb": case "org.elasticsearch.cluster.routing.operation.hash.djb.DjbHashFunction": pre20HashFunction = DjbHashFunction.class; break; default: - pre20HashFunction = settings.getAsClass(DEPRECATED_SETTING_ROUTING_HASH_FUNCTION, DjbHashFunction.class, "org.elasticsearch.cluster.routing.", "HashFunction"); + pre20HashFunction = Classes.loadClass(getClass().getClassLoader(), pre20HashFunctionName); } } else { pre20HashFunction = DjbHashFunction.class; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/ShardsAllocatorModule.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/ShardsAllocatorModule.java index 38d8c0a2d7b..6370f68ac8b 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/ShardsAllocatorModule.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/ShardsAllocatorModule.java @@ -19,6 +19,7 @@ package org.elasticsearch.cluster.routing.allocation.allocator; +import org.elasticsearch.common.Classes; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; @@ -64,8 +65,7 @@ public class ShardsAllocatorModule extends AbstractModule { logger.warn("{} allocator has been removed in 2.0 using {} instead", EVEN_SHARD_COUNT_ALLOCATOR_KEY, BALANCED_ALLOCATOR_KEY); shardsAllocator = BalancedShardsAllocator.class; } else { - shardsAllocator = settings.getAsClass(TYPE_KEY, BalancedShardsAllocator.class, - "org.elasticsearch.cluster.routing.allocation.allocator.", "Allocator"); + throw new IllegalArgumentException("Unknown ShardsAllocator type [" + type + "]"); } return shardsAllocator; } diff --git a/core/src/main/java/org/elasticsearch/common/Classes.java b/core/src/main/java/org/elasticsearch/common/Classes.java index dee807a303a..b9a508e94bd 100644 --- a/core/src/main/java/org/elasticsearch/common/Classes.java +++ b/core/src/main/java/org/elasticsearch/common/Classes.java @@ -19,6 +19,8 @@ package org.elasticsearch.common; +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.bootstrap.Elasticsearch; import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.settings.NoClassSettingsException; @@ -81,14 +83,6 @@ public class Classes { return (lastDotIndex != -1 ? className.substring(0, lastDotIndex) : ""); } - public static String getPackageNameNoDomain(Class clazz) { - String fullPackage = getPackageName(clazz); - if (fullPackage.startsWith("org.") || fullPackage.startsWith("com.") || fullPackage.startsWith("net.")) { - return fullPackage.substring(4); - } - return fullPackage; - } - public static boolean isInnerClass(Class clazz) { return !Modifier.isStatic(clazz.getModifiers()) && clazz.getEnclosingClass() != null; @@ -99,47 +93,13 @@ public class Classes { return !clazz.isInterface() && !Modifier.isAbstract(modifiers); } - public static Class loadClass(ClassLoader classLoader, String className, String prefixPackage, String suffixClassName) { - return loadClass(classLoader, className, prefixPackage, suffixClassName, null); - } - - @SuppressWarnings({"unchecked"}) - public static Class loadClass(ClassLoader classLoader, String className, String prefixPackage, String suffixClassName, String errorPrefix) { - Throwable t = null; - String[] classNames = classNames(className, prefixPackage, suffixClassName); - for (String fullClassName : classNames) { - try { - return (Class) classLoader.loadClass(fullClassName); - } catch (ClassNotFoundException ex) { - t = ex; - } catch (NoClassDefFoundError er) { - t = er; - } + public static Class loadClass(ClassLoader classLoader, String className) { + try { + return (Class) classLoader.loadClass(className); + } catch (ClassNotFoundException|NoClassDefFoundError e) { + throw new ElasticsearchException("failed to load class [" + className + "]", e); } - if (errorPrefix == null) { - errorPrefix = "failed to load class"; - } - throw new NoClassSettingsException(errorPrefix + " with value [" + className + "]; tried " + Arrays.toString(classNames), t); } - private static String[] classNames(String className, String prefixPackage, String suffixClassName) { - String prefixValue = prefixPackage; - int packageSeparator = className.lastIndexOf('.'); - String classNameValue = className; - // If class name contains package use it as package prefix instead of specified default one - if (packageSeparator > 0) { - prefixValue = className.substring(0, packageSeparator + 1); - classNameValue = className.substring(packageSeparator + 1); - } - return new String[]{ - className, - prefixValue + Strings.capitalize(toCamelCase(classNameValue)) + suffixClassName, - prefixValue + toCamelCase(classNameValue) + "." + Strings.capitalize(toCamelCase(classNameValue)) + suffixClassName, - prefixValue + toCamelCase(classNameValue).toLowerCase(Locale.ROOT) + "." + Strings.capitalize(toCamelCase(classNameValue)) + suffixClassName, - }; - } - - private Classes() { - - } + private Classes() {} } diff --git a/core/src/main/java/org/elasticsearch/common/inject/SpawnModules.java b/core/src/main/java/org/elasticsearch/common/inject/SpawnModules.java index b2d1c548c09..e5005353590 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/SpawnModules.java +++ b/core/src/main/java/org/elasticsearch/common/inject/SpawnModules.java @@ -20,7 +20,15 @@ package org.elasticsearch.common.inject; /** + * This interface can be added to a Module to spawn sub modules. DO NOT USE. * + * This is fundamentally broken. + *
    + *
  • If you have a plugin with multiple modules, return all the modules at once.
  • + *
  • If you are trying to make the implementation of a module "pluggable", don't do it. + * This is not extendable because custom implementations (using onModule) cannot be + * registered before spawnModules() is called.
  • + *
*/ public interface SpawnModules { diff --git a/core/src/main/java/org/elasticsearch/common/settings/Settings.java b/core/src/main/java/org/elasticsearch/common/settings/Settings.java index b3a55fd3245..bbbde3886c0 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/Settings.java +++ b/core/src/main/java/org/elasticsearch/common/settings/Settings.java @@ -533,78 +533,6 @@ public final class Settings implements ToXContent { return parseSizeValue(get(settings), defaultValue); } - /** - * Returns the setting value (as a class) associated with the setting key. If it does not exists, - * returns the default class provided. - * - * @param setting The setting key - * @param defaultClazz The class to return if no value is associated with the setting - * @param The type of the class - * @return The class setting value, or the default class provided is no value exists - * @throws org.elasticsearch.common.settings.NoClassSettingsException Failure to load a class - */ - @SuppressWarnings({"unchecked"}) - public Class getAsClass(String setting, Class defaultClazz) throws NoClassSettingsException { - String sValue = get(setting); - if (sValue == null) { - return defaultClazz; - } - try { - return (Class) getClassLoader().loadClass(sValue); - } catch (ClassNotFoundException e) { - throw new NoClassSettingsException("Failed to load class setting [" + setting + "] with value [" + sValue + "]", e); - } - } - - /** - * Returns the setting value (as a class) associated with the setting key. If the value itself fails to - * represent a loadable class, the value will be appended to the prefixPackage and suffixed with the - * suffixClassName and it will try to be loaded with it. - * - * @param setting The setting key - * @param defaultClazz The class to return if no value is associated with the setting - * @param prefixPackage The prefix package to prefix the value with if failing to load the class as is - * @param suffixClassName The suffix class name to prefix the value with if failing to load the class as is - * @param The type of the class - * @return The class represented by the setting value, or the default class provided if no value exists - * @throws org.elasticsearch.common.settings.NoClassSettingsException Failure to load the class - */ - @SuppressWarnings({"unchecked"}) - public Class getAsClass(String setting, Class defaultClazz, String prefixPackage, String suffixClassName) throws NoClassSettingsException { - String sValue = get(setting); - if (sValue == null) { - return defaultClazz; - } - String fullClassName = sValue; - try { - return (Class) getClassLoader().loadClass(fullClassName); - } catch (ClassNotFoundException e) { - String prefixValue = prefixPackage; - int packageSeparator = sValue.lastIndexOf('.'); - if (packageSeparator > 0) { - prefixValue = sValue.substring(0, packageSeparator + 1); - sValue = sValue.substring(packageSeparator + 1); - } - fullClassName = prefixValue + Strings.capitalize(toCamelCase(sValue)) + suffixClassName; - try { - return (Class) getClassLoader().loadClass(fullClassName); - } catch (ClassNotFoundException e1) { - return loadClass(prefixValue, sValue, suffixClassName, setting); - } catch (NoClassDefFoundError e1) { - return loadClass(prefixValue, sValue, suffixClassName, setting); - } - } - } - - private Class loadClass(String prefixValue, String sValue, String suffixClassName, String setting) { - String fullClassName = prefixValue + toCamelCase(sValue).toLowerCase(Locale.ROOT) + "." + Strings.capitalize(toCamelCase(sValue)) + suffixClassName; - try { - return (Class) getClassLoader().loadClass(fullClassName); - } catch (ClassNotFoundException e2) { - throw new NoClassSettingsException("Failed to load class setting [" + setting + "] with value [" + get(setting) + "]", e2); - } - } - /** * The values associated with a setting prefix as an array. The settings array is in the format of: * settingPrefix.[index]. @@ -858,6 +786,43 @@ public final class Settings implements ToXContent { return map.remove(key); } + /** + * Removes the specified value from the given key. + * Returns true if the value was found and removed, false otherwise. + */ + public boolean removeArrayElement(String key, String value) { + // TODO: this is too crazy, we should just have a multimap... + String oldValue = get(key); + if (oldValue != null) { + // single valued case + boolean match = oldValue.equals(value); + if (match) { + remove(key); + } + return match; + } + + // multi valued + int i = 0; + while (true) { + String toCheck = map.get(key + '.' + i++); + if (toCheck == null) { + return false; + } else if (toCheck.equals(value)) { + break; + } + } + // found the value, shift values after it back one index + int j = i + 1; + while (true) { + String toMove = map.get(key + '.' + j++); + if (toMove == null) { + return true; + } + put(key + '.' + i++, toMove); + } + } + /** * Returns a setting value based on the setting key. */ @@ -1028,6 +993,26 @@ public final class Settings implements ToXContent { return this; } + /** + * Sets the setting as an array of values, but keeps existing elements for the key. + */ + public Builder extendArray(String setting, String... values) { + // check for a singular (non array) value + String oldSingle = remove(setting); + // find the highest array index + int counter = 0; + while (map.containsKey(setting + '.' + counter)) { + ++counter; + } + if (oldSingle != null) { + put(setting + '.' + counter++, oldSingle); + } + for (String value : values) { + put(setting + '.' + counter++, value); + } + return this; + } + /** * Sets the setting group. */ diff --git a/core/src/main/java/org/elasticsearch/common/util/BigArraysModule.java b/core/src/main/java/org/elasticsearch/common/util/BigArraysModule.java index b2fc2b06b7b..8d863910332 100644 --- a/core/src/main/java/org/elasticsearch/common/util/BigArraysModule.java +++ b/core/src/main/java/org/elasticsearch/common/util/BigArraysModule.java @@ -19,17 +19,15 @@ package org.elasticsearch.common.util; -import com.google.common.collect.ImmutableList; +import org.elasticsearch.common.Classes; import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.inject.Module; -import org.elasticsearch.common.inject.SpawnModules; import org.elasticsearch.common.settings.Settings; import static org.elasticsearch.common.inject.Modules.createModule; /** */ -public class BigArraysModule extends AbstractModule implements SpawnModules { +public class BigArraysModule extends AbstractModule { public static final String IMPL = "common.util.big_arrays_impl"; @@ -41,10 +39,12 @@ public class BigArraysModule extends AbstractModule implements SpawnModules { @Override protected void configure() { - } - - @Override - public Iterable spawnModules() { - return ImmutableList.of(createModule(settings.getAsClass(IMPL, DefaultBigArraysModule.class), settings)); + String impl = settings.get(IMPL); + if (impl == null) { + bind(BigArrays.class).asEagerSingleton(); + } else { + Class implClass = Classes.loadClass(getClass().getClassLoader(), impl); + bind(BigArrays.class).to(implClass).asEagerSingleton(); + } } } diff --git a/core/src/main/java/org/elasticsearch/common/util/DefaultBigArraysModule.java b/core/src/main/java/org/elasticsearch/common/util/DefaultBigArraysModule.java deleted file mode 100644 index ce73a51225a..00000000000 --- a/core/src/main/java/org/elasticsearch/common/util/DefaultBigArraysModule.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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.common.util; - -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.settings.Settings; - -/** - */ -public class DefaultBigArraysModule extends AbstractModule { - - private final Settings settings; - - public DefaultBigArraysModule(Settings settings) { - this.settings = settings; - } - - @Override - protected void configure() { - bind(BigArrays.class).asEagerSingleton(); - } -} diff --git a/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java b/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java index 9e8e776430c..5d3c8914a14 100644 --- a/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java +++ b/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java @@ -19,42 +19,71 @@ package org.elasticsearch.discovery; -import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.inject.Module; -import org.elasticsearch.common.inject.Modules; -import org.elasticsearch.common.inject.SpawnModules; +import org.elasticsearch.common.inject.multibindings.Multibinder; +import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.discovery.local.LocalDiscoveryModule; -import org.elasticsearch.discovery.zen.ZenDiscoveryModule; +import org.elasticsearch.discovery.local.LocalDiscovery; +import org.elasticsearch.discovery.zen.ZenDiscovery; +import org.elasticsearch.discovery.zen.elect.ElectMasterService; +import org.elasticsearch.discovery.zen.ping.ZenPingService; +import org.elasticsearch.discovery.zen.ping.unicast.UnicastHostsProvider; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** - * + * A module for loading classes for node discovery. */ -public class DiscoveryModule extends AbstractModule implements SpawnModules { - - private final Settings settings; +public class DiscoveryModule extends AbstractModule { public static final String DISCOVERY_TYPE_KEY = "discovery.type"; + private final Settings settings; + private final List> unicastHostProviders = Lists.newArrayList(); + private final Map> discoveryTypes = new HashMap<>(); + public DiscoveryModule(Settings settings) { this.settings = settings; + addDiscoveryType("local", LocalDiscovery.class); + addDiscoveryType("zen", ZenDiscovery.class); } - @Override - public Iterable spawnModules() { - Class defaultDiscoveryModule; - if (DiscoveryNode.localNode(settings)) { - defaultDiscoveryModule = LocalDiscoveryModule.class; - } else { - defaultDiscoveryModule = ZenDiscoveryModule.class; - } - return ImmutableList.of(Modules.createModule(settings.getAsClass(DISCOVERY_TYPE_KEY, defaultDiscoveryModule, "org.elasticsearch.discovery.", "DiscoveryModule"), settings)); + /** + * Adds a custom unicast hosts provider to build a dynamic list of unicast hosts list when doing unicast discovery. + */ + public void addUnicastHostProvider(Class unicastHostProvider) { + unicastHostProviders.add(unicastHostProvider); + } + + /** + * Adds a custom Discovery type. + */ + public void addDiscoveryType(String type, Class clazz) { + discoveryTypes.put(type, clazz); } @Override protected void configure() { + String defaultType = DiscoveryNode.localNode(settings) ? "local" : "zen"; + String discoveryType = settings.get(DISCOVERY_TYPE_KEY, defaultType); + Class discoveryClass = discoveryTypes.get(discoveryType); + if (discoveryClass == null) { + throw new IllegalArgumentException("Unknown Discovery type [" + discoveryType + "]"); + } + + if (discoveryType.equals("local") == false) { + bind(ElectMasterService.class).asEagerSingleton(); + bind(ZenPingService.class).asEagerSingleton(); + Multibinder unicastHostsProviderMultibinder = Multibinder.newSetBinder(binder(), UnicastHostsProvider.class); + for (Class unicastHostProvider : unicastHostProviders) { + unicastHostsProviderMultibinder.addBinding().to(unicastHostProvider); + } + } + bind(Discovery.class).to(discoveryClass).asEagerSingleton(); bind(DiscoveryService.class).asEagerSingleton(); } } \ No newline at end of file diff --git a/core/src/main/java/org/elasticsearch/discovery/local/LocalDiscoveryModule.java b/core/src/main/java/org/elasticsearch/discovery/local/LocalDiscoveryModule.java deleted file mode 100644 index 7f145291b0f..00000000000 --- a/core/src/main/java/org/elasticsearch/discovery/local/LocalDiscoveryModule.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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.discovery.local; - -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.discovery.Discovery; - -/** - * - */ -public class LocalDiscoveryModule extends AbstractModule { - - @Override - protected void configure() { - bind(Discovery.class).to(LocalDiscovery.class).asEagerSingleton(); - } -} diff --git a/core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscoveryModule.java b/core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscoveryModule.java deleted file mode 100644 index 33987662bfa..00000000000 --- a/core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscoveryModule.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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.discovery.zen; - -import com.google.common.collect.Lists; -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.inject.multibindings.Multibinder; -import org.elasticsearch.discovery.Discovery; -import org.elasticsearch.discovery.zen.elect.ElectMasterService; -import org.elasticsearch.discovery.zen.ping.ZenPingService; -import org.elasticsearch.discovery.zen.ping.unicast.UnicastHostsProvider; - -import java.util.List; - -/** - */ -public class ZenDiscoveryModule extends AbstractModule { - - private final List> unicastHostProviders = Lists.newArrayList(); - - /** - * Adds a custom unicast hosts provider to build a dynamic list of unicast hosts list when doing unicast discovery. - */ - public ZenDiscoveryModule addUnicastHostProvider(Class unicastHostProvider) { - unicastHostProviders.add(unicastHostProvider); - return this; - } - - @Override - protected void configure() { - bind(ElectMasterService.class).asEagerSingleton(); - bind(ZenPingService.class).asEagerSingleton(); - Multibinder unicastHostsProviderMultibinder = Multibinder.newSetBinder(binder(), UnicastHostsProvider.class); - for (Class unicastHostProvider : unicastHostProviders) { - unicastHostsProviderMultibinder.addBinding().to(unicastHostProvider); - } - bindDiscovery(); - } - - protected void bindDiscovery() { - bind(Discovery.class).to(ZenDiscovery.class).asEagerSingleton(); - } -} diff --git a/core/src/main/java/org/elasticsearch/http/HttpServerModule.java b/core/src/main/java/org/elasticsearch/http/HttpServerModule.java index df0be6bcf69..6030ac06bc8 100644 --- a/core/src/main/java/org/elasticsearch/http/HttpServerModule.java +++ b/core/src/main/java/org/elasticsearch/http/HttpServerModule.java @@ -34,33 +34,25 @@ public class HttpServerModule extends AbstractModule { private final Settings settings; private final ESLogger logger; - private Class configuredHttpServerTransport; - private String configuredHttpServerTransportSource; + private Class httpServerTransportClass; public HttpServerModule(Settings settings) { this.settings = settings; this.logger = Loggers.getLogger(getClass(), settings); + this.httpServerTransportClass = NettyHttpServerTransport.class; } @SuppressWarnings({"unchecked"}) @Override protected void configure() { - if (configuredHttpServerTransport != null) { - logger.info("Using [{}] as http transport, overridden by [{}]", configuredHttpServerTransport.getName(), configuredHttpServerTransportSource); - bind(HttpServerTransport.class).to(configuredHttpServerTransport).asEagerSingleton(); - } else { - Class defaultHttpServerTransport = NettyHttpServerTransport.class; - Class httpServerTransport = settings.getAsClass("http.type", defaultHttpServerTransport, "org.elasticsearch.http.", "HttpServerTransport"); - bind(HttpServerTransport.class).to(httpServerTransport).asEagerSingleton(); - } - + bind(HttpServerTransport.class).to(httpServerTransportClass).asEagerSingleton(); bind(HttpServer.class).asEagerSingleton(); } public void setHttpServerTransport(Class httpServerTransport, String source) { Preconditions.checkNotNull(httpServerTransport, "Configured http server transport may not be null"); Preconditions.checkNotNull(source, "Plugin, that changes transport may not be null"); - this.configuredHttpServerTransport = httpServerTransport; - this.configuredHttpServerTransportSource = source; + logger.info("Using [{}] as http transport, overridden by [{}]", httpServerTransportClass.getName(), source); + this.httpServerTransportClass = httpServerTransport; } } diff --git a/core/src/main/java/org/elasticsearch/index/IndexService.java b/core/src/main/java/org/elasticsearch/index/IndexService.java index 8c25cd17c42..be7b8e5d0d3 100644 --- a/core/src/main/java/org/elasticsearch/index/IndexService.java +++ b/core/src/main/java/org/elasticsearch/index/IndexService.java @@ -324,7 +324,7 @@ public class IndexService extends AbstractIndexComponent implements IndexCompone injector.getInstance(IndicesQueryCache.class).onClose(shardId); } }), path)); - modules.add(new DeletionPolicyModule(indexSettings)); + modules.add(new DeletionPolicyModule()); try { shardInjector = modules.createChildInjector(injector); } catch (CreationException e) { diff --git a/core/src/main/java/org/elasticsearch/index/analysis/AnalysisModule.java b/core/src/main/java/org/elasticsearch/index/analysis/AnalysisModule.java index 99cd9e4aa80..38f846a57f4 100644 --- a/core/src/main/java/org/elasticsearch/index/analysis/AnalysisModule.java +++ b/core/src/main/java/org/elasticsearch/index/analysis/AnalysisModule.java @@ -34,6 +34,7 @@ import org.elasticsearch.indices.analysis.IndicesAnalysisService; import java.util.LinkedList; import java.util.Map; +import java.util.Objects; /** * @@ -114,12 +115,8 @@ public class AnalysisModule extends AbstractModule { private final Map> tokenizers = Maps.newHashMap(); private final Map> analyzers = Maps.newHashMap(); - - public AnalysisModule(Settings settings) { - this(settings, null); - } - public AnalysisModule(Settings settings, IndicesAnalysisService indicesAnalysisService) { + Objects.requireNonNull(indicesAnalysisService); this.settings = settings; this.indicesAnalysisService = indicesAnalysisService; processors.add(new DefaultProcessor()); @@ -173,24 +170,13 @@ public class AnalysisModule extends AbstractModule { String charFilterName = entry.getKey(); Settings charFilterSettings = entry.getValue(); - Class type = null; - try { - type = charFilterSettings.getAsClass("type", null, "org.elasticsearch.index.analysis.", "CharFilterFactory"); - } catch (NoClassSettingsException e) { - // nothing found, see if its in bindings as a binding name - if (charFilterSettings.get("type") != null) { - type = charFiltersBindings.charFilters.get(Strings.toUnderscoreCase(charFilterSettings.get("type"))); - if (type == null) { - type = charFiltersBindings.charFilters.get(Strings.toCamelCase(charFilterSettings.get("type"))); - } - } - if (type == null) { - throw new IllegalArgumentException("failed to find char filter type [" + charFilterSettings.get("type") + "] for [" + charFilterName + "]", e); - } + String typeName = charFilterSettings.get("type"); + if (typeName == null) { + throw new IllegalArgumentException("CharFilter [" + charFilterName + "] must have a type associated with it"); } + Class type = charFiltersBindings.charFilters.get(typeName); if (type == null) { - // nothing found, see if its in bindings as a binding name - throw new IllegalArgumentException("Char Filter [" + charFilterName + "] must have a type associated with it"); + throw new IllegalArgumentException("Unknown CharFilter type [" + typeName + "] for [" + charFilterName + "]"); } charFilterBinder.addBinding(charFilterName).toProvider(FactoryProvider.newFactory(CharFilterFactoryFactory.class, type)).in(Scopes.SINGLETON); } @@ -206,11 +192,8 @@ public class AnalysisModule extends AbstractModule { if (clazz.getAnnotation(AnalysisSettingsRequired.class) != null) { continue; } - // register it as default under the name - if (indicesAnalysisService != null && indicesAnalysisService.hasCharFilter(charFilterName)) { - // don't register it here, we will use explicitly register it in the AnalysisService - //charFilterBinder.addBinding(charFilterName).toInstance(indicesAnalysisService.charFilterFactoryFactory(charFilterName)); - } else { + // register if it's not builtin + if (indicesAnalysisService.hasCharFilter(charFilterName) == false) { charFilterBinder.addBinding(charFilterName).toProvider(FactoryProvider.newFactory(CharFilterFactoryFactory.class, clazz)).in(Scopes.SINGLETON); } } @@ -233,23 +216,13 @@ public class AnalysisModule extends AbstractModule { String tokenFilterName = entry.getKey(); Settings tokenFilterSettings = entry.getValue(); - Class type = null; - try { - type = tokenFilterSettings.getAsClass("type", null, "org.elasticsearch.index.analysis.", "TokenFilterFactory"); - } catch (NoClassSettingsException e) { - // nothing found, see if its in bindings as a binding name - if (tokenFilterSettings.get("type") != null) { - type = tokenFiltersBindings.tokenFilters.get(Strings.toUnderscoreCase(tokenFilterSettings.get("type"))); - if (type == null) { - type = tokenFiltersBindings.tokenFilters.get(Strings.toCamelCase(tokenFilterSettings.get("type"))); - } - } - if (type == null) { - throw new IllegalArgumentException("failed to find token filter type [" + tokenFilterSettings.get("type") + "] for [" + tokenFilterName + "]", e); - } + String typeName = tokenFilterSettings.get("type"); + if (typeName == null) { + throw new IllegalArgumentException("TokenFilter [" + tokenFilterName + "] must have a type associated with it"); } + Class type = tokenFiltersBindings.tokenFilters.get(typeName); if (type == null) { - throw new IllegalArgumentException("token filter [" + tokenFilterName + "] must have a type associated with it"); + throw new IllegalArgumentException("Unknown TokenFilter type [" + typeName + "] for [" + tokenFilterName + "]"); } tokenFilterBinder.addBinding(tokenFilterName).toProvider(FactoryProvider.newFactory(TokenFilterFactoryFactory.class, type)).in(Scopes.SINGLETON); } @@ -265,11 +238,8 @@ public class AnalysisModule extends AbstractModule { if (clazz.getAnnotation(AnalysisSettingsRequired.class) != null) { continue; } - // register it as default under the name - if (indicesAnalysisService != null && indicesAnalysisService.hasTokenFilter(tokenFilterName)) { - // don't register it here, we will use explicitly register it in the AnalysisService - // tokenFilterBinder.addBinding(tokenFilterName).toInstance(indicesAnalysisService.tokenFilterFactoryFactory(tokenFilterName)); - } else { + // register if it's not builtin + if (indicesAnalysisService.hasTokenFilter(tokenFilterName) == false) { tokenFilterBinder.addBinding(tokenFilterName).toProvider(FactoryProvider.newFactory(TokenFilterFactoryFactory.class, clazz)).in(Scopes.SINGLETON); } } @@ -291,24 +261,13 @@ public class AnalysisModule extends AbstractModule { String tokenizerName = entry.getKey(); Settings tokenizerSettings = entry.getValue(); - - Class type = null; - try { - type = tokenizerSettings.getAsClass("type", null, "org.elasticsearch.index.analysis.", "TokenizerFactory"); - } catch (NoClassSettingsException e) { - // nothing found, see if its in bindings as a binding name - if (tokenizerSettings.get("type") != null) { - type = tokenizersBindings.tokenizers.get(Strings.toUnderscoreCase(tokenizerSettings.get("type"))); - if (type == null) { - type = tokenizersBindings.tokenizers.get(Strings.toCamelCase(tokenizerSettings.get("type"))); - } - } - if (type == null) { - throw new IllegalArgumentException("failed to find tokenizer type [" + tokenizerSettings.get("type") + "] for [" + tokenizerName + "]", e); - } + String typeName = tokenizerSettings.get("type"); + if (typeName == null) { + throw new IllegalArgumentException("Tokenizer [" + tokenizerName + "] must have a type associated with it"); } + Class type = tokenizersBindings.tokenizers.get(typeName); if (type == null) { - throw new IllegalArgumentException("token filter [" + tokenizerName + "] must have a type associated with it"); + throw new IllegalArgumentException("Unknown Tokenizer type [" + typeName + "] for [" + tokenizerName + "]"); } tokenizerBinder.addBinding(tokenizerName).toProvider(FactoryProvider.newFactory(TokenizerFactoryFactory.class, type)).in(Scopes.SINGLETON); } @@ -324,11 +283,8 @@ public class AnalysisModule extends AbstractModule { if (clazz.getAnnotation(AnalysisSettingsRequired.class) != null) { continue; } - // register it as default under the name - if (indicesAnalysisService != null && indicesAnalysisService.hasTokenizer(tokenizerName)) { - // don't register it here, we will use explicitly register it in the AnalysisService - // tokenizerBinder.addBinding(tokenizerName).toProvider(FactoryProvider.newFactory(TokenizerFactoryFactory.class, clazz)).in(Scopes.SINGLETON); - } else { + // register if it's not builtin + if (indicesAnalysisService.hasTokenizer(tokenizerName) == false) { tokenizerBinder.addBinding(tokenizerName).toProvider(FactoryProvider.newFactory(TokenizerFactoryFactory.class, clazz)).in(Scopes.SINGLETON); } } @@ -350,42 +306,27 @@ public class AnalysisModule extends AbstractModule { String analyzerName = entry.getKey(); Settings analyzerSettings = entry.getValue(); - Class type = null; - try { - type = analyzerSettings.getAsClass("type", null, "org.elasticsearch.index.analysis.", "AnalyzerProvider"); - } catch (NoClassSettingsException e) { - // nothing found, see if its in bindings as a binding name - if (analyzerSettings.get("type") != null) { - type = analyzersBindings.analyzers.get(Strings.toUnderscoreCase(analyzerSettings.get("type"))); - if (type == null) { - type = analyzersBindings.analyzers.get(Strings.toCamelCase(analyzerSettings.get("type"))); - } - } - if (type == null) { - // no specific type, check if it has a tokenizer associated with it - String tokenizerName = analyzerSettings.get("tokenizer"); - if (tokenizerName != null) { - // we have a tokenizer, use the CustomAnalyzer - type = CustomAnalyzerProvider.class; - } else { - throw new IllegalArgumentException("failed to find analyzer type [" + analyzerSettings.get("type") + "] or tokenizer for [" + analyzerName + "]", e); - } - } - } - if (type == null) { - // no specific type, check if it has a tokenizer associated with it - String tokenizerName = analyzerSettings.get("tokenizer"); - if (tokenizerName != null) { - // we have a tokenizer, use the CustomAnalyzer + String typeName = analyzerSettings.get("type"); + Class type; + if (typeName == null) { + if (analyzerSettings.get("tokenizer") != null) { + // custom analyzer, need to add it type = CustomAnalyzerProvider.class; } else { - throw new IllegalArgumentException("failed to find analyzer type [" + analyzerSettings.get("type") + "] or tokenizer for [" + analyzerName + "]"); + throw new IllegalArgumentException("Analyzer [" + analyzerName + "] must have a type associated with it"); + } + } else if (typeName.equals("custom")) { + type = CustomAnalyzerProvider.class; + } else { + type = analyzersBindings.analyzers.get(typeName); + if (type == null) { + throw new IllegalArgumentException("Unknown Analyzer type [" + typeName + "] for [" + analyzerName + "]"); } } + analyzerBinder.addBinding(analyzerName).toProvider(FactoryProvider.newFactory(AnalyzerProviderFactory.class, type)).in(Scopes.SINGLETON); } - // go over the analyzers in the bindings and register the ones that are not configured for (Map.Entry> entry : analyzersBindings.analyzers.entrySet()) { String analyzerName = entry.getKey(); @@ -398,11 +339,8 @@ public class AnalysisModule extends AbstractModule { if (clazz.getAnnotation(AnalysisSettingsRequired.class) != null) { continue; } - // register it as default under the name - if (indicesAnalysisService != null && indicesAnalysisService.hasAnalyzer(analyzerName)) { - // don't register it here, we will use explicitly register it in the AnalysisService - // analyzerBinder.addBinding(analyzerName).toProvider(FactoryProvider.newFactory(AnalyzerProviderFactory.class, clazz)).in(Scopes.SINGLETON); - } else { + // register if it's not builtin + if (indicesAnalysisService.hasAnalyzer(analyzerName) == false) { analyzerBinder.addBinding(analyzerName).toProvider(FactoryProvider.newFactory(AnalyzerProviderFactory.class, clazz)).in(Scopes.SINGLETON); } } diff --git a/core/src/main/java/org/elasticsearch/index/cache/query/QueryCacheModule.java b/core/src/main/java/org/elasticsearch/index/cache/query/QueryCacheModule.java index 84030c0c693..f5465c9c6ed 100644 --- a/core/src/main/java/org/elasticsearch/index/cache/query/QueryCacheModule.java +++ b/core/src/main/java/org/elasticsearch/index/cache/query/QueryCacheModule.java @@ -19,6 +19,8 @@ package org.elasticsearch.index.cache.query; +import org.elasticsearch.cluster.metadata.AliasOrIndex; +import org.elasticsearch.common.Classes; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.Scopes; import org.elasticsearch.common.settings.Settings; @@ -43,8 +45,12 @@ public class QueryCacheModule extends AbstractModule { @Override protected void configure() { - bind(QueryCache.class) - .to(settings.getAsClass(QueryCacheSettings.QUERY_CACHE_TYPE, IndexQueryCache.class, "org.elasticsearch.index.cache.query.", "QueryCache")) - .in(Scopes.SINGLETON); + Class queryCacheClass = IndexQueryCache.class; + String customQueryCache = settings.get(QueryCacheSettings.QUERY_CACHE_TYPE); + if (customQueryCache != null) { + // TODO: make this only useable from tests + queryCacheClass = Classes.loadClass(getClass().getClassLoader(), customQueryCache); + } + bind(QueryCache.class).to(queryCacheClass).in(Scopes.SINGLETON); } } diff --git a/core/src/main/java/org/elasticsearch/index/deletionpolicy/DeletionPolicyModule.java b/core/src/main/java/org/elasticsearch/index/deletionpolicy/DeletionPolicyModule.java index 35f370d3869..55ec61fca93 100644 --- a/core/src/main/java/org/elasticsearch/index/deletionpolicy/DeletionPolicyModule.java +++ b/core/src/main/java/org/elasticsearch/index/deletionpolicy/DeletionPolicyModule.java @@ -22,30 +22,14 @@ package org.elasticsearch.index.deletionpolicy; import org.apache.lucene.index.IndexDeletionPolicy; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.name.Names; -import org.elasticsearch.common.settings.Settings; -import static org.elasticsearch.index.deletionpolicy.DeletionPolicyModule.DeletionPolicySettings.TYPE; - -/** - * - */ public class DeletionPolicyModule extends AbstractModule { - public static class DeletionPolicySettings { - public static final String TYPE = "index.deletionpolicy.type"; - } - - private final Settings settings; - - public DeletionPolicyModule(Settings settings) { - this.settings = settings; - } - @Override protected void configure() { bind(IndexDeletionPolicy.class) .annotatedWith(Names.named("actual")) - .to(settings.getAsClass(TYPE, KeepOnlyLastDeletionPolicy.class)) + .to(KeepOnlyLastDeletionPolicy.class) .asEagerSingleton(); bind(SnapshotDeletionPolicy.class) diff --git a/core/src/main/java/org/elasticsearch/index/shard/IndexShardModule.java b/core/src/main/java/org/elasticsearch/index/shard/IndexShardModule.java index 870cc4eee99..28a59734dac 100644 --- a/core/src/main/java/org/elasticsearch/index/shard/IndexShardModule.java +++ b/core/src/main/java/org/elasticsearch/index/shard/IndexShardModule.java @@ -20,9 +20,11 @@ package org.elasticsearch.index.shard; import org.elasticsearch.cluster.metadata.IndexMetaData; +import org.elasticsearch.common.Classes; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.multibindings.Multibinder; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.index.cache.query.index.IndexQueryCache; import org.elasticsearch.index.engine.IndexSearcherWrapper; import org.elasticsearch.index.engine.IndexSearcherWrappingService; import org.elasticsearch.index.engine.EngineFactory; @@ -39,10 +41,6 @@ import org.elasticsearch.index.translog.TranslogService; public class IndexShardModule extends AbstractModule { public static final String ENGINE_FACTORY = "index.engine.factory"; - private static final Class DEFAULT_ENGINE_FACTORY_CLASS = InternalEngineFactory.class; - - private static final String ENGINE_PREFIX = "org.elasticsearch.index.engine."; - private static final String ENGINE_SUFFIX = "EngineFactory"; private final ShardId shardId; private final Settings settings; @@ -72,7 +70,13 @@ public class IndexShardModule extends AbstractModule { bind(TranslogService.class).asEagerSingleton(); } - bind(EngineFactory.class).to(settings.getAsClass(ENGINE_FACTORY, DEFAULT_ENGINE_FACTORY_CLASS, ENGINE_PREFIX, ENGINE_SUFFIX)); + Class engineFactoryClass = InternalEngineFactory.class; + String customEngineFactory = settings.get(ENGINE_FACTORY); + if (customEngineFactory != null) { + // TODO: make this only useable from tests + engineFactoryClass = Classes.loadClass(getClass().getClassLoader(), customEngineFactory); + } + bind(EngineFactory.class).to(engineFactoryClass); bind(StoreRecoveryService.class).asEagerSingleton(); bind(ShardPercolateService.class).asEagerSingleton(); bind(ShardTermVectorsService.class).asEagerSingleton(); diff --git a/core/src/main/java/org/elasticsearch/index/similarity/SimilarityModule.java b/core/src/main/java/org/elasticsearch/index/similarity/SimilarityModule.java index e2bc92adb3f..d53a1002b64 100644 --- a/core/src/main/java/org/elasticsearch/index/similarity/SimilarityModule.java +++ b/core/src/main/java/org/elasticsearch/index/similarity/SimilarityModule.java @@ -46,6 +46,12 @@ public class SimilarityModule extends AbstractModule { public SimilarityModule(Settings settings) { this.settings = settings; + addSimilarity("default", DefaultSimilarityProvider.class); + addSimilarity("BM25", BM25SimilarityProvider.class); + addSimilarity("DFR", DFRSimilarityProvider.class); + addSimilarity("IB", IBSimilarityProvider.class); + addSimilarity("LMDirichlet", LMDirichletSimilarityProvider.class); + addSimilarity("LMJelinekMercer", LMJelinekMercerSimilarityProvider.class); } /** @@ -60,30 +66,25 @@ public class SimilarityModule extends AbstractModule { @Override protected void configure() { - Map> providers = Maps.newHashMap(similarities); + MapBinder similarityBinder = + MapBinder.newMapBinder(binder(), String.class, SimilarityProvider.Factory.class); Map similaritySettings = settings.getGroups(SIMILARITY_SETTINGS_PREFIX); for (Map.Entry entry : similaritySettings.entrySet()) { String name = entry.getKey(); Settings settings = entry.getValue(); - Class type = - settings.getAsClass("type", null, "org.elasticsearch.index.similarity.", "SimilarityProvider"); - if (type == null) { - throw new IllegalArgumentException("SimilarityProvider [" + name + "] must have an associated type"); + String typeName = settings.get("type"); + if (typeName == null) { + throw new IllegalArgumentException("Similarity [" + name + "] must have an associated type"); + } else if (similarities.containsKey(typeName) == false) { + throw new IllegalArgumentException("Unknown Similarity type [" + typeName + "] for [" + name + "]"); } - providers.put(name, type); - } - - MapBinder similarityBinder = - MapBinder.newMapBinder(binder(), String.class, SimilarityProvider.Factory.class); - - for (Map.Entry> entry : providers.entrySet()) { - similarityBinder.addBinding(entry.getKey()).toProvider(FactoryProvider.newFactory(SimilarityProvider.Factory.class, entry.getValue())).in(Scopes.SINGLETON); + similarityBinder.addBinding(entry.getKey()).toProvider(FactoryProvider.newFactory(SimilarityProvider.Factory.class, similarities.get(typeName))).in(Scopes.SINGLETON); } for (PreBuiltSimilarityProvider.Factory factory : Similarities.listFactories()) { - if (!providers.containsKey(factory.name())) { + if (!similarities.containsKey(factory.name())) { similarityBinder.addBinding(factory.name()).toInstance(factory); } } diff --git a/core/src/main/java/org/elasticsearch/index/store/IndexStoreModule.java b/core/src/main/java/org/elasticsearch/index/store/IndexStoreModule.java index d3c80222a45..84c856d1701 100644 --- a/core/src/main/java/org/elasticsearch/index/store/IndexStoreModule.java +++ b/core/src/main/java/org/elasticsearch/index/store/IndexStoreModule.java @@ -19,20 +19,22 @@ package org.elasticsearch.index.store; -import com.google.common.collect.ImmutableList; -import org.elasticsearch.common.inject.*; +import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.settings.Settings; +import java.util.HashMap; +import java.util.Map; import java.util.Locale; /** * */ -public class IndexStoreModule extends AbstractModule implements SpawnModules { +public class IndexStoreModule extends AbstractModule { public static final String STORE_TYPE = "index.store.type"; private final Settings settings; + private final Map> storeTypes = new HashMap<>(); public enum Type { NIOFS, @@ -56,25 +58,30 @@ public class IndexStoreModule extends AbstractModule implements SpawnModules { this.settings = settings; } - @Override - public Iterable spawnModules() { - final String storeType = settings.get(STORE_TYPE, Type.DEFAULT.getSettingsKey()); + public void addIndexStore(String type, Class clazz) { + storeTypes.put(type, clazz); + } + + private static boolean isBuiltinType(String storeType) { for (Type type : Type.values()) { if (type.match(storeType)) { - return ImmutableList.of(new DefaultStoreModule()); + return true; } } - final Class indexStoreModule = settings.getAsClass(STORE_TYPE, null, "org.elasticsearch.index.store.", "IndexStoreModule"); - return ImmutableList.of(Modules.createModule(indexStoreModule, settings)); + return false; } @Override - protected void configure() {} - - private static class DefaultStoreModule extends AbstractModule { - @Override - protected void configure() { + protected void configure() { + final String storeType = settings.get(STORE_TYPE); + if (storeType == null || isBuiltinType(storeType)) { bind(IndexStore.class).asEagerSingleton(); + } else { + Class clazz = storeTypes.get(storeType); + if (clazz == null) { + throw new IllegalArgumentException("Unknown store type [" + storeType + "]"); + } + bind(IndexStore.class).to(clazz).asEagerSingleton(); } } } \ No newline at end of file diff --git a/core/src/main/java/org/elasticsearch/indices/breaker/CircuitBreakerModule.java b/core/src/main/java/org/elasticsearch/indices/breaker/CircuitBreakerModule.java index 66a1e746a6d..084d3b7c66a 100644 --- a/core/src/main/java/org/elasticsearch/indices/breaker/CircuitBreakerModule.java +++ b/core/src/main/java/org/elasticsearch/indices/breaker/CircuitBreakerModule.java @@ -24,7 +24,7 @@ import org.elasticsearch.common.settings.Settings; public class CircuitBreakerModule extends AbstractModule { - public static final String IMPL = "indices.breaker.type"; + public static final String TYPE_KEY = "indices.breaker.type"; private final Settings settings; @@ -34,6 +34,15 @@ public class CircuitBreakerModule extends AbstractModule { @Override protected void configure() { - bind(CircuitBreakerService.class).to(settings.getAsClass(IMPL, HierarchyCircuitBreakerService.class)).asEagerSingleton(); + String type = settings.get(TYPE_KEY); + Class impl; + if (type == null || type.equals("hierarchy")) { + impl = HierarchyCircuitBreakerService.class; + } else if (type.equals("none")) { + impl = NoneCircuitBreakerService.class; + } else { + throw new IllegalArgumentException("Unknown circuit breaker type [" + type + "]"); + } + bind(CircuitBreakerService.class).to(impl).asEagerSingleton(); } } diff --git a/core/src/main/java/org/elasticsearch/repositories/RepositoryModule.java b/core/src/main/java/org/elasticsearch/repositories/RepositoryModule.java index 1edbf4046be..2dccc2b0186 100644 --- a/core/src/main/java/org/elasticsearch/repositories/RepositoryModule.java +++ b/core/src/main/java/org/elasticsearch/repositories/RepositoryModule.java @@ -20,13 +20,15 @@ package org.elasticsearch.repositories; import com.google.common.collect.ImmutableList; -import org.elasticsearch.common.Classes; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.inject.Modules; import org.elasticsearch.common.inject.SpawnModules; import org.elasticsearch.common.settings.Settings; +import java.util.Arrays; +import java.util.Collections; + import static org.elasticsearch.common.Strings.toCamelCase; /** @@ -67,7 +69,11 @@ public class RepositoryModule extends AbstractModule implements SpawnModules { */ @Override public Iterable spawnModules() { - return ImmutableList.of(Modules.createModule(loadTypeModule(repositoryName.type(), "org.elasticsearch.repositories.", "RepositoryModule"), globalSettings)); + Class repoModuleClass = typesRegistry.type(repositoryName.type()); + if (repoModuleClass == null) { + throw new IllegalArgumentException("Could not find repository type [" + repositoryName.getType() + "] for repository [" + repositoryName.getName() + "]"); + } + return Collections.unmodifiableList(Arrays.asList(Modules.createModule(repoModuleClass, globalSettings))); } /** @@ -77,12 +83,4 @@ public class RepositoryModule extends AbstractModule implements SpawnModules { protected void configure() { bind(RepositorySettings.class).toInstance(new RepositorySettings(globalSettings, settings)); } - - private Class loadTypeModule(String type, String prefixPackage, String suffixClassName) { - Class registered = typesRegistry.type(type); - if (registered != null) { - return registered; - } - return Classes.loadClass(globalSettings.getClassLoader(), type, prefixPackage, suffixClassName); - } } diff --git a/core/src/main/java/org/elasticsearch/script/ScriptModule.java b/core/src/main/java/org/elasticsearch/script/ScriptModule.java index 2cc12e13d85..d6c52a6b130 100644 --- a/core/src/main/java/org/elasticsearch/script/ScriptModule.java +++ b/core/src/main/java/org/elasticsearch/script/ScriptModule.java @@ -75,17 +75,6 @@ public class ScriptModule extends AbstractModule { scriptsBinder.addBinding(entry.getKey()).to(entry.getValue()).asEagerSingleton(); } - // now, check for config based ones - Map nativeSettings = settings.getGroups("script.native"); - for (Map.Entry entry : nativeSettings.entrySet()) { - String name = entry.getKey(); - Class type = entry.getValue().getAsClass("type", NativeScriptFactory.class); - if (type == NativeScriptFactory.class) { - throw new IllegalArgumentException("type is missing for native script [" + name + "]"); - } - scriptsBinder.addBinding(name).to(type).asEagerSingleton(); - } - Multibinder multibinder = Multibinder.newSetBinder(binder(), ScriptEngineService.class); multibinder.addBinding().to(NativeScriptEngineService.class); diff --git a/core/src/main/java/org/elasticsearch/search/DefaultSearchServiceModule.java b/core/src/main/java/org/elasticsearch/search/DefaultSearchServiceModule.java deleted file mode 100644 index 464576276fb..00000000000 --- a/core/src/main/java/org/elasticsearch/search/DefaultSearchServiceModule.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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.search; - -import org.elasticsearch.common.inject.AbstractModule; - -public class DefaultSearchServiceModule extends AbstractModule { - - @Override - protected void configure() { - bind(SearchService.class).asEagerSingleton(); - } - -} diff --git a/core/src/main/java/org/elasticsearch/search/SearchModule.java b/core/src/main/java/org/elasticsearch/search/SearchModule.java index eba17c8afd7..eb2f16cf0cf 100644 --- a/core/src/main/java/org/elasticsearch/search/SearchModule.java +++ b/core/src/main/java/org/elasticsearch/search/SearchModule.java @@ -33,15 +33,7 @@ import org.elasticsearch.search.controller.SearchPhaseController; import org.elasticsearch.search.dfs.DfsPhase; import org.elasticsearch.search.fetch.FetchPhase; import org.elasticsearch.search.fetch.FetchSubPhaseModule; -import org.elasticsearch.search.fetch.explain.ExplainFetchSubPhase; -import org.elasticsearch.search.fetch.fielddata.FieldDataFieldsFetchSubPhase; -import org.elasticsearch.search.fetch.innerhits.InnerHitsFetchSubPhase; -import org.elasticsearch.search.fetch.matchedqueries.MatchedQueriesFetchSubPhase; -import org.elasticsearch.search.fetch.script.ScriptFieldsFetchSubPhase; -import org.elasticsearch.search.fetch.source.FetchSourceSubPhase; -import org.elasticsearch.search.fetch.version.VersionFetchSubPhase; import org.elasticsearch.search.highlight.HighlightModule; -import org.elasticsearch.search.highlight.HighlightPhase; import org.elasticsearch.search.query.QueryPhase; import org.elasticsearch.search.suggest.SuggestModule; diff --git a/core/src/main/java/org/elasticsearch/search/SearchServiceModule.java b/core/src/main/java/org/elasticsearch/search/SearchServiceModule.java index 4bc1e360d89..be2d8796781 100644 --- a/core/src/main/java/org/elasticsearch/search/SearchServiceModule.java +++ b/core/src/main/java/org/elasticsearch/search/SearchServiceModule.java @@ -19,16 +19,11 @@ package org.elasticsearch.search; -import com.google.common.collect.ImmutableList; - +import org.elasticsearch.common.Classes; import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.inject.Module; -import org.elasticsearch.common.inject.SpawnModules; import org.elasticsearch.common.settings.Settings; -import static org.elasticsearch.common.inject.Modules.createModule; - -public class SearchServiceModule extends AbstractModule implements SpawnModules { +public class SearchServiceModule extends AbstractModule { public static final String IMPL = "search.service_impl"; @@ -40,10 +35,12 @@ public class SearchServiceModule extends AbstractModule implements SpawnModules @Override protected void configure() { - } - - @Override - public Iterable spawnModules() { - return ImmutableList.of(createModule(settings.getAsClass(IMPL, DefaultSearchServiceModule.class), settings)); + String impl = settings.get(IMPL); + if (impl == null) { + bind(SearchService.class).asEagerSingleton(); + } else { + Class implClass = Classes.loadClass(getClass().getClassLoader(), impl); + bind(SearchService.class).to(implClass).asEagerSingleton(); + } } } diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/AggregationModule.java b/core/src/main/java/org/elasticsearch/search/aggregations/AggregationModule.java index 4466bc7d3a3..6f9281d1015 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/AggregationModule.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/AggregationModule.java @@ -74,7 +74,7 @@ import java.util.List; /** * The main module for the get (binding all get components together) */ -public class AggregationModule extends AbstractModule implements SpawnModules{ +public class AggregationModule extends AbstractModule implements SpawnModules { private List> aggParsers = Lists.newArrayList(); private List> pipelineAggParsers = Lists.newArrayList(); diff --git a/core/src/main/java/org/elasticsearch/transport/TransportModule.java b/core/src/main/java/org/elasticsearch/transport/TransportModule.java index 6953d19bfdd..fd8932b5760 100644 --- a/core/src/main/java/org/elasticsearch/transport/TransportModule.java +++ b/core/src/main/java/org/elasticsearch/transport/TransportModule.java @@ -20,6 +20,7 @@ package org.elasticsearch.transport; import com.google.common.base.Preconditions; +import com.google.common.collect.Maps; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; @@ -29,6 +30,8 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.transport.local.LocalTransport; import org.elasticsearch.transport.netty.NettyTransport; +import java.util.Map; + /** * */ @@ -37,9 +40,14 @@ public class TransportModule extends AbstractModule { public static final String TRANSPORT_TYPE_KEY = "transport.type"; public static final String TRANSPORT_SERVICE_TYPE_KEY = "transport.service.type"; + public static final String LOCAL_TRANSPORT = "local"; + public static final String NETTY_TRANSPORT = "netty"; + private final ESLogger logger; private final Settings settings; + private final Map> transportServices = Maps.newHashMap(); + private final Map> transports = Maps.newHashMap(); private Class configuredTransportService; private Class configuredTransport; private String configuredTransportServiceSource; @@ -48,6 +56,22 @@ public class TransportModule extends AbstractModule { public TransportModule(Settings settings) { this.settings = settings; this.logger = Loggers.getLogger(getClass(), settings); + addTransport(LOCAL_TRANSPORT, LocalTransport.class); + addTransport(NETTY_TRANSPORT, NettyTransport.class); + } + + public void addTransportService(String name, Class clazz) { + Class oldClazz = transportServices.put(name, clazz); + if (oldClazz != null) { + throw new IllegalArgumentException("Cannot register TransportService [" + name + "] to " + clazz.getName() + ", already registered to " + oldClazz.getName()); + } + } + + public void addTransport(String name, Class clazz) { + Class oldClazz = transports.put(name, clazz); + if (oldClazz != null) { + throw new IllegalArgumentException("Cannot register Transport [" + name + "] to " + clazz.getName() + ", already registered to " + oldClazz.getName()); + } } @Override @@ -56,12 +80,14 @@ public class TransportModule extends AbstractModule { logger.info("Using [{}] as transport service, overridden by [{}]", configuredTransportService.getName(), configuredTransportServiceSource); bind(TransportService.class).to(configuredTransportService).asEagerSingleton(); } else { - Class defaultTransportService = TransportService.class; - Class transportService = settings.getAsClass(TRANSPORT_SERVICE_TYPE_KEY, defaultTransportService, "org.elasticsearch.transport.", "TransportService"); - if (!TransportService.class.equals(transportService)) { - bind(TransportService.class).to(transportService).asEagerSingleton(); - } else { + String typeName = settings.get(TRANSPORT_SERVICE_TYPE_KEY); + if (typeName == null) { bind(TransportService.class).asEagerSingleton(); + } else { + if (transportServices.containsKey(typeName) == false) { + throw new IllegalArgumentException("Unknown TransportService [" + typeName + "]"); + } + bind(TransportService.class).to(transportServices.get(typeName)).asEagerSingleton(); } } @@ -71,9 +97,13 @@ public class TransportModule extends AbstractModule { logger.info("Using [{}] as transport, overridden by [{}]", configuredTransport.getName(), configuredTransportSource); bind(Transport.class).to(configuredTransport).asEagerSingleton(); } else { - Class defaultTransport = DiscoveryNode.localNode(settings) ? LocalTransport.class : NettyTransport.class; - Class transport = settings.getAsClass(TRANSPORT_TYPE_KEY, defaultTransport, "org.elasticsearch.transport.", "Transport"); - bind(Transport.class).to(transport).asEagerSingleton(); + String defaultType = DiscoveryNode.localNode(settings) ? LOCAL_TRANSPORT : NETTY_TRANSPORT; + String typeName = settings.get(TRANSPORT_TYPE_KEY, defaultType); + Class clazz = transports.get(typeName); + if (clazz == null) { + throw new IllegalArgumentException("Unknown Transport [" + typeName + "]"); + } + bind(Transport.class).to(clazz).asEagerSingleton(); } } diff --git a/core/src/test/java/org/elasticsearch/action/IndicesRequestIT.java b/core/src/test/java/org/elasticsearch/action/IndicesRequestIT.java index 1b956656093..3d017cf8f6e 100644 --- a/core/src/test/java/org/elasticsearch/action/IndicesRequestIT.java +++ b/core/src/test/java/org/elasticsearch/action/IndicesRequestIT.java @@ -89,6 +89,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.plugins.AbstractPlugin; import org.elasticsearch.script.Script; import org.elasticsearch.search.action.SearchServiceTransportAction; import org.elasticsearch.test.ESIntegTestCase; @@ -143,7 +144,7 @@ public class IndicesRequestIT extends ESIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.settingsBuilder() .put(super.nodeSettings(nodeOrdinal)) - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, InterceptingTransportService.class.getName()) + .extendArray("plugin.types", InterceptingTransportService.Plugin.class.getName()) .build(); } @@ -843,6 +844,24 @@ public class IndicesRequestIT extends ESIntegTestCase { public static class InterceptingTransportService extends TransportService { + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "intercepting-transport-service"; + } + @Override + public String description() { + return "an intercepting transport service for testing"; + } + public void onModule(TransportModule transportModule) { + transportModule.addTransportService("intercepting", InterceptingTransportService.class); + } + @Override + public Settings additionalSettings() { + return Settings.builder().put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, "intercepting").build(); + } + } + private final Set actions = new HashSet<>(); private final Map> requests = new HashMap<>(); diff --git a/core/src/test/java/org/elasticsearch/client/transport/TransportClientHeadersTests.java b/core/src/test/java/org/elasticsearch/client/transport/TransportClientHeadersTests.java index d513f5d4a5b..758dc3fe0a9 100644 --- a/core/src/test/java/org/elasticsearch/client/transport/TransportClientHeadersTests.java +++ b/core/src/test/java/org/elasticsearch/client/transport/TransportClientHeadersTests.java @@ -35,6 +35,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.LocalTransportAddress; import org.elasticsearch.common.transport.TransportAddress; +import org.elasticsearch.plugins.AbstractPlugin; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.*; import org.junit.Test; @@ -57,7 +58,7 @@ public class TransportClientHeadersTests extends AbstractClientHeadersTests { TransportClient client = TransportClient.builder().settings(Settings.builder() .put("client.transport.sniff", false) .put("node.name", "transport_client_" + this.getTestName()) - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, InternalTransportService.class.getName()) + .put("plugin.types", InternalTransportService.Plugin.class.getName()) .put(headersSettings) .build()).build(); @@ -71,8 +72,8 @@ public class TransportClientHeadersTests extends AbstractClientHeadersTests { .put("client.transport.sniff", true) .put("cluster.name", "cluster1") .put("node.name", "transport_client_" + this.getTestName() + "_1") - .put("client.transport.nodes_sampler_interval", "1s") - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, InternalTransportService.class.getName()) + .put("client.transport.nodes_sampler_interval", "1s") + .put("plugin.types", InternalTransportService.Plugin.class.getName()) .put(HEADER_SETTINGS) .put("path.home", createTempDir().toString()) .build()).build(); @@ -95,6 +96,24 @@ public class TransportClientHeadersTests extends AbstractClientHeadersTests { public static class InternalTransportService extends TransportService { + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "mock-transport-service"; + } + @Override + public String description() { + return "a mock transport service"; + } + public void onModule(TransportModule transportModule) { + transportModule.addTransportService("internal", InternalTransportService.class); + } + @Override + public Settings additionalSettings() { + return Settings.builder().put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, "internal").build(); + } + } + CountDownLatch clusterStateLatch = new CountDownLatch(1); @Inject diff --git a/core/src/test/java/org/elasticsearch/cluster/ClusterInfoServiceIT.java b/core/src/test/java/org/elasticsearch/cluster/ClusterInfoServiceIT.java index 70e425e10e2..40dec515f9c 100644 --- a/core/src/test/java/org/elasticsearch/cluster/ClusterInfoServiceIT.java +++ b/core/src/test/java/org/elasticsearch/cluster/ClusterInfoServiceIT.java @@ -143,8 +143,7 @@ public class ClusterInfoServiceIT extends ESIntegTestCase { return Settings.builder() // manual collection or upon cluster forming. .put(InternalClusterInfoService.INTERNAL_CLUSTER_INFO_TIMEOUT, "1s") - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, MockTransportService.class.getName()) - .put("plugin.types", Plugin.class.getName()) + .putArray("plugin.types", Plugin.class.getName(), MockTransportService.Plugin.class.getName()) .build(); } diff --git a/core/src/test/java/org/elasticsearch/cluster/allocation/ShardsAllocatorModuleIT.java b/core/src/test/java/org/elasticsearch/cluster/allocation/ShardsAllocatorModuleIT.java index edb6235b815..702955e523c 100644 --- a/core/src/test/java/org/elasticsearch/cluster/allocation/ShardsAllocatorModuleIT.java +++ b/core/src/test/java/org/elasticsearch/cluster/allocation/ShardsAllocatorModuleIT.java @@ -47,15 +47,6 @@ public class ShardsAllocatorModuleIT extends ESIntegTestCase { assertAllocatorInstance(build, BalancedShardsAllocator.class); } - public void testLoadByClassNameShardsAllocator() throws IOException { - Settings build = settingsBuilder().put(ShardsAllocatorModule.TYPE_KEY, "BalancedShards").build(); - assertAllocatorInstance(build, BalancedShardsAllocator.class); - - build = settingsBuilder().put(ShardsAllocatorModule.TYPE_KEY, - "org.elasticsearch.cluster.routing.allocation.allocator.BalancedShardsAllocator").build(); - assertAllocatorInstance(build, BalancedShardsAllocator.class); - } - private void assertAllocatorInstance(Settings settings, Class clazz) throws IOException { while (cluster().size() != 0) { internalCluster().stopRandomDataNode(); diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingsTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingsTests.java index 5e2a44a327e..a17bb4fd9d9 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/SettingsTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/SettingsTests.java @@ -47,35 +47,6 @@ public class SettingsTests extends ESTestCase { assertThat(settings.get("test.camel_case"), equalTo("bar")); } - @Test - public void testGetAsClass() { - Settings settings = settingsBuilder() - .put("test.class", "bar") - .put("test.class.package", "org.elasticsearch.common.settings.bar") - .build(); - - // Assert that defaultClazz is loaded if setting is not specified - assertThat(settings.getAsClass("no.settings", FooTestClass.class, "org.elasticsearch.common.settings.", "TestClass").getName(), - equalTo(FooTestClass.class.getName())); - - // Assert that correct class is loaded if setting contain name without package - assertThat(settings.getAsClass("test.class", FooTestClass.class, "org.elasticsearch.common.settings.", "TestClass").getName(), - equalTo(BarTestClass.class.getName())); - - // Assert that class cannot be loaded if wrong packagePrefix is specified - try { - settings.getAsClass("test.class", FooTestClass.class, "com.example.elasticsearch.test.unit..common.settings.", "TestClass"); - fail("Class with wrong package name shouldn't be loaded"); - } catch (NoClassSettingsException ex) { - // Ignore - } - - // Assert that package name in settings is getting correctly applied - assertThat(settings.getAsClass("test.class.package", FooTestClass.class, "com.example.elasticsearch.test.unit.common.settings.", "TestClass").getName(), - equalTo(BarTestClass.class.getName())); - - } - @Test public void testLoadFromDelimitedString() { Settings settings = settingsBuilder() @@ -95,13 +66,6 @@ public class SettingsTests extends ESTestCase { assertThat(settings.toDelimitedString(';'), equalTo("key1=value1;key2=value2;")); } - @Test(expected = NoClassSettingsException.class) - public void testThatAllClassNotFoundExceptionsAreCaught() { - // this should be nGram in order to really work, but for sure not not throw a NoClassDefFoundError - Settings settings = settingsBuilder().put("type", "ngram").build(); - settings.getAsClass("type", null, "org.elasticsearch.index.analysis.", "TokenFilterFactory"); - } - @Test public void testReplacePropertiesPlaceholderSystemProperty() { System.setProperty("sysProp1", "sysVal1"); diff --git a/core/src/test/java/org/elasticsearch/discovery/DiscoveryWithServiceDisruptionsIT.java b/core/src/test/java/org/elasticsearch/discovery/DiscoveryWithServiceDisruptionsIT.java index 2db457c4084..6c466599e66 100644 --- a/core/src/test/java/org/elasticsearch/discovery/DiscoveryWithServiceDisruptionsIT.java +++ b/core/src/test/java/org/elasticsearch/discovery/DiscoveryWithServiceDisruptionsIT.java @@ -143,7 +143,7 @@ public class DiscoveryWithServiceDisruptionsIT extends ESIntegTestCase { .put(DiscoverySettings.PUBLISH_TIMEOUT, "1s") // <-- for hitting simulated network failures quickly .put("http.enabled", false) // just to make test quicker .put("gateway.local.list_timeout", "10s") // still long to induce failures but to long so test won't time out - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, MockTransportService.class.getName()) + .put("plugin.types", MockTransportService.Plugin.class.getName()) .build(); private void configureCluster(int numberOfNodes, int minimumMasterNode) throws ExecutionException, InterruptedException { diff --git a/core/src/test/java/org/elasticsearch/index/IndexWithShadowReplicasIT.java b/core/src/test/java/org/elasticsearch/index/IndexWithShadowReplicasIT.java index 5c6f7b376c7..659b15ed424 100644 --- a/core/src/test/java/org/elasticsearch/index/IndexWithShadowReplicasIT.java +++ b/core/src/test/java/org/elasticsearch/index/IndexWithShadowReplicasIT.java @@ -396,7 +396,7 @@ public class IndexWithShadowReplicasIT extends ESIntegTestCase { Settings nodeSettings = Settings.builder() .put("node.add_id_to_custom_path", false) .put("node.enable_custom_paths", true) - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, MockTransportService.class.getName()) + .put("plugin.types", MockTransportService.Plugin.class.getName()) .build(); String node1 = internalCluster().startNode(nodeSettings); diff --git a/core/src/test/java/org/elasticsearch/index/TransportIndexFailuresIT.java b/core/src/test/java/org/elasticsearch/index/TransportIndexFailuresIT.java index ae2a979202a..7efc56115ce 100644 --- a/core/src/test/java/org/elasticsearch/index/TransportIndexFailuresIT.java +++ b/core/src/test/java/org/elasticsearch/index/TransportIndexFailuresIT.java @@ -56,7 +56,7 @@ public class TransportIndexFailuresIT extends ESIntegTestCase { .put(FaultDetection.SETTING_PING_RETRIES, "1") // <-- for hitting simulated network failures quickly .put(DiscoverySettings.PUBLISH_TIMEOUT, "1s") // <-- for hitting simulated network failures quickly .put("discovery.zen.minimum_master_nodes", 1) - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, MockTransportService.class.getName()) + .put("plugin.types", MockTransportService.Plugin.class.getName()) .build(); @Override diff --git a/core/src/test/java/org/elasticsearch/index/analysis/AnalysisModuleTests.java b/core/src/test/java/org/elasticsearch/index/analysis/AnalysisModuleTests.java index 5757cc7a832..e667afaf5a3 100644 --- a/core/src/test/java/org/elasticsearch/index/analysis/AnalysisModuleTests.java +++ b/core/src/test/java/org/elasticsearch/index/analysis/AnalysisModuleTests.java @@ -67,11 +67,13 @@ public class AnalysisModuleTests extends ESTestCase { public AnalysisService getAnalysisService(Settings settings) { Index index = new Index("test"); Injector parentInjector = new ModulesBuilder().add(new SettingsModule(settings), new EnvironmentModule(new Environment(settings)), new IndicesAnalysisModule()).createInjector(); + AnalysisModule analysisModule = new AnalysisModule(settings, parentInjector.getInstance(IndicesAnalysisService.class)); + analysisModule.addTokenFilter("myfilter", MyFilterTokenFilterFactory.class); injector = new ModulesBuilder().add( new IndexSettingsModule(index, settings), new IndexNameModule(index), - new AnalysisModule(settings, parentInjector.getInstance(IndicesAnalysisService.class))) - .createChildInjector(parentInjector); + analysisModule) + .createChildInjector(parentInjector); return injector.getInstance(AnalysisService.class); } diff --git a/core/src/test/java/org/elasticsearch/index/analysis/AnalyzerBackwardsCompatTests.java b/core/src/test/java/org/elasticsearch/index/analysis/AnalyzerBackwardsCompatTests.java index 43ec10173b5..63acbc81c8d 100644 --- a/core/src/test/java/org/elasticsearch/index/analysis/AnalyzerBackwardsCompatTests.java +++ b/core/src/test/java/org/elasticsearch/index/analysis/AnalyzerBackwardsCompatTests.java @@ -44,6 +44,7 @@ public class AnalyzerBackwardsCompatTests extends ESTokenStreamTestCase { builder.put("path.home", createTempDir().toString()); AnalysisService analysisService = AnalysisTestsHelper.createAnalysisServiceFromSettings(builder.build()); NamedAnalyzer analyzer = analysisService.analyzer("foo"); + assertNotNull(analyzer); if (version.onOrAfter(noStopwordVersion)) { assertAnalyzesTo(analyzer, "this is bogus", new String[]{"this", "is", "bogus"}); } else { diff --git a/core/src/test/java/org/elasticsearch/index/analysis/CompoundAnalysisTests.java b/core/src/test/java/org/elasticsearch/index/analysis/CompoundAnalysisTests.java index e5c79439352..a259dc0d19e 100644 --- a/core/src/test/java/org/elasticsearch/index/analysis/CompoundAnalysisTests.java +++ b/core/src/test/java/org/elasticsearch/index/analysis/CompoundAnalysisTests.java @@ -35,6 +35,7 @@ import org.elasticsearch.env.EnvironmentModule; import org.elasticsearch.index.Index; import org.elasticsearch.index.IndexNameModule; import org.elasticsearch.index.analysis.compound.DictionaryCompoundWordTokenFilterFactory; +import org.elasticsearch.index.analysis.filter1.MyFilterTokenFilterFactory; import org.elasticsearch.index.settings.IndexSettingsModule; import org.elasticsearch.indices.analysis.IndicesAnalysisModule; import org.elasticsearch.indices.analysis.IndicesAnalysisService; @@ -58,10 +59,12 @@ public class CompoundAnalysisTests extends ESTestCase { Index index = new Index("test"); Settings settings = getJsonSettings(); Injector parentInjector = new ModulesBuilder().add(new SettingsModule(settings), new EnvironmentModule(new Environment(settings)), new IndicesAnalysisModule()).createInjector(); + AnalysisModule analysisModule = new AnalysisModule(settings, parentInjector.getInstance(IndicesAnalysisService.class)); + analysisModule.addTokenFilter("myfilter", MyFilterTokenFilterFactory.class); Injector injector = new ModulesBuilder().add( new IndexSettingsModule(index, settings), new IndexNameModule(index), - new AnalysisModule(settings, parentInjector.getInstance(IndicesAnalysisService.class))) + analysisModule) .createChildInjector(parentInjector); AnalysisService analysisService = injector.getInstance(AnalysisService.class); @@ -83,10 +86,12 @@ public class CompoundAnalysisTests extends ESTestCase { private List analyze(Settings settings, String analyzerName, String text) throws IOException { Index index = new Index("test"); Injector parentInjector = new ModulesBuilder().add(new SettingsModule(settings), new EnvironmentModule(new Environment(settings)), new IndicesAnalysisModule()).createInjector(); + AnalysisModule analysisModule = new AnalysisModule(settings, parentInjector.getInstance(IndicesAnalysisService.class)); + analysisModule.addTokenFilter("myfilter", MyFilterTokenFilterFactory.class); Injector injector = new ModulesBuilder().add( new IndexSettingsModule(index, settings), new IndexNameModule(index), - new AnalysisModule(settings, parentInjector.getInstance(IndicesAnalysisService.class))) + analysisModule) .createChildInjector(parentInjector); AnalysisService analysisService = injector.getInstance(AnalysisService.class); diff --git a/core/src/test/java/org/elasticsearch/index/analysis/test1.json b/core/src/test/java/org/elasticsearch/index/analysis/test1.json index 69be6db8f82..927d0704d1f 100644 --- a/core/src/test/java/org/elasticsearch/index/analysis/test1.json +++ b/core/src/test/java/org/elasticsearch/index/analysis/test1.json @@ -32,7 +32,7 @@ "stopwords":["stop2-1", "stop2-2"] }, "my":{ - "type":"org.elasticsearch.index.analysis.filter1.MyFilterTokenFilterFactory" + "type":"myfilter" }, "dict_dec":{ "type":"dictionary_decompounder", diff --git a/core/src/test/java/org/elasticsearch/index/analysis/test1.yml b/core/src/test/java/org/elasticsearch/index/analysis/test1.yml index 81ef2353103..518ef2c5f43 100644 --- a/core/src/test/java/org/elasticsearch/index/analysis/test1.yml +++ b/core/src/test/java/org/elasticsearch/index/analysis/test1.yml @@ -23,7 +23,7 @@ index : type : stop stopwords : [stop2-1, stop2-2] my : - type : org.elasticsearch.index.analysis.filter1.MyFilterTokenFilterFactory + type : myfilter dict_dec : type : dictionary_decompounder word_list : [donau, dampf, schiff, spargel, creme, suppe] diff --git a/core/src/test/java/org/elasticsearch/index/query/TemplateQueryParserTest.java b/core/src/test/java/org/elasticsearch/index/query/TemplateQueryParserTest.java index ccb9cd11139..cee5bd70ad9 100644 --- a/core/src/test/java/org/elasticsearch/index/query/TemplateQueryParserTest.java +++ b/core/src/test/java/org/elasticsearch/index/query/TemplateQueryParserTest.java @@ -40,6 +40,7 @@ import org.elasticsearch.index.cache.IndexCacheModule; import org.elasticsearch.index.query.functionscore.FunctionScoreModule; import org.elasticsearch.index.settings.IndexSettingsModule; import org.elasticsearch.index.similarity.SimilarityModule; +import org.elasticsearch.indices.analysis.IndicesAnalysisService; import org.elasticsearch.indices.breaker.CircuitBreakerService; import org.elasticsearch.indices.breaker.NoneCircuitBreakerService; import org.elasticsearch.indices.query.IndicesQueriesModule; @@ -80,7 +81,7 @@ public class TemplateQueryParserTest extends ESTestCase { new ScriptModule(settings), new IndexSettingsModule(index, settings), new IndexCacheModule(settings), - new AnalysisModule(settings), + new AnalysisModule(settings, new IndicesAnalysisService(settings)), new SimilarityModule(settings), new IndexNameModule(index), new FunctionScoreModule(), diff --git a/core/src/test/java/org/elasticsearch/index/store/CorruptedFileIT.java b/core/src/test/java/org/elasticsearch/index/store/CorruptedFileIT.java index 1692eb50499..4a2f560c4f4 100644 --- a/core/src/test/java/org/elasticsearch/index/store/CorruptedFileIT.java +++ b/core/src/test/java/org/elasticsearch/index/store/CorruptedFileIT.java @@ -98,7 +98,7 @@ public class CorruptedFileIT extends ESIntegTestCase { // we really need local GW here since this also checks for corruption etc. // and we need to make sure primaries are not just trashed if we don't have replicas .put(super.nodeSettings(nodeOrdinal)) - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, MockTransportService.class.getName()) + .extendArray("plugin.types", MockTransportService.Plugin.class.getName()) // speed up recoveries .put(RecoverySettings.INDICES_RECOVERY_CONCURRENT_STREAMS, 10) .put(RecoverySettings.INDICES_RECOVERY_CONCURRENT_SMALL_FILE_STREAMS, 10) diff --git a/core/src/test/java/org/elasticsearch/index/store/CorruptedTranslogIT.java b/core/src/test/java/org/elasticsearch/index/store/CorruptedTranslogIT.java index 5b3227c8a8e..ec5d24254a1 100644 --- a/core/src/test/java/org/elasticsearch/index/store/CorruptedTranslogIT.java +++ b/core/src/test/java/org/elasticsearch/index/store/CorruptedTranslogIT.java @@ -66,7 +66,7 @@ public class CorruptedTranslogIT extends ESIntegTestCase { // we really need local GW here since this also checks for corruption etc. // and we need to make sure primaries are not just trashed if we don't have replicas .put(super.nodeSettings(nodeOrdinal)) - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, MockTransportService.class.getName()).build(); + .extendArray("plugin.types", MockTransportService.Plugin.class.getName()).build(); } @Test diff --git a/core/src/test/java/org/elasticsearch/index/store/ExceptionRetryIT.java b/core/src/test/java/org/elasticsearch/index/store/ExceptionRetryIT.java index c42e320c6d8..bd2adc1e579 100644 --- a/core/src/test/java/org/elasticsearch/index/store/ExceptionRetryIT.java +++ b/core/src/test/java/org/elasticsearch/index/store/ExceptionRetryIT.java @@ -54,7 +54,7 @@ public class ExceptionRetryIT extends ESIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, MockTransportService.class.getName()) + .extendArray("plugin.types", MockTransportService.Plugin.class.getName()) .build(); } diff --git a/core/src/test/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java b/core/src/test/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java index c8e582a5825..a6263eee9d5 100644 --- a/core/src/test/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java +++ b/core/src/test/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java @@ -519,7 +519,7 @@ public class IndexRecoveryIT extends ESIntegTestCase { final Settings nodeSettings = Settings.builder() .put(RecoverySettings.INDICES_RECOVERY_RETRY_DELAY_NETWORK, "100ms") .put(RecoverySettings.INDICES_RECOVERY_INTERNAL_ACTION_TIMEOUT, "1s") - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, MockTransportService.class.getName()) + .put("plugin.types", MockTransportService.Plugin.class.getName()) .put(MockFSDirectoryService.RANDOM_PREVENT_DOUBLE_WRITE, false) // restarted recoveries will delete temp files and write them again .build(); // start a master node diff --git a/core/src/test/java/org/elasticsearch/indices/store/IndicesStoreIntegrationIT.java b/core/src/test/java/org/elasticsearch/indices/store/IndicesStoreIntegrationIT.java index db999cd479d..8417b227845 100644 --- a/core/src/test/java/org/elasticsearch/indices/store/IndicesStoreIntegrationIT.java +++ b/core/src/test/java/org/elasticsearch/indices/store/IndicesStoreIntegrationIT.java @@ -87,7 +87,7 @@ public class IndicesStoreIntegrationIT extends ESIntegTestCase { // which is between 1 and 2 sec can cause each of the shard deletion requests to timeout. // to prevent this we are setting the timeout here to something highish ie. the default in practice .put(IndicesStore.INDICES_STORE_DELETE_SHARD_TIMEOUT, new TimeValue(30, TimeUnit.SECONDS)) - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, MockTransportService.class.getName()) + .extendArray("plugin.types", MockTransportService.Plugin.class.getName()) .build(); } diff --git a/core/src/test/java/org/elasticsearch/recovery/RelocationIT.java b/core/src/test/java/org/elasticsearch/recovery/RelocationIT.java index cc92e494e1d..c73baac193e 100644 --- a/core/src/test/java/org/elasticsearch/recovery/RelocationIT.java +++ b/core/src/test/java/org/elasticsearch/recovery/RelocationIT.java @@ -102,7 +102,7 @@ public class RelocationIT extends ESIntegTestCase { @Override protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, MockTransportService.class.getName()).build(); + .put("plugin.types", MockTransportService.Plugin.class.getName()).build(); } diff --git a/core/src/test/java/org/elasticsearch/recovery/TruncatedRecoveryIT.java b/core/src/test/java/org/elasticsearch/recovery/TruncatedRecoveryIT.java index 335da8601d9..c8943d1ff27 100644 --- a/core/src/test/java/org/elasticsearch/recovery/TruncatedRecoveryIT.java +++ b/core/src/test/java/org/elasticsearch/recovery/TruncatedRecoveryIT.java @@ -58,7 +58,7 @@ public class TruncatedRecoveryIT extends ESIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { Settings.Builder builder = Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, MockTransportService.class.getName()) + .extendArray("plugin.types", MockTransportService.Plugin.class.getName()) .put(RecoverySettings.INDICES_RECOVERY_FILE_CHUNK_SIZE, new ByteSizeValue(randomIntBetween(50, 300), ByteSizeUnit.BYTES)); return builder.build(); } diff --git a/core/src/test/java/org/elasticsearch/script/NativeScriptTests.java b/core/src/test/java/org/elasticsearch/script/NativeScriptTests.java index 490bcefebcc..2ad584bfec5 100644 --- a/core/src/test/java/org/elasticsearch/script/NativeScriptTests.java +++ b/core/src/test/java/org/elasticsearch/script/NativeScriptTests.java @@ -29,6 +29,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.env.Environment; import org.elasticsearch.env.EnvironmentModule; +import org.elasticsearch.plugins.AbstractPlugin; import org.elasticsearch.script.ScriptService.ScriptType; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.threadpool.ThreadPool; @@ -49,15 +50,16 @@ public class NativeScriptTests extends ESTestCase { @Test public void testNativeScript() throws InterruptedException { Settings settings = Settings.settingsBuilder() - .put("script.native.my.type", MyNativeScriptFactory.class.getName()) .put("name", "testNativeScript") .put("path.home", createTempDir()) .build(); + ScriptModule scriptModule = new ScriptModule(settings); + scriptModule.registerScript("my", MyNativeScriptFactory.class); Injector injector = new ModulesBuilder().add( new EnvironmentModule(new Environment(settings)), new ThreadPoolModule(new ThreadPool(settings)), new SettingsModule(settings), - new ScriptModule(settings)).createInjector(); + scriptModule).createInjector(); ScriptService scriptService = injector.getInstance(ScriptService.class); diff --git a/core/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java b/core/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java index 7aedb958630..75e910f48dd 100644 --- a/core/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java +++ b/core/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java @@ -34,6 +34,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.snapshots.mockstore.MockRepository; +import org.elasticsearch.snapshots.mockstore.MockRepositoryPlugin; import org.elasticsearch.test.ESIntegTestCase; import java.io.IOException; @@ -47,11 +48,18 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import static org.elasticsearch.common.settings.Settings.settingsBuilder; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThanOrEqualTo; public abstract class AbstractSnapshotIntegTestCase extends ESIntegTestCase { + @Override + protected Settings nodeSettings(int nodeOrdinal) { + return settingsBuilder().put(super.nodeSettings(nodeOrdinal)) + .extendArray("plugin.types", MockRepositoryPlugin.class.getName()).build(); + } + public static long getFailureCount(String repository) { long failureCount = 0; for (RepositoriesService repositoriesService : internalCluster().getDataNodeInstances(RepositoriesService.class)) { diff --git a/core/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java b/core/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java index 6f4e4e217d8..fa0ebdec5a0 100644 --- a/core/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java +++ b/core/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java @@ -303,7 +303,7 @@ public class DedicatedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTest logger.info("--> create repository"); logger.info("--> creating repository"); PutRepositoryResponse putRepositoryResponse = client.admin().cluster().preparePutRepository("test-repo") - .setType(MockRepositoryModule.class.getCanonicalName()).setSettings( + .setType("mock").setSettings( Settings.settingsBuilder() .put("location", randomRepoPath()) .put("random", randomAsciiOfLength(10)) @@ -352,7 +352,7 @@ public class DedicatedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTest logger.info("--> creating repository"); Path repo = randomRepoPath(); PutRepositoryResponse putRepositoryResponse = client.admin().cluster().preparePutRepository("test-repo") - .setType(MockRepositoryModule.class.getCanonicalName()).setSettings( + .setType("mock").setSettings( Settings.settingsBuilder() .put("location", repo) .put("random", randomAsciiOfLength(10)) diff --git a/core/src/test/java/org/elasticsearch/snapshots/RepositoriesIT.java b/core/src/test/java/org/elasticsearch/snapshots/RepositoriesIT.java index 1ea8c68f778..27a67588df9 100644 --- a/core/src/test/java/org/elasticsearch/snapshots/RepositoriesIT.java +++ b/core/src/test/java/org/elasticsearch/snapshots/RepositoriesIT.java @@ -33,12 +33,14 @@ import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.repositories.RepositoryException; import org.elasticsearch.repositories.RepositoryVerificationException; import org.elasticsearch.snapshots.mockstore.MockRepositoryModule; +import org.elasticsearch.snapshots.mockstore.MockRepositoryPlugin; import org.elasticsearch.test.ESIntegTestCase; import org.junit.Test; import java.nio.file.Path; import java.util.List; +import static org.elasticsearch.common.settings.Settings.settingsBuilder; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertThrows; import static org.hamcrest.Matchers.containsString; @@ -211,12 +213,12 @@ public class RepositoriesIT extends AbstractSnapshotIntegTestCase { .put("random_control_io_exception_rate", 1.0).build(); logger.info("--> creating repository that cannot write any files - should fail"); assertThrows(client.admin().cluster().preparePutRepository("test-repo-1") - .setType(MockRepositoryModule.class.getCanonicalName()).setSettings(settings), + .setType("mock").setSettings(settings), RepositoryVerificationException.class); logger.info("--> creating repository that cannot write any files, but suppress verification - should be acked"); assertAcked(client.admin().cluster().preparePutRepository("test-repo-1") - .setType(MockRepositoryModule.class.getCanonicalName()).setSettings(settings).setVerify(false)); + .setType("mock").setSettings(settings).setVerify(false)); logger.info("--> verifying repository"); assertThrows(client.admin().cluster().prepareVerifyRepository("test-repo-1"), RepositoryVerificationException.class); @@ -226,7 +228,7 @@ public class RepositoriesIT extends AbstractSnapshotIntegTestCase { logger.info("--> creating repository"); try { client.admin().cluster().preparePutRepository("test-repo-1") - .setType(MockRepositoryModule.class.getCanonicalName()) + .setType("mock") .setSettings(Settings.settingsBuilder() .put("location", location) .put("localize_location", true) @@ -246,12 +248,12 @@ public class RepositoriesIT extends AbstractSnapshotIntegTestCase { .put("random_control_io_exception_rate", 1.0).build(); logger.info("--> creating repository that cannot write any files - should fail"); assertThrows(client.admin().cluster().preparePutRepository("test-repo-1") - .setType(MockRepositoryModule.class.getCanonicalName()).setSettings(settings), + .setType("mock").setSettings(settings), RepositoryVerificationException.class); logger.info("--> creating repository that cannot write any files, but suppress verification - should be acked"); assertAcked(client.admin().cluster().preparePutRepository("test-repo-1") - .setType(MockRepositoryModule.class.getCanonicalName()).setSettings(settings).setVerify(false)); + .setType("mock").setSettings(settings).setVerify(false)); logger.info("--> verifying repository"); assertThrows(client.admin().cluster().prepareVerifyRepository("test-repo-1"), RepositoryVerificationException.class); @@ -261,7 +263,7 @@ public class RepositoriesIT extends AbstractSnapshotIntegTestCase { logger.info("--> creating repository"); try { client.admin().cluster().preparePutRepository("test-repo-1") - .setType(MockRepositoryModule.class.getCanonicalName()) + .setType("mock") .setSettings(Settings.settingsBuilder() .put("location", location) .put("localize_location", true) diff --git a/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java index 85fd0c7c2f5..380c301a5a5 100644 --- a/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java +++ b/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java @@ -535,7 +535,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas logger.info("--> creating repository"); assertAcked(client.admin().cluster().preparePutRepository("test-repo") - .setType(MockRepositoryModule.class.getCanonicalName()).setSettings( + .setType("mock").setSettings( Settings.settingsBuilder() .put("location", randomRepoPath()) .put("random", randomAsciiOfLength(10)) @@ -585,7 +585,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas Client client = client(); logger.info("--> creating repository"); assertAcked(client.admin().cluster().preparePutRepository("test-repo") - .setType(MockRepositoryModule.class.getCanonicalName()).setSettings( + .setType("mock").setSettings( Settings.settingsBuilder() .put("location", randomRepoPath()) .put("random", randomAsciiOfLength(10)) @@ -672,7 +672,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas logger.info("--> update repository with mock version"); assertAcked(client.admin().cluster().preparePutRepository("test-repo") - .setType(MockRepositoryModule.class.getCanonicalName()).setSettings( + .setType("mock").setSettings( Settings.settingsBuilder() .put("location", repositoryLocation) .put("random", randomAsciiOfLength(10)) @@ -714,7 +714,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas logger.info("--> update repository with mock version"); assertAcked(client.admin().cluster().preparePutRepository("test-repo") - .setType(MockRepositoryModule.class.getCanonicalName()).setSettings( + .setType("mock").setSettings( Settings.settingsBuilder() .put("location", repositoryLocation) .put("random", randomAsciiOfLength(10)) @@ -1121,7 +1121,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas Path repositoryLocation = randomRepoPath(); logger.info("--> creating repository"); assertAcked(client.admin().cluster().preparePutRepository("test-repo") - .setType(MockRepositoryModule.class.getCanonicalName()).setSettings( + .setType("mock").setSettings( Settings.settingsBuilder() .put("location", repositoryLocation) .put("random", randomAsciiOfLength(10)) @@ -1183,7 +1183,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas Path repositoryLocation = randomRepoPath(); logger.info("--> creating repository"); PutRepositoryResponse putRepositoryResponse = client.admin().cluster().preparePutRepository("test-repo") - .setType(MockRepositoryModule.class.getCanonicalName()).setSettings( + .setType("mock").setSettings( Settings.settingsBuilder() .put("location", repositoryLocation) .put("random", randomAsciiOfLength(10)) @@ -1384,7 +1384,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas Path repositoryLocation = randomRepoPath(); logger.info("--> creating repository"); PutRepositoryResponse putRepositoryResponse = client.admin().cluster().preparePutRepository("test-repo") - .setType(MockRepositoryModule.class.getCanonicalName()).setSettings( + .setType("mock").setSettings( Settings.settingsBuilder() .put("location", repositoryLocation) .put("random", randomAsciiOfLength(10)) @@ -1711,7 +1711,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas logger.info("--> creating repository"); assertAcked(client.admin().cluster().preparePutRepository("test-repo") - .setType(MockRepositoryModule.class.getCanonicalName()).setSettings(Settings.settingsBuilder() + .setType("mock").setSettings(Settings.settingsBuilder() .put("location", randomRepoPath()) .put("compress", randomBoolean()) .put("chunk_size", randomIntBetween(100, 1000), ByteSizeUnit.BYTES) @@ -1763,7 +1763,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas logger.info("--> creating repository"); assertAcked(client.admin().cluster().preparePutRepository("test-repo") - .setType(MockRepositoryModule.class.getCanonicalName()).setSettings(Settings.settingsBuilder() + .setType("mock").setSettings(Settings.settingsBuilder() .put("location", randomRepoPath()) .put("compress", randomBoolean()) .put("chunk_size", randomIntBetween(100, 1000), ByteSizeUnit.BYTES) diff --git a/core/src/test/java/org/elasticsearch/test/ESBackcompatTestCase.java b/core/src/test/java/org/elasticsearch/test/ESBackcompatTestCase.java index 1468efed8bc..4fab1c0bb3d 100644 --- a/core/src/test/java/org/elasticsearch/test/ESBackcompatTestCase.java +++ b/core/src/test/java/org/elasticsearch/test/ESBackcompatTestCase.java @@ -19,6 +19,7 @@ package org.elasticsearch.test; import com.carrotsearch.randomizedtesting.annotations.TestGroup; +import org.apache.commons.lang3.ArrayUtils; import org.elasticsearch.Version; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.routing.IndexRoutingTable; @@ -31,6 +32,8 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.test.junit.annotations.TestLogging; import org.elasticsearch.test.junit.listeners.LoggingListener; +import org.elasticsearch.test.transport.AssertingLocalTransport; +import org.elasticsearch.test.transport.MockTransportService; import org.elasticsearch.transport.Transport; import org.elasticsearch.transport.TransportModule; import org.elasticsearch.transport.TransportService; @@ -247,9 +250,10 @@ public abstract class ESBackcompatTestCase extends ESIntegTestCase { } protected Settings commonNodeSettings(int nodeOrdinal) { - Settings.Builder builder = Settings.builder().put(requiredSettings()) - .put(TransportModule.TRANSPORT_TYPE_KEY, NettyTransport.class.getName()) // run same transport / disco as external - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, TransportService.class.getName()); + Settings.Builder builder = Settings.builder().put(requiredSettings()); + builder.removeArrayElement("plugin.types", MockTransportService.Plugin.class.getName()); + builder.removeArrayElement("plugin.types", AssertingLocalTransport.class.getName()); + builder.put(TransportModule.TRANSPORT_TYPE_KEY, "netty"); // run same transport / disco as external if (compatibilityVersion().before(Version.V_1_3_2)) { // if we test against nodes before 1.3.2 we disable all the compression due to a known bug // see #7210 diff --git a/core/src/test/java/org/elasticsearch/test/InternalTestCluster.java b/core/src/test/java/org/elasticsearch/test/InternalTestCluster.java index 189a813bbf0..eeaa810c7c9 100644 --- a/core/src/test/java/org/elasticsearch/test/InternalTestCluster.java +++ b/core/src/test/java/org/elasticsearch/test/InternalTestCluster.java @@ -26,11 +26,15 @@ import com.carrotsearch.randomizedtesting.generators.RandomPicks; import com.carrotsearch.randomizedtesting.generators.RandomStrings; import com.google.common.base.Predicate; import com.google.common.base.Predicates; -import com.google.common.collect.*; +import com.google.common.collect.Collections2; +import com.google.common.collect.Iterables; +import com.google.common.collect.Iterators; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; - import org.apache.lucene.store.StoreRateLimiting; import org.apache.lucene.util.IOUtils; import org.elasticsearch.ElasticsearchException; @@ -97,17 +101,17 @@ import org.elasticsearch.node.service.NodeService; import org.elasticsearch.script.ScriptService; import org.elasticsearch.search.SearchService; import org.elasticsearch.search.SearchServiceModule; -import org.elasticsearch.test.cache.recycler.MockBigArraysModule; -import org.elasticsearch.test.cache.recycler.MockPageCacheRecyclerModule; +import org.elasticsearch.test.cache.recycler.MockBigArrays; +import org.elasticsearch.test.cache.recycler.MockPageCacheRecycler; import org.elasticsearch.test.disruption.ServiceDisruptionScheme; import org.elasticsearch.test.engine.MockEngineFactory; -import org.elasticsearch.test.search.MockSearchServiceModule; +import org.elasticsearch.test.search.MockSearchService; +import org.elasticsearch.test.store.MockFSIndexStore; import org.elasticsearch.test.store.MockFSIndexStoreModule; import org.elasticsearch.test.transport.AssertingLocalTransport; import org.elasticsearch.test.transport.MockTransportService; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.Transport; -import org.elasticsearch.transport.TransportModule; import org.elasticsearch.transport.TransportService; import org.elasticsearch.transport.netty.NettyTransport; import org.junit.Assert; @@ -116,20 +120,35 @@ import java.io.Closeable; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.file.Path; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NavigableMap; +import java.util.Random; +import java.util.Set; +import java.util.TreeMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import static junit.framework.Assert.fail; -import static org.apache.lucene.util.LuceneTestCase.*; +import static org.apache.lucene.util.LuceneTestCase.TEST_NIGHTLY; +import static org.apache.lucene.util.LuceneTestCase.rarely; +import static org.apache.lucene.util.LuceneTestCase.usually; import static org.elasticsearch.common.settings.Settings.settingsBuilder; import static org.elasticsearch.node.NodeBuilder.nodeBuilder; import static org.elasticsearch.test.ESTestCase.assertBusy; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoTimeout; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertFalse; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.junit.Assert.assertThat; /** @@ -373,15 +392,14 @@ public final class InternalTestCluster extends TestCluster { Builder builder = Settings.settingsBuilder() .put(SETTING_CLUSTER_NODE_SEED, seed); if (ENABLE_MOCK_MODULES && usually(random)) { - builder.put(IndexStoreModule.STORE_TYPE, MockFSIndexStoreModule.class.getName()); + builder.extendArray("plugin.types", MockTransportService.Plugin.class.getName(), MockFSIndexStore.Plugin.class.getName()); builder.put(IndexShardModule.ENGINE_FACTORY, MockEngineFactory.class); - builder.put(PageCacheRecyclerModule.CACHE_IMPL, MockPageCacheRecyclerModule.class.getName()); - builder.put(BigArraysModule.IMPL, MockBigArraysModule.class.getName()); - builder.put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, MockTransportService.class.getName()); - builder.put(SearchServiceModule.IMPL, MockSearchServiceModule.class.getName()); + builder.put(PageCacheRecyclerModule.CACHE_IMPL, MockPageCacheRecycler.class.getName()); + builder.put(BigArraysModule.IMPL, MockBigArrays.class.getName()); + builder.put(SearchServiceModule.IMPL, MockSearchService.class.getName()); } if (isLocalTransportConfigured()) { - builder.put(TransportModule.TRANSPORT_TYPE_KEY, AssertingLocalTransport.class.getName()); + builder.extendArray("plugin.types", AssertingLocalTransport.Plugin.class.getName()); } else { builder.put(Transport.TransportSettings.TRANSPORT_TCP_COMPRESS, rarely(random)); } diff --git a/core/src/test/java/org/elasticsearch/test/cache/recycler/MockBigArraysModule.java b/core/src/test/java/org/elasticsearch/test/cache/recycler/MockBigArraysModule.java deleted file mode 100644 index e5b48a318d7..00000000000 --- a/core/src/test/java/org/elasticsearch/test/cache/recycler/MockBigArraysModule.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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.test.cache.recycler; - -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.util.BigArrays; - -public class MockBigArraysModule extends AbstractModule { - - @Override - protected void configure() { - bind(BigArrays.class).to(MockBigArrays.class).asEagerSingleton(); - } - -} diff --git a/core/src/test/java/org/elasticsearch/test/cache/recycler/MockPageCacheRecyclerModule.java b/core/src/test/java/org/elasticsearch/test/cache/recycler/MockPageCacheRecyclerModule.java deleted file mode 100644 index 339fb949699..00000000000 --- a/core/src/test/java/org/elasticsearch/test/cache/recycler/MockPageCacheRecyclerModule.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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.test.cache.recycler; - -import org.elasticsearch.cache.recycler.PageCacheRecycler; -import org.elasticsearch.common.inject.AbstractModule; - -public class MockPageCacheRecyclerModule extends AbstractModule { - - @Override - protected void configure() { - bind(PageCacheRecycler.class).to(MockPageCacheRecycler.class).asEagerSingleton(); - } - -} diff --git a/core/src/test/java/org/elasticsearch/test/disruption/NetworkPartitionIT.java b/core/src/test/java/org/elasticsearch/test/disruption/NetworkPartitionIT.java index 84aa300fb84..a1ec62b64fa 100644 --- a/core/src/test/java/org/elasticsearch/test/disruption/NetworkPartitionIT.java +++ b/core/src/test/java/org/elasticsearch/test/disruption/NetworkPartitionIT.java @@ -35,7 +35,7 @@ public class NetworkPartitionIT extends ESIntegTestCase { @Override protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() - .put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, MockTransportService.class.getName()) + .put("plugin.types", MockTransportService.Plugin.class.getName()) .build(); } diff --git a/core/src/test/java/org/elasticsearch/test/engine/MockEngineSupport.java b/core/src/test/java/org/elasticsearch/test/engine/MockEngineSupport.java index e448bfa070f..78b0439c593 100644 --- a/core/src/test/java/org/elasticsearch/test/engine/MockEngineSupport.java +++ b/core/src/test/java/org/elasticsearch/test/engine/MockEngineSupport.java @@ -29,6 +29,7 @@ import org.apache.lucene.search.QueryCachingPolicy; import org.apache.lucene.search.SearcherManager; import org.apache.lucene.util.LuceneTestCase; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.common.Classes; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Settings; @@ -87,7 +88,13 @@ public final class MockEngineSupport { final long seed = indexSettings.getAsLong(ESIntegTestCase.SETTING_INDEX_SEED, 0l); Random random = new Random(seed); final double ratio = indexSettings.getAsDouble(WRAP_READER_RATIO, 0.0d); // DISABLED by default - AssertingDR is crazy slow - Class wrapper = indexSettings.getAsClass(READER_WRAPPER_TYPE, AssertingDirectoryReader.class); + String readerWrapperType = indexSettings.get(READER_WRAPPER_TYPE); + Class wrapper; + if (readerWrapperType == null) { + wrapper = AssertingDirectoryReader.class; + } else { + wrapper = Classes.loadClass(getClass().getClassLoader(), readerWrapperType); + } boolean wrapReader = random.nextDouble() < ratio; if (logger.isTraceEnabled()) { logger.trace("Using [{}] for shard [{}] seed: [{}] wrapReader: [{}]", this.getClass().getName(), shardId, seed, wrapReader); diff --git a/core/src/test/java/org/elasticsearch/test/search/MockSearchServiceModule.java b/core/src/test/java/org/elasticsearch/test/search/MockSearchServiceModule.java deleted file mode 100644 index 896c403bd1d..00000000000 --- a/core/src/test/java/org/elasticsearch/test/search/MockSearchServiceModule.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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.test.search; - -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.search.SearchService; - -public class MockSearchServiceModule extends AbstractModule { - - @Override - protected void configure() { - bind(SearchService.class).to(MockSearchService.class).asEagerSingleton(); - } - -} diff --git a/core/src/test/java/org/elasticsearch/test/store/MockFSIndexStore.java b/core/src/test/java/org/elasticsearch/test/store/MockFSIndexStore.java index 2020c9f2710..47b0baa7c54 100644 --- a/core/src/test/java/org/elasticsearch/test/store/MockFSIndexStore.java +++ b/core/src/test/java/org/elasticsearch/test/store/MockFSIndexStore.java @@ -26,10 +26,30 @@ import org.elasticsearch.index.settings.IndexSettings; import org.elasticsearch.index.settings.IndexSettingsService; import org.elasticsearch.index.store.DirectoryService; import org.elasticsearch.index.store.IndexStore; +import org.elasticsearch.index.store.IndexStoreModule; import org.elasticsearch.indices.store.IndicesStore; +import org.elasticsearch.plugins.AbstractPlugin; public class MockFSIndexStore extends IndexStore { + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "mock-index-store"; + } + @Override + public String description() { + return "a mock index store for testing"; + } + public void onModule(IndexStoreModule indexStoreModule) { + indexStoreModule.addIndexStore("mock", MockFSIndexStore.class); + } + @Override + public Settings additionalSettings() { + return Settings.builder().put(IndexStoreModule.STORE_TYPE, "mock").build(); + } + } + @Inject public MockFSIndexStore(Index index, @IndexSettings Settings indexSettings, IndexSettingsService indexSettingsService, IndicesStore indicesStore) { diff --git a/core/src/test/java/org/elasticsearch/test/transport/AssertingLocalTransport.java b/core/src/test/java/org/elasticsearch/test/transport/AssertingLocalTransport.java index 1229f9e65ec..7bda47b94c8 100644 --- a/core/src/test/java/org/elasticsearch/test/transport/AssertingLocalTransport.java +++ b/core/src/test/java/org/elasticsearch/test/transport/AssertingLocalTransport.java @@ -24,6 +24,7 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.plugins.AbstractPlugin; import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.VersionUtils; import org.elasticsearch.test.hamcrest.ElasticsearchAssertions; @@ -34,11 +35,26 @@ import org.elasticsearch.transport.local.LocalTransport; import java.io.IOException; import java.util.Random; -/** - * - */ public class AssertingLocalTransport extends LocalTransport { + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "asserting-local-transport"; + } + @Override + public String description() { + return "an asserting transport for testing"; + } + public void onModule(TransportModule transportModule) { + transportModule.addTransport("mock", AssertingLocalTransport.class); + } + @Override + public Settings additionalSettings() { + return Settings.builder().put(TransportModule.TRANSPORT_TYPE_KEY, "mock").build(); + } + } + public static final String ASSERTING_TRANSPORT_MIN_VERSION_KEY = "transport.asserting.version.min"; public static final String ASSERTING_TRANSPORT_MAX_VERSION_KEY = "transport.asserting.version.max"; private final Random random; diff --git a/core/src/test/java/org/elasticsearch/test/transport/MockTransportService.java b/core/src/test/java/org/elasticsearch/test/transport/MockTransportService.java index 2a566a1ff53..ce381af6263 100644 --- a/core/src/test/java/org/elasticsearch/test/transport/MockTransportService.java +++ b/core/src/test/java/org/elasticsearch/test/transport/MockTransportService.java @@ -32,6 +32,7 @@ import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.AbstractRunnable; import org.elasticsearch.common.util.concurrent.ConcurrentCollections; +import org.elasticsearch.plugins.AbstractPlugin; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.*; @@ -45,6 +46,24 @@ import java.util.concurrent.CopyOnWriteArrayList; */ public class MockTransportService extends TransportService { + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "mock-transport-service"; + } + @Override + public String description() { + return "a mock transport service for testing"; + } + public void onModule(TransportModule transportModule) { + transportModule.addTransportService("mock", MockTransportService.class); + } + @Override + public Settings additionalSettings() { + return Settings.builder().put(TransportModule.TRANSPORT_SERVICE_TYPE_KEY, "mock").build(); + } + } + private final Transport original; @Inject diff --git a/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportIT.java b/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportIT.java index f53f3e07f5f..ad38b4c8925 100644 --- a/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportIT.java +++ b/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportIT.java @@ -33,6 +33,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.common.util.concurrent.AbstractRunnable; +import org.elasticsearch.plugins.AbstractPlugin; import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.ActionNotFoundTransportException; @@ -66,7 +67,7 @@ public class NettyTransportIT extends ESIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { return settingsBuilder().put(super.nodeSettings(nodeOrdinal)) .put("node.mode", "network") - .put(TransportModule.TRANSPORT_TYPE_KEY, ExceptionThrowingNettyTransport.class.getName()).build(); + .extendArray("plugin.types", ExceptionThrowingNettyTransport.Plugin.class.getName()).build(); } @Test @@ -86,6 +87,24 @@ public class NettyTransportIT extends ESIntegTestCase { public static final class ExceptionThrowingNettyTransport extends NettyTransport { + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "exception-throwing-netty-transport"; + } + @Override + public String description() { + return "an exception throwing transport for testing"; + } + public void onModule(TransportModule transportModule) { + transportModule.addTransport("exception-throwing", ExceptionThrowingNettyTransport.class); + } + @Override + public Settings additionalSettings() { + return Settings.builder().put(TransportModule.TRANSPORT_TYPE_KEY, "exception-throwing").build(); + } + } + @Inject public ExceptionThrowingNettyTransport(Settings settings, ThreadPool threadPool, NetworkService networkService, BigArrays bigArrays, Version version, NamedWriteableRegistry namedWriteableRegistry) { super(settings, threadPool, networkService, bigArrays, version, namedWriteableRegistry); diff --git a/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java b/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java index 7e883c9fb09..132462e875d 100644 --- a/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java +++ b/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java @@ -52,7 +52,7 @@ public class NettyTransportMultiPortIntegrationIT extends ESIntegTestCase { return settingsBuilder() .put(super.nodeSettings(nodeOrdinal)) .put("network.host", "127.0.0.1") - .put(TransportModule.TRANSPORT_TYPE_KEY, NettyTransport.class.getName()) + .put(TransportModule.TRANSPORT_TYPE_KEY, "netty") .put("node.mode", "network") .put("transport.profiles.client1.port", randomPortRange) .put("transport.profiles.client1.publish_host", "127.0.0.7") @@ -65,7 +65,7 @@ public class NettyTransportMultiPortIntegrationIT extends ESIntegTestCase { public void testThatTransportClientCanConnect() throws Exception { Settings settings = settingsBuilder() .put("cluster.name", internalCluster().getClusterName()) - .put(TransportModule.TRANSPORT_TYPE_KEY, NettyTransport.class.getName()) + .put(TransportModule.TRANSPORT_TYPE_KEY, "netty") .put("path.home", createTempDir().toString()) .build(); try (TransportClient transportClient = TransportClient.builder().settings(settings).loadConfigSettings(false).build()) { diff --git a/core/src/test/java/org/elasticsearch/update/UpdateByNativeScriptIT.java b/core/src/test/java/org/elasticsearch/update/UpdateByNativeScriptIT.java index d3284d88eb4..8a7279261f0 100644 --- a/core/src/test/java/org/elasticsearch/update/UpdateByNativeScriptIT.java +++ b/core/src/test/java/org/elasticsearch/update/UpdateByNativeScriptIT.java @@ -22,11 +22,13 @@ import com.google.common.collect.Maps; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.plugins.AbstractPlugin; import org.elasticsearch.script.AbstractExecutableScript; import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.NativeScriptEngineService; import org.elasticsearch.script.NativeScriptFactory; import org.elasticsearch.script.Script; +import org.elasticsearch.script.ScriptModule; import org.elasticsearch.script.ScriptService; import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; @@ -48,7 +50,7 @@ public class UpdateByNativeScriptIT extends ESIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.settingsBuilder() .put(super.nodeSettings(nodeOrdinal)) - .put("script.native.custom.type", CustomNativeScriptFactory.class.getName()) + .extendArray("plugin.types", CustomNativeScriptFactory.Plugin.class.getName()) .build(); } @@ -69,7 +71,20 @@ public class UpdateByNativeScriptIT extends ESIntegTestCase { assertThat(data.get("foo").toString(), is("SETVALUE")); } - static class CustomNativeScriptFactory implements NativeScriptFactory { + public static class CustomNativeScriptFactory implements NativeScriptFactory { + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "mock-native-script"; + } + @Override + public String description() { + return "a mock native script for testing"; + } + public void onModule(ScriptModule scriptModule) { + scriptModule.registerScript("custom", CustomNativeScriptFactory.class); + } + } @Override public ExecutableScript newScript(@Nullable Map params) { return new CustomScript(params); diff --git a/distribution/src/main/resources/config/logging.yml b/distribution/src/main/resources/config/logging.yml index 035106eeec6..939aa1eed0e 100644 --- a/distribution/src/main/resources/config/logging.yml +++ b/distribution/src/main/resources/config/logging.yml @@ -10,6 +10,10 @@ logger: # reduce the logging for aws, too much is logged under the default INFO com.amazonaws: WARN + # aws will try to do some sketchy JMX stuff, but its not needed. + com.amazonaws.jmx.SdkMBeanRegistrySupport: ERROR + com.amazonaws.metrics.AwsSdkMetrics: ERROR + org.apache.http: INFO # gateway diff --git a/plugins/cloud-aws/src/main/java/org/elasticsearch/cloud/aws/AwsModule.java b/plugins/cloud-aws/src/main/java/org/elasticsearch/cloud/aws/AwsModule.java index 254fe6fbd9d..e848d33ff99 100644 --- a/plugins/cloud-aws/src/main/java/org/elasticsearch/cloud/aws/AwsModule.java +++ b/plugins/cloud-aws/src/main/java/org/elasticsearch/cloud/aws/AwsModule.java @@ -22,27 +22,19 @@ package org.elasticsearch.cloud.aws; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.settings.Settings; -/** - * - */ public class AwsModule extends AbstractModule { - private final Settings settings; - public static final String S3_SERVICE_TYPE_KEY = "cloud.aws.s3service.type"; + // pkg private so it is settable by tests + static Class s3ServiceImpl = InternalAwsS3Service.class; - public AwsModule(Settings settings) { - this.settings = settings; + public static Class getS3ServiceImpl() { + return s3ServiceImpl; } @Override protected void configure() { - bind(AwsS3Service.class).to(getS3ServiceClass(settings)).asEagerSingleton(); + bind(AwsS3Service.class).to(s3ServiceImpl).asEagerSingleton(); bind(AwsEc2Service.class).asEagerSingleton(); } - - public static Class getS3ServiceClass(Settings settings) { - return settings.getAsClass(S3_SERVICE_TYPE_KEY, InternalAwsS3Service.class); - } - } \ No newline at end of file diff --git a/plugins/cloud-aws/src/main/java/org/elasticsearch/discovery/ec2/Ec2DiscoveryModule.java b/plugins/cloud-aws/src/main/java/org/elasticsearch/discovery/ec2/Ec2DiscoveryModule.java deleted file mode 100644 index efa1cbdfb9d..00000000000 --- a/plugins/cloud-aws/src/main/java/org/elasticsearch/discovery/ec2/Ec2DiscoveryModule.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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.discovery.ec2; - -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.discovery.Discovery; -import org.elasticsearch.discovery.zen.ZenDiscoveryModule; - -/** - * - */ -public class Ec2DiscoveryModule extends ZenDiscoveryModule { - - @Inject - public Ec2DiscoveryModule(Settings settings) { - if (settings.getAsBoolean("cloud.enabled", true)) { - addUnicastHostProvider(AwsEc2UnicastHostsProvider.class); - } - } - - @Override - protected void bindDiscovery() { - bind(Discovery.class).to(Ec2Discovery.class).asEagerSingleton(); - } -} diff --git a/plugins/cloud-aws/src/main/java/org/elasticsearch/plugin/cloud/aws/CloudAwsPlugin.java b/plugins/cloud-aws/src/main/java/org/elasticsearch/plugin/cloud/aws/CloudAwsPlugin.java index 4d912530333..4b16400897f 100644 --- a/plugins/cloud-aws/src/main/java/org/elasticsearch/plugin/cloud/aws/CloudAwsPlugin.java +++ b/plugins/cloud-aws/src/main/java/org/elasticsearch/plugin/cloud/aws/CloudAwsPlugin.java @@ -24,6 +24,8 @@ import org.elasticsearch.cloud.aws.AwsModule; import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.discovery.DiscoveryModule; +import org.elasticsearch.discovery.ec2.Ec2Discovery; import org.elasticsearch.plugins.AbstractPlugin; import org.elasticsearch.repositories.RepositoriesModule; import org.elasticsearch.repositories.s3.S3Repository; @@ -57,7 +59,7 @@ public class CloudAwsPlugin extends AbstractPlugin { public Collection modules(Settings settings) { Collection modules = new ArrayList<>(); if (settings.getAsBoolean("cloud.enabled", true)) { - modules.add(new AwsModule(settings)); + modules.add(new AwsModule()); } return modules; } @@ -66,7 +68,7 @@ public class CloudAwsPlugin extends AbstractPlugin { public Collection> services() { Collection> services = new ArrayList<>(); if (settings.getAsBoolean("cloud.enabled", true)) { - services.add(AwsModule.getS3ServiceClass(settings)); + services.add(AwsModule.getS3ServiceImpl()); services.add(AwsEc2Service.class); } return services; @@ -77,4 +79,8 @@ public class CloudAwsPlugin extends AbstractPlugin { repositoriesModule.registerRepository(S3Repository.TYPE, S3RepositoryModule.class); } } + + public void onModule(DiscoveryModule discoveryModule) { + discoveryModule.addDiscoveryType("ec2", Ec2Discovery.class); + } } diff --git a/plugins/cloud-aws/src/test/java/org/elasticsearch/cloud/aws/AbstractAwsTest.java b/plugins/cloud-aws/src/test/java/org/elasticsearch/cloud/aws/AbstractAwsTest.java index 12abdbe71bc..34aa0755ef3 100644 --- a/plugins/cloud-aws/src/test/java/org/elasticsearch/cloud/aws/AbstractAwsTest.java +++ b/plugins/cloud-aws/src/test/java/org/elasticsearch/cloud/aws/AbstractAwsTest.java @@ -75,8 +75,7 @@ public abstract class AbstractAwsTest extends ESIntegTestCase { Settings.Builder settings = Settings.builder() .put(super.nodeSettings(nodeOrdinal)) .put("path.home", createTempDir()) - .put("plugin.types", CloudAwsPlugin.class.getName()) - .put(AwsModule.S3_SERVICE_TYPE_KEY, TestAwsS3Service.class) + .extendArray("plugin.types", CloudAwsPlugin.class.getName(), TestAwsS3Service.Plugin.class.getName()) .put("cloud.aws.test.random", randomInt()) .put("cloud.aws.test.write_failures", 0.1) .put("cloud.aws.test.read_failures", 0.1); diff --git a/plugins/cloud-aws/src/test/java/org/elasticsearch/cloud/aws/TestAwsS3Service.java b/plugins/cloud-aws/src/test/java/org/elasticsearch/cloud/aws/TestAwsS3Service.java index 920441a51ba..1124150ccf0 100644 --- a/plugins/cloud-aws/src/test/java/org/elasticsearch/cloud/aws/TestAwsS3Service.java +++ b/plugins/cloud-aws/src/test/java/org/elasticsearch/cloud/aws/TestAwsS3Service.java @@ -22,13 +22,24 @@ import com.amazonaws.services.s3.AmazonS3; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.plugins.AbstractPlugin; import java.util.IdentityHashMap; -/** - * - */ public class TestAwsS3Service extends InternalAwsS3Service { + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "mock-s3-service"; + } + @Override + public String description() { + return "plugs in mock s3 service"; + } + public void onModule(AwsModule awsModule) { + awsModule.s3ServiceImpl = TestAwsS3Service.class; + } + } IdentityHashMap clients = new IdentityHashMap(); diff --git a/plugins/cloud-azure/src/main/java/org/elasticsearch/cloud/azure/AzureModule.java b/plugins/cloud-azure/src/main/java/org/elasticsearch/cloud/azure/AzureModule.java index d7d1c81ff18..eec355af760 100644 --- a/plugins/cloud-azure/src/main/java/org/elasticsearch/cloud/azure/AzureModule.java +++ b/plugins/cloud-azure/src/main/java/org/elasticsearch/cloud/azure/AzureModule.java @@ -23,6 +23,7 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.cloud.azure.management.AzureComputeService; import org.elasticsearch.cloud.azure.management.AzureComputeService.Management; import org.elasticsearch.cloud.azure.management.AzureComputeServiceImpl; +import org.elasticsearch.cloud.azure.management.AzureComputeSettingsFilter; import org.elasticsearch.cloud.azure.storage.AzureStorageService; import org.elasticsearch.cloud.azure.storage.AzureStorageService.Storage; import org.elasticsearch.cloud.azure.storage.AzureStorageServiceImpl; @@ -51,6 +52,18 @@ public class AzureModule extends AbstractModule { protected final ESLogger logger; private Settings settings; + // pkg private so it is settable by tests + static Class computeServiceImpl = AzureComputeServiceImpl.class; + static Class storageServiceImpl = AzureStorageServiceImpl.class; + + public static Class getComputeServiceImpl() { + return computeServiceImpl; + } + + public static Class getStorageServiceImpl() { + return storageServiceImpl; + } + @Inject public AzureModule(Settings settings) { this.settings = settings; @@ -60,21 +73,18 @@ public class AzureModule extends AbstractModule { @Override protected void configure() { logger.debug("starting azure services"); + bind(AzureComputeSettingsFilter.class).asEagerSingleton(); // If we have set discovery to azure, let's start the azure compute service if (isDiscoveryReady(settings, logger)) { logger.debug("starting azure discovery service"); - bind(AzureComputeService.class) - .to(settings.getAsClass(Management.API_IMPLEMENTATION, AzureComputeServiceImpl.class)) - .asEagerSingleton(); + bind(AzureComputeService.class).to(computeServiceImpl).asEagerSingleton(); } // If we have settings for azure repository, let's start the azure storage service if (isSnapshotReady(settings, logger)) { logger.debug("starting azure repository service"); - bind(AzureStorageService.class) - .to(settings.getAsClass(Storage.API_IMPLEMENTATION, AzureStorageServiceImpl.class)) - .asEagerSingleton(); + bind(AzureStorageService.class).to(storageServiceImpl).asEagerSingleton(); } } diff --git a/plugins/cloud-azure/src/main/java/org/elasticsearch/discovery/azure/AzureDiscoveryModule.java b/plugins/cloud-azure/src/main/java/org/elasticsearch/discovery/azure/AzureDiscoveryModule.java deleted file mode 100644 index 886baa44774..00000000000 --- a/plugins/cloud-azure/src/main/java/org/elasticsearch/discovery/azure/AzureDiscoveryModule.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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.discovery.azure; - -import org.elasticsearch.cloud.azure.AzureModule; -import org.elasticsearch.cloud.azure.management.AzureComputeSettingsFilter; -import org.elasticsearch.common.logging.ESLogger; -import org.elasticsearch.common.logging.Loggers; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.discovery.Discovery; -import org.elasticsearch.discovery.zen.ZenDiscoveryModule; - -/** - * - */ -public class AzureDiscoveryModule extends ZenDiscoveryModule { - - protected final ESLogger logger; - private Settings settings; - - public AzureDiscoveryModule(Settings settings) { - super(); - this.logger = Loggers.getLogger(getClass(), settings); - this.settings = settings; - if (AzureModule.isDiscoveryReady(settings, logger)) { - addUnicastHostProvider(AzureUnicastHostsProvider.class); - } - } - - @Override - protected void bindDiscovery() { - bind(AzureComputeSettingsFilter.class).asEagerSingleton(); - if (AzureModule.isDiscoveryReady(settings, logger)) { - bind(Discovery.class).to(AzureDiscovery.class).asEagerSingleton(); - } else { - logger.debug("disabling azure discovery features"); - } - } -} diff --git a/plugins/cloud-azure/src/main/java/org/elasticsearch/index/store/smbmmapfs/SmbMmapFsIndexStoreModule.java b/plugins/cloud-azure/src/main/java/org/elasticsearch/index/store/smbmmapfs/SmbMmapFsIndexStoreModule.java deleted file mode 100644 index 335a58b32c5..00000000000 --- a/plugins/cloud-azure/src/main/java/org/elasticsearch/index/store/smbmmapfs/SmbMmapFsIndexStoreModule.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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.index.store.smbmmapfs; - -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.index.store.IndexStore; - -public class SmbMmapFsIndexStoreModule extends AbstractModule { - - @Override - protected void configure() { - bind(IndexStore.class).to(SmbMmapFsIndexStore.class).asEagerSingleton(); - } -} diff --git a/plugins/cloud-azure/src/main/java/org/elasticsearch/index/store/smbsimplefs/SmbSimpleFsIndexStoreModule.java b/plugins/cloud-azure/src/main/java/org/elasticsearch/index/store/smbsimplefs/SmbSimpleFsIndexStoreModule.java deleted file mode 100644 index 9604dc11c77..00000000000 --- a/plugins/cloud-azure/src/main/java/org/elasticsearch/index/store/smbsimplefs/SmbSimpleFsIndexStoreModule.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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.index.store.smbsimplefs; - -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.index.store.IndexStore; - -public class SmbSimpleFsIndexStoreModule extends AbstractModule { - - @Override - protected void configure() { - bind(IndexStore.class).to(SmbSimpleFsIndexStore.class).asEagerSingleton(); - } -} diff --git a/plugins/cloud-azure/src/main/java/org/elasticsearch/plugin/cloud/azure/CloudAzurePlugin.java b/plugins/cloud-azure/src/main/java/org/elasticsearch/plugin/cloud/azure/CloudAzurePlugin.java index 27c4bf2ddfc..e3b5b455584 100644 --- a/plugins/cloud-azure/src/main/java/org/elasticsearch/plugin/cloud/azure/CloudAzurePlugin.java +++ b/plugins/cloud-azure/src/main/java/org/elasticsearch/plugin/cloud/azure/CloudAzurePlugin.java @@ -24,6 +24,11 @@ import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.discovery.DiscoveryModule; +import org.elasticsearch.discovery.azure.AzureDiscovery; +import org.elasticsearch.index.store.IndexStoreModule; +import org.elasticsearch.index.store.smbmmapfs.SmbMmapFsIndexStore; +import org.elasticsearch.index.store.smbsimplefs.SmbSimpleFsIndexStore; import org.elasticsearch.plugins.AbstractPlugin; import org.elasticsearch.repositories.RepositoriesModule; import org.elasticsearch.repositories.azure.AzureRepository; @@ -73,4 +78,13 @@ public class CloudAzurePlugin extends AbstractPlugin { ((RepositoriesModule)module).registerRepository(AzureRepository.TYPE, AzureRepositoryModule.class); } } + + public void onModule(DiscoveryModule discoveryModule) { + discoveryModule.addDiscoveryType("azure", AzureDiscovery.class); + } + + public void onModule(IndexStoreModule storeModule) { + storeModule.addIndexStore("smb_mmap_fs", SmbMmapFsIndexStore.class); + storeModule.addIndexStore("smb_simple_fs", SmbSimpleFsIndexStore.class); + } } diff --git a/plugins/cloud-azure/src/test/java/org/elasticsearch/discovery/azure/AbstractAzureComputeServiceTest.java b/plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/AbstractAzureComputeServiceTest.java similarity index 70% rename from plugins/cloud-azure/src/test/java/org/elasticsearch/discovery/azure/AbstractAzureComputeServiceTest.java rename to plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/AbstractAzureComputeServiceTest.java index b12b8bf1d49..620c10465f5 100644 --- a/plugins/cloud-azure/src/test/java/org/elasticsearch/discovery/azure/AbstractAzureComputeServiceTest.java +++ b/plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/AbstractAzureComputeServiceTest.java @@ -17,31 +17,44 @@ * under the License. */ -package org.elasticsearch.discovery.azure; +package org.elasticsearch.cloud.azure; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse; +import org.elasticsearch.cloud.azure.AzureModule; import org.elasticsearch.cloud.azure.management.AzureComputeService; import org.elasticsearch.cloud.azure.management.AzureComputeService.Discovery; import org.elasticsearch.cloud.azure.management.AzureComputeService.Management; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.plugin.cloud.azure.CloudAzurePlugin; +import org.elasticsearch.plugins.AbstractPlugin; +import org.elasticsearch.plugins.Plugin; import org.elasticsearch.test.ESIntegTestCase; public abstract class AbstractAzureComputeServiceTest extends ESIntegTestCase { - private Class mock; + private String mockPlugin; - public AbstractAzureComputeServiceTest(Class mock) { + public AbstractAzureComputeServiceTest(String mockPlugin) { // We want to inject the Azure API Mock - this.mock = mock; + this.mockPlugin = mockPlugin; } @Override protected Settings nodeSettings(int nodeOrdinal) { - Settings.Builder settings = Settings.builder() - .put(super.nodeSettings(nodeOrdinal)) - .put("plugin.types", CloudAzurePlugin.class.getName()); - return settings.build(); + Settings.Builder builder = Settings.settingsBuilder() + .put(super.nodeSettings(nodeOrdinal)) + .put("discovery.type", "azure") + // We need the network to make the mock working + .put("node.mode", "network") + .extendArray("plugin.types", CloudAzurePlugin.class.getName(), mockPlugin); + + // We add a fake subscription_id to start mock compute service + builder.put(Management.SUBSCRIPTION_ID, "fake") + .put(Discovery.REFRESH, "5s") + .put(Management.KEYSTORE_PATH, "dummy") + .put(Management.KEYSTORE_PASSWORD, "dummy") + .put(Management.SERVICE_NAME, "dummy"); + return builder.build(); } protected void checkNumberOfNodes(int expected) { @@ -50,21 +63,4 @@ public abstract class AbstractAzureComputeServiceTest extends ESIntegTestCase { assertNotNull(nodeInfos.getNodes()); assertEquals(expected, nodeInfos.getNodes().length); } - - protected Settings settingsBuilder() { - Settings.Builder builder = Settings.settingsBuilder() - .put("discovery.type", "azure") - .put(Management.API_IMPLEMENTATION, mock) - // We need the network to make the mock working - .put("node.mode", "network"); - - // We add a fake subscription_id to start mock compute service - builder.put(Management.SUBSCRIPTION_ID, "fake") - .put(Discovery.REFRESH, "5s") - .put(Management.KEYSTORE_PATH, "dummy") - .put(Management.KEYSTORE_PASSWORD, "dummy") - .put(Management.SERVICE_NAME, "dummy"); - - return builder.build(); - } } diff --git a/plugins/cloud-azure/src/test/java/org/elasticsearch/repositories/azure/AbstractAzureRepositoryServiceTest.java b/plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/AbstractAzureRepositoryServiceTest.java similarity index 83% rename from plugins/cloud-azure/src/test/java/org/elasticsearch/repositories/azure/AbstractAzureRepositoryServiceTest.java rename to plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/AbstractAzureRepositoryServiceTest.java index 876430213e4..9fae8158c3d 100644 --- a/plugins/cloud-azure/src/test/java/org/elasticsearch/repositories/azure/AbstractAzureRepositoryServiceTest.java +++ b/plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/AbstractAzureRepositoryServiceTest.java @@ -17,17 +17,16 @@ * under the License. */ -package org.elasticsearch.repositories.azure; +package org.elasticsearch.cloud.azure; import com.microsoft.azure.storage.StorageException; - -import org.elasticsearch.cloud.azure.AbstractAzureTest; import org.elasticsearch.cloud.azure.storage.AzureStorageService; import org.elasticsearch.cloud.azure.storage.AzureStorageService.Storage; +import org.elasticsearch.cloud.azure.storage.AzureStorageServiceMock; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.plugin.cloud.azure.CloudAzurePlugin; -import org.elasticsearch.plugins.PluginsService; +import org.elasticsearch.plugins.AbstractPlugin; import org.elasticsearch.repositories.RepositoryMissingException; import org.elasticsearch.test.store.MockFSDirectoryService; import org.junit.After; @@ -37,13 +36,24 @@ import java.net.URISyntaxException; public abstract class AbstractAzureRepositoryServiceTest extends AbstractAzureTest { + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "mock-stoarge-service"; + } + @Override + public String description() { + return "plugs in a mock storage service for testing"; + } + public void onModule(AzureModule azureModule) { + azureModule.storageServiceImpl = AzureStorageServiceMock.class; + } + } + protected String basePath; private Class mock; - public AbstractAzureRepositoryServiceTest(Class mock, - String basePath) { - // We want to inject the Azure API Mock - this.mock = mock; + public AbstractAzureRepositoryServiceTest(String basePath) { this.basePath = basePath; } @@ -67,7 +77,7 @@ public abstract class AbstractAzureRepositoryServiceTest extends AbstractAzureTe @Override protected Settings nodeSettings(int nodeOrdinal) { Settings.Builder builder = Settings.settingsBuilder() - .put("plugin.types", CloudAzurePlugin.class.getName()) + .extendArray("plugin.types", CloudAzurePlugin.class.getName(), Plugin.class.getName()) .put(Storage.API_IMPLEMENTATION, mock) .put(Storage.CONTAINER, "snapshots"); diff --git a/plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/management/AzureComputeServiceSimpleMock.java b/plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/AzureComputeServiceSimpleMock.java similarity index 80% rename from plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/management/AzureComputeServiceSimpleMock.java rename to plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/AzureComputeServiceSimpleMock.java index b34b5aeb8b1..2f161bbd602 100644 --- a/plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/management/AzureComputeServiceSimpleMock.java +++ b/plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/AzureComputeServiceSimpleMock.java @@ -17,12 +17,14 @@ * under the License. */ -package org.elasticsearch.cloud.azure.management; +package org.elasticsearch.cloud.azure; import com.microsoft.windowsazure.management.compute.models.*; +import org.elasticsearch.cloud.azure.management.AzureComputeServiceAbstractMock; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.CollectionUtils; +import org.elasticsearch.plugins.AbstractPlugin; import java.net.InetAddress; @@ -31,6 +33,20 @@ import java.net.InetAddress; */ public class AzureComputeServiceSimpleMock extends AzureComputeServiceAbstractMock { + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "mock-compute-service"; + } + @Override + public String description() { + return "plugs in a mock compute service for testing"; + } + public void onModule(AzureModule azureModule) { + azureModule.computeServiceImpl = AzureComputeServiceSimpleMock.class; + } + } + @Inject protected AzureComputeServiceSimpleMock(Settings settings) { super(settings); diff --git a/plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/management/AzureComputeServiceTwoNodesMock.java b/plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/AzureComputeServiceTwoNodesMock.java similarity index 82% rename from plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/management/AzureComputeServiceTwoNodesMock.java rename to plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/AzureComputeServiceTwoNodesMock.java index f6a4c567259..e8f7fa9e37c 100644 --- a/plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/management/AzureComputeServiceTwoNodesMock.java +++ b/plugins/cloud-azure/src/test/java/org/elasticsearch/cloud/azure/AzureComputeServiceTwoNodesMock.java @@ -17,13 +17,17 @@ * under the License. */ -package org.elasticsearch.cloud.azure.management; +package org.elasticsearch.cloud.azure; import com.microsoft.windowsazure.management.compute.models.*; +import org.elasticsearch.cloud.azure.AzureModule; +import org.elasticsearch.cloud.azure.management.AzureComputeServiceAbstractMock; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.network.NetworkService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.CollectionUtils; +import org.elasticsearch.plugins.AbstractPlugin; +import org.elasticsearch.plugins.Plugin; import java.net.InetAddress; @@ -32,6 +36,19 @@ import java.net.InetAddress; * Mock Azure API with two started nodes */ public class AzureComputeServiceTwoNodesMock extends AzureComputeServiceAbstractMock { + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "mock-compute-service"; + } + @Override + public String description() { + return "plugs in a mock compute service for testing"; + } + public void onModule(AzureModule azureModule) { + azureModule.computeServiceImpl = AzureComputeServiceTwoNodesMock.class; + } + } NetworkService networkService; diff --git a/plugins/cloud-azure/src/test/java/org/elasticsearch/discovery/azure/AzureMinimumMasterNodesTest.java b/plugins/cloud-azure/src/test/java/org/elasticsearch/discovery/azure/AzureMinimumMasterNodesTest.java index 296c3ed44a3..c0cde86ccc6 100644 --- a/plugins/cloud-azure/src/test/java/org/elasticsearch/discovery/azure/AzureMinimumMasterNodesTest.java +++ b/plugins/cloud-azure/src/test/java/org/elasticsearch/discovery/azure/AzureMinimumMasterNodesTest.java @@ -19,7 +19,8 @@ package org.elasticsearch.discovery.azure; -import org.elasticsearch.cloud.azure.management.AzureComputeServiceTwoNodesMock; +import org.elasticsearch.cloud.azure.AbstractAzureComputeServiceTest; +import org.elasticsearch.cloud.azure.AzureComputeServiceTwoNodesMock; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.discovery.MasterNotDiscoveredException; import org.elasticsearch.test.ESIntegTestCase; @@ -43,13 +44,13 @@ import static org.hamcrest.Matchers.nullValue; public class AzureMinimumMasterNodesTest extends AbstractAzureComputeServiceTest { public AzureMinimumMasterNodesTest() { - super(AzureComputeServiceTwoNodesMock.class); + super(AzureComputeServiceTwoNodesMock.Plugin.class.getName()); } @Override - protected final Settings settingsBuilder() { + protected Settings nodeSettings(int nodeOrdinal) { Settings.Builder builder = Settings.settingsBuilder() - .put(super.settingsBuilder()) + .put(super.nodeSettings(nodeOrdinal)) .put("discovery.zen.minimum_master_nodes", 2) // Make the test run faster .put("discovery.zen.join.timeout", "50ms") @@ -61,7 +62,7 @@ public class AzureMinimumMasterNodesTest extends AbstractAzureComputeServiceTest @Test public void simpleOnlyMasterNodeElection() throws IOException { logger.info("--> start data node / non master node"); - internalCluster().startNode(settingsBuilder()); + internalCluster().startNode(); try { assertThat(client().admin().cluster().prepareState().setMasterNodeTimeout("100ms").execute().actionGet().getState().nodes().masterNodeId(), nullValue()); fail("should not be able to find master"); @@ -69,7 +70,7 @@ public class AzureMinimumMasterNodesTest extends AbstractAzureComputeServiceTest // all is well, no master elected } logger.info("--> start another node"); - internalCluster().startNode(settingsBuilder()); + internalCluster().startNode(); assertThat(client().admin().cluster().prepareState().setMasterNodeTimeout("1s").execute().actionGet().getState().nodes().masterNodeId(), notNullValue()); logger.info("--> stop master node"); @@ -83,7 +84,7 @@ public class AzureMinimumMasterNodesTest extends AbstractAzureComputeServiceTest } logger.info("--> start another node"); - internalCluster().startNode(settingsBuilder()); + internalCluster().startNode(); assertThat(client().admin().cluster().prepareState().setMasterNodeTimeout("1s").execute().actionGet().getState().nodes().masterNodeId(), notNullValue()); } } diff --git a/plugins/cloud-azure/src/test/java/org/elasticsearch/discovery/azure/AzureSimpleTest.java b/plugins/cloud-azure/src/test/java/org/elasticsearch/discovery/azure/AzureSimpleTest.java index b859701b087..d99267e3b90 100644 --- a/plugins/cloud-azure/src/test/java/org/elasticsearch/discovery/azure/AzureSimpleTest.java +++ b/plugins/cloud-azure/src/test/java/org/elasticsearch/discovery/azure/AzureSimpleTest.java @@ -19,9 +19,10 @@ package org.elasticsearch.discovery.azure; +import org.elasticsearch.cloud.azure.AbstractAzureComputeServiceTest; import org.elasticsearch.cloud.azure.management.AzureComputeService.Discovery; import org.elasticsearch.cloud.azure.management.AzureComputeService.Management; -import org.elasticsearch.cloud.azure.management.AzureComputeServiceSimpleMock; +import org.elasticsearch.cloud.azure.AzureComputeServiceSimpleMock; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.test.ESIntegTestCase; import org.junit.Test; @@ -35,15 +36,14 @@ import static org.hamcrest.Matchers.notNullValue; public class AzureSimpleTest extends AbstractAzureComputeServiceTest { public AzureSimpleTest() { - super(AzureComputeServiceSimpleMock.class); + super(AzureComputeServiceSimpleMock.Plugin.class.getName()); } @Test public void one_node_should_run_using_private_ip() { Settings.Builder settings = Settings.settingsBuilder() .put(Management.SERVICE_NAME, "dummy") - .put(Discovery.HOST_TYPE, "private_ip") - .put(super.settingsBuilder()); + .put(Discovery.HOST_TYPE, "private_ip"); logger.info("--> start one node"); internalCluster().startNode(settings); @@ -57,8 +57,7 @@ public class AzureSimpleTest extends AbstractAzureComputeServiceTest { public void one_node_should_run_using_public_ip() { Settings.Builder settings = Settings.settingsBuilder() .put(Management.SERVICE_NAME, "dummy") - .put(Discovery.HOST_TYPE, "public_ip") - .put(super.settingsBuilder()); + .put(Discovery.HOST_TYPE, "public_ip"); logger.info("--> start one node"); internalCluster().startNode(settings); @@ -72,8 +71,7 @@ public class AzureSimpleTest extends AbstractAzureComputeServiceTest { public void one_node_should_run_using_wrong_settings() { Settings.Builder settings = Settings.settingsBuilder() .put(Management.SERVICE_NAME, "dummy") - .put(Discovery.HOST_TYPE, "do_not_exist") - .put(super.settingsBuilder()); + .put(Discovery.HOST_TYPE, "do_not_exist"); logger.info("--> start one node"); internalCluster().startNode(settings); diff --git a/plugins/cloud-azure/src/test/java/org/elasticsearch/discovery/azure/AzureTwoStartedNodesTest.java b/plugins/cloud-azure/src/test/java/org/elasticsearch/discovery/azure/AzureTwoStartedNodesTest.java index a80ac5ba445..818d828197a 100644 --- a/plugins/cloud-azure/src/test/java/org/elasticsearch/discovery/azure/AzureTwoStartedNodesTest.java +++ b/plugins/cloud-azure/src/test/java/org/elasticsearch/discovery/azure/AzureTwoStartedNodesTest.java @@ -19,9 +19,10 @@ package org.elasticsearch.discovery.azure; +import org.elasticsearch.cloud.azure.AbstractAzureComputeServiceTest; import org.elasticsearch.cloud.azure.management.AzureComputeService.Discovery; import org.elasticsearch.cloud.azure.management.AzureComputeService.Management; -import org.elasticsearch.cloud.azure.management.AzureComputeServiceTwoNodesMock; +import org.elasticsearch.cloud.azure.AzureComputeServiceTwoNodesMock; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.test.ESIntegTestCase; import org.junit.Test; @@ -35,7 +36,7 @@ import static org.hamcrest.Matchers.notNullValue; public class AzureTwoStartedNodesTest extends AbstractAzureComputeServiceTest { public AzureTwoStartedNodesTest() { - super(AzureComputeServiceTwoNodesMock.class); + super(AzureComputeServiceTwoNodesMock.Plugin.class.getName()); } @Test @@ -43,8 +44,7 @@ public class AzureTwoStartedNodesTest extends AbstractAzureComputeServiceTest { public void two_nodes_should_run_using_private_ip() { Settings.Builder settings = Settings.settingsBuilder() .put(Management.SERVICE_NAME, "dummy") - .put(Discovery.HOST_TYPE, "private_ip") - .put(super.settingsBuilder()); + .put(Discovery.HOST_TYPE, "private_ip"); logger.info("--> start first node"); internalCluster().startNode(settings); @@ -63,8 +63,7 @@ public class AzureTwoStartedNodesTest extends AbstractAzureComputeServiceTest { public void two_nodes_should_run_using_public_ip() { Settings.Builder settings = Settings.settingsBuilder() .put(Management.SERVICE_NAME, "dummy") - .put(Discovery.HOST_TYPE, "public_ip") - .put(super.settingsBuilder()); + .put(Discovery.HOST_TYPE, "public_ip"); logger.info("--> start first node"); internalCluster().startNode(settings); diff --git a/plugins/cloud-azure/src/test/java/org/elasticsearch/index/store/AbstractAzureFsTest.java b/plugins/cloud-azure/src/test/java/org/elasticsearch/index/store/AbstractAzureFsTest.java index 047a0faecf1..a335910e9f7 100644 --- a/plugins/cloud-azure/src/test/java/org/elasticsearch/index/store/AbstractAzureFsTest.java +++ b/plugins/cloud-azure/src/test/java/org/elasticsearch/index/store/AbstractAzureFsTest.java @@ -20,6 +20,8 @@ package org.elasticsearch.index.store; import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.plugin.cloud.azure.CloudAzurePlugin; import org.elasticsearch.test.ESIntegTestCase; import org.junit.Test; @@ -27,6 +29,13 @@ import static org.hamcrest.Matchers.is; abstract public class AbstractAzureFsTest extends ESIntegTestCase { + @Override + protected Settings nodeSettings(int nodeOrdinal) { + return Settings.settingsBuilder() + .put(super.nodeSettings(nodeOrdinal)) + .extendArray("plugin.types", CloudAzurePlugin.class.getName()).build(); + } + @Test public void testAzureFs() { // Create an index and index some documents diff --git a/plugins/cloud-azure/src/test/java/org/elasticsearch/index/store/SmbMMapFsTest.java b/plugins/cloud-azure/src/test/java/org/elasticsearch/index/store/SmbMMapFsTest.java index 2b925a86820..820f50071c7 100644 --- a/plugins/cloud-azure/src/test/java/org/elasticsearch/index/store/SmbMMapFsTest.java +++ b/plugins/cloud-azure/src/test/java/org/elasticsearch/index/store/SmbMMapFsTest.java @@ -20,6 +20,7 @@ package org.elasticsearch.index.store; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.plugin.cloud.azure.CloudAzurePlugin; public class SmbMMapFsTest extends AbstractAzureFsTest { diff --git a/plugins/cloud-azure/src/test/java/org/elasticsearch/index/store/SmbSimpleFsTest.java b/plugins/cloud-azure/src/test/java/org/elasticsearch/index/store/SmbSimpleFsTest.java index 482075ad327..d4bd02f6b52 100644 --- a/plugins/cloud-azure/src/test/java/org/elasticsearch/index/store/SmbSimpleFsTest.java +++ b/plugins/cloud-azure/src/test/java/org/elasticsearch/index/store/SmbSimpleFsTest.java @@ -20,6 +20,7 @@ package org.elasticsearch.index.store; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.plugin.cloud.azure.CloudAzurePlugin; public class SmbSimpleFsTest extends AbstractAzureFsTest { diff --git a/plugins/cloud-azure/src/test/java/org/elasticsearch/repositories/azure/AzureSnapshotRestoreTest.java b/plugins/cloud-azure/src/test/java/org/elasticsearch/repositories/azure/AzureSnapshotRestoreTest.java index 1b8a9083358..fec61b8e677 100644 --- a/plugins/cloud-azure/src/test/java/org/elasticsearch/repositories/azure/AzureSnapshotRestoreTest.java +++ b/plugins/cloud-azure/src/test/java/org/elasticsearch/repositories/azure/AzureSnapshotRestoreTest.java @@ -24,6 +24,7 @@ import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryResp import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse; import org.elasticsearch.client.Client; +import org.elasticsearch.cloud.azure.AbstractAzureRepositoryServiceTest; import org.elasticsearch.cloud.azure.storage.AzureStorageServiceMock; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.common.settings.Settings; @@ -43,7 +44,7 @@ import static org.hamcrest.Matchers.greaterThan; public class AzureSnapshotRestoreTest extends AbstractAzureRepositoryServiceTest { public AzureSnapshotRestoreTest() { - super(AzureStorageServiceMock.class, "/snapshot-test/repo-" + randomInt()); + super("/snapshot-test/repo-" + randomInt()); } @Test diff --git a/plugins/cloud-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java b/plugins/cloud-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java index b6b45b2861a..f23ba0cdc3e 100644 --- a/plugins/cloud-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java +++ b/plugins/cloud-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java @@ -20,13 +20,15 @@ package org.elasticsearch.cloud.gce; import com.google.api.services.compute.model.Instance; +import org.elasticsearch.common.component.AbstractLifecycleComponent; +import org.elasticsearch.common.component.LifecycleComponent; import java.util.Collection; /** * */ -public interface GceComputeService { +public interface GceComputeService extends LifecycleComponent { static final public class Fields { public static final String PROJECT = "cloud.gce.project_id"; public static final String ZONE = "cloud.gce.zone"; diff --git a/plugins/cloud-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeServiceImpl.java b/plugins/cloud-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeServiceImpl.java index ceb3b8633d2..4ca7e19404e 100644 --- a/plugins/cloud-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeServiceImpl.java +++ b/plugins/cloud-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeServiceImpl.java @@ -45,7 +45,7 @@ import java.util.List; /** * */ -public class GceComputeServiceImpl extends AbstractLifecycleComponent +public class GceComputeServiceImpl extends AbstractLifecycleComponent implements GceComputeService { private final String project; diff --git a/plugins/cloud-gce/src/main/java/org/elasticsearch/cloud/gce/GceModule.java b/plugins/cloud-gce/src/main/java/org/elasticsearch/cloud/gce/GceModule.java index 870698c3778..8db0dec3e7e 100644 --- a/plugins/cloud-gce/src/main/java/org/elasticsearch/cloud/gce/GceModule.java +++ b/plugins/cloud-gce/src/main/java/org/elasticsearch/cloud/gce/GceModule.java @@ -23,21 +23,16 @@ import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -/** - * - */ public class GceModule extends AbstractModule { - private Settings settings; + // pkg private so tests can override with mock + static Class computeServiceImpl = GceComputeServiceImpl.class; - @Inject - public GceModule(Settings settings) { - this.settings = settings; + public static Class getComputeServiceImpl() { + return computeServiceImpl; } @Override protected void configure() { - bind(GceComputeService.class) - .to(settings.getAsClass("cloud.gce.api.impl", GceComputeServiceImpl.class)) - .asEagerSingleton(); + bind(GceComputeService.class).to(computeServiceImpl).asEagerSingleton(); } } diff --git a/plugins/cloud-gce/src/main/java/org/elasticsearch/discovery/gce/GceDiscoveryModule.java b/plugins/cloud-gce/src/main/java/org/elasticsearch/discovery/gce/GceDiscoveryModule.java deleted file mode 100644 index 2dcb65789e9..00000000000 --- a/plugins/cloud-gce/src/main/java/org/elasticsearch/discovery/gce/GceDiscoveryModule.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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.discovery.gce; - -import org.elasticsearch.discovery.Discovery; -import org.elasticsearch.discovery.zen.ZenDiscoveryModule; - -/** - * - */ -public class GceDiscoveryModule extends ZenDiscoveryModule { - - @Override - protected void bindDiscovery() { - bind(Discovery.class).to(GceDiscovery.class).asEagerSingleton(); - } -} diff --git a/plugins/cloud-gce/src/main/java/org/elasticsearch/plugin/cloud/gce/CloudGcePlugin.java b/plugins/cloud-gce/src/main/java/org/elasticsearch/plugin/cloud/gce/CloudGcePlugin.java index 0333db58665..465b68028d1 100644 --- a/plugins/cloud-gce/src/main/java/org/elasticsearch/plugin/cloud/gce/CloudGcePlugin.java +++ b/plugins/cloud-gce/src/main/java/org/elasticsearch/plugin/cloud/gce/CloudGcePlugin.java @@ -23,6 +23,8 @@ import org.elasticsearch.cloud.gce.GceModule; import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.discovery.DiscoveryModule; +import org.elasticsearch.discovery.gce.GceDiscovery; import org.elasticsearch.plugins.AbstractPlugin; import java.util.ArrayList; @@ -62,9 +64,13 @@ public class CloudGcePlugin extends AbstractPlugin { public Collection> services() { Collection> services = new ArrayList<>(); if (settings.getAsBoolean("cloud.enabled", true)) { -// services.add(GceComputeServiceImpl.class); + services.add(GceModule.getComputeServiceImpl()); } return services; } + public void onModule(DiscoveryModule discoveryModule) { + discoveryModule.addDiscoveryType("gce", GceDiscovery.class); + } + } diff --git a/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceTwoNodesDifferentTagsMock.java b/plugins/cloud-gce/src/test/java/org/elasticsearch/cloud/gce/GceComputeServiceTwoNodesDifferentTagsMock.java similarity index 70% rename from plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceTwoNodesDifferentTagsMock.java rename to plugins/cloud-gce/src/test/java/org/elasticsearch/cloud/gce/GceComputeServiceTwoNodesDifferentTagsMock.java index bba393c6540..7b67c45be7f 100644 --- a/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceTwoNodesDifferentTagsMock.java +++ b/plugins/cloud-gce/src/test/java/org/elasticsearch/cloud/gce/GceComputeServiceTwoNodesDifferentTagsMock.java @@ -17,10 +17,13 @@ * under the License. */ -package org.elasticsearch.discovery.gce.mock; +package org.elasticsearch.cloud.gce; +import org.elasticsearch.cloud.gce.GceModule; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.discovery.gce.mock.GceComputeServiceAbstractMock; +import org.elasticsearch.plugins.AbstractPlugin; import java.util.ArrayList; import java.util.Arrays; @@ -30,6 +33,21 @@ import java.util.List; * */ public class GceComputeServiceTwoNodesDifferentTagsMock extends GceComputeServiceAbstractMock { + + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "mock-compute-service"; + } + @Override + public String description() { + return "a mock compute service for testing"; + } + public void onModule(GceModule gceModule) { + gceModule.computeServiceImpl = GceComputeServiceTwoNodesDifferentTagsMock.class; + } + } + private static List> tags = Arrays.asList( Arrays.asList("dev"), Arrays.asList("elasticsearch", "dev")); diff --git a/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceTwoNodesOneZoneMock.java b/plugins/cloud-gce/src/test/java/org/elasticsearch/cloud/gce/GceComputeServiceTwoNodesOneZoneMock.java similarity index 70% rename from plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceTwoNodesOneZoneMock.java rename to plugins/cloud-gce/src/test/java/org/elasticsearch/cloud/gce/GceComputeServiceTwoNodesOneZoneMock.java index 9221b0263f1..3bcec91406a 100644 --- a/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceTwoNodesOneZoneMock.java +++ b/plugins/cloud-gce/src/test/java/org/elasticsearch/cloud/gce/GceComputeServiceTwoNodesOneZoneMock.java @@ -17,19 +17,32 @@ * under the License. */ -package org.elasticsearch.discovery.gce.mock; +package org.elasticsearch.cloud.gce; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.discovery.gce.mock.GceComputeServiceAbstractMock; +import org.elasticsearch.plugins.AbstractPlugin; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -/** - * - */ public class GceComputeServiceTwoNodesOneZoneMock extends GceComputeServiceAbstractMock { + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "mock-compute-service"; + } + @Override + public String description() { + return "a mock compute service for testing"; + } + public void onModule(GceModule gceModule) { + gceModule.computeServiceImpl = GceComputeServiceTwoNodesOneZoneMock.class; + } + } + private static List zones = Arrays.asList("us-central1-a", "us-central1-a"); @Override diff --git a/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceTwoNodesSameTagsMock.java b/plugins/cloud-gce/src/test/java/org/elasticsearch/cloud/gce/GceComputeServiceTwoNodesSameTagsMock.java similarity index 71% rename from plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceTwoNodesSameTagsMock.java rename to plugins/cloud-gce/src/test/java/org/elasticsearch/cloud/gce/GceComputeServiceTwoNodesSameTagsMock.java index e2384a6a441..4b31c2204ad 100644 --- a/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceTwoNodesSameTagsMock.java +++ b/plugins/cloud-gce/src/test/java/org/elasticsearch/cloud/gce/GceComputeServiceTwoNodesSameTagsMock.java @@ -17,19 +17,32 @@ * under the License. */ -package org.elasticsearch.discovery.gce.mock; +package org.elasticsearch.cloud.gce; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.discovery.gce.mock.GceComputeServiceAbstractMock; +import org.elasticsearch.plugins.AbstractPlugin; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -/** - * - */ public class GceComputeServiceTwoNodesSameTagsMock extends GceComputeServiceAbstractMock { + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "mock-compute-service"; + } + @Override + public String description() { + return "a mock compute service for testing"; + } + public void onModule(GceModule gceModule) { + gceModule.computeServiceImpl = GceComputeServiceTwoNodesSameTagsMock.class; + } + } + private static List> tags = Arrays.asList( Arrays.asList("elasticsearch", "dev"), Arrays.asList("elasticsearch", "dev")); diff --git a/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceTwoNodesTwoZonesMock.java b/plugins/cloud-gce/src/test/java/org/elasticsearch/cloud/gce/GceComputeServiceTwoNodesTwoZonesMock.java similarity index 70% rename from plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceTwoNodesTwoZonesMock.java rename to plugins/cloud-gce/src/test/java/org/elasticsearch/cloud/gce/GceComputeServiceTwoNodesTwoZonesMock.java index a1a5cbeb864..0645ff29dfe 100644 --- a/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceTwoNodesTwoZonesMock.java +++ b/plugins/cloud-gce/src/test/java/org/elasticsearch/cloud/gce/GceComputeServiceTwoNodesTwoZonesMock.java @@ -17,19 +17,32 @@ * under the License. */ -package org.elasticsearch.discovery.gce.mock; +package org.elasticsearch.cloud.gce; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.discovery.gce.mock.GceComputeServiceAbstractMock; +import org.elasticsearch.plugins.AbstractPlugin; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -/** - * - */ public class GceComputeServiceTwoNodesTwoZonesMock extends GceComputeServiceAbstractMock { + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "mock-compute-service"; + } + @Override + public String description() { + return "a mock compute service for testing"; + } + public void onModule(GceModule gceModule) { + gceModule.computeServiceImpl = GceComputeServiceTwoNodesTwoZonesMock.class; + } + } + private static List zones = Arrays.asList("us-central1-a", "europe-west1-a"); @Override diff --git a/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceZeroNodeMock.java b/plugins/cloud-gce/src/test/java/org/elasticsearch/cloud/gce/GceComputeServiceZeroNodeMock.java similarity index 80% rename from plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceZeroNodeMock.java rename to plugins/cloud-gce/src/test/java/org/elasticsearch/cloud/gce/GceComputeServiceZeroNodeMock.java index 7eccfd0f8bd..5a3bbe27a1d 100644 --- a/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceZeroNodeMock.java +++ b/plugins/cloud-gce/src/test/java/org/elasticsearch/cloud/gce/GceComputeServiceZeroNodeMock.java @@ -17,7 +17,7 @@ * under the License. */ -package org.elasticsearch.discovery.gce.mock; +package org.elasticsearch.cloud.gce; import com.google.api.services.compute.model.Instance; import com.google.common.base.Function; @@ -25,15 +25,27 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.discovery.gce.mock.GceComputeServiceAbstractMock; +import org.elasticsearch.plugins.AbstractPlugin; import java.util.ArrayList; import java.util.Collection; import java.util.List; -/** - * - */ public class GceComputeServiceZeroNodeMock extends GceComputeServiceAbstractMock { + public static class Plugin extends AbstractPlugin { + @Override + public String name() { + return "mock-compute-service"; + } + @Override + public String description() { + return "a mock compute service for testing"; + } + public void onModule(GceModule gceModule) { + gceModule.computeServiceImpl = GceComputeServiceZeroNodeMock.class; + } + } @Override protected List> getTags() { diff --git a/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/GceComputeEngineTest.java b/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/GceComputeEngineTest.java index 489ae3a4c7c..c7a2656002d 100644 --- a/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/GceComputeEngineTest.java +++ b/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/GceComputeEngineTest.java @@ -23,13 +23,15 @@ import com.google.common.collect.Lists; import org.apache.lucene.util.LuceneTestCase; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse; -import org.elasticsearch.cloud.gce.GceComputeService; import org.elasticsearch.cloud.gce.GceComputeService.Fields; +import org.elasticsearch.cloud.gce.GceComputeServiceTwoNodesDifferentTagsMock; +import org.elasticsearch.cloud.gce.GceComputeServiceTwoNodesOneZoneMock; +import org.elasticsearch.cloud.gce.GceComputeServiceTwoNodesSameTagsMock; +import org.elasticsearch.cloud.gce.GceComputeServiceTwoNodesTwoZonesMock; +import org.elasticsearch.cloud.gce.GceComputeServiceZeroNodeMock; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.discovery.gce.mock.*; import org.elasticsearch.plugin.cloud.gce.CloudGcePlugin; import org.elasticsearch.test.ESIntegTestCase; -import org.junit.Ignore; import org.junit.Test; import java.io.IOException; @@ -61,10 +63,9 @@ public class GceComputeEngineTest extends ESIntegTestCase { assertEquals(expected, nodeInfos.getNodes().length); } - protected Settings settingsBuilder(int nodeOrdinal, Class mock, Settings settings) { + protected Settings settingsBuilder(int nodeOrdinal, String mockClass, Settings settings) { Settings.Builder builder = Settings.settingsBuilder() .put("discovery.type", "gce") - .put("cloud.gce.api.impl", mock) // We need the network to make the mock working .put("node.mode", "network") // Make the tests run faster @@ -76,29 +77,29 @@ public class GceComputeEngineTest extends ESIntegTestCase { // We disable http .put("http.enabled", false) // We force plugin loading - .put("plugin.types", CloudGcePlugin.class.getName()) + .extendArray("plugin.types", CloudGcePlugin.class.getName(), mockClass) .put(settings) .put(super.nodeSettings(nodeOrdinal)); return builder.build(); } - protected void startNode(int nodeOrdinal, Class mock, Settings settings) { - logger.info("--> start node #{}, mock [{}], settings [{}]", nodeOrdinal, mock.getSimpleName(), settings.getAsMap()); + protected void startNode(int nodeOrdinal, String mockClass, Settings settings) { + logger.info("--> start node #{}, mock [{}], settings [{}]", nodeOrdinal, mockClass, settings.getAsMap()); internalCluster().startNode(settingsBuilder( - nodeOrdinal, - mock, - settings)); + nodeOrdinal, + mockClass, + settings)); assertThat(client().admin().cluster().prepareState().setMasterNodeTimeout("1s").execute().actionGet().getState().nodes().masterNodeId(), notNullValue()); } @Test public void nodes_with_different_tags_and_no_tag_set() { startNode(1, - GceComputeServiceTwoNodesDifferentTagsMock.class, + GceComputeServiceTwoNodesDifferentTagsMock.Plugin.class.getName(), Settings.EMPTY); startNode(2, - GceComputeServiceTwoNodesDifferentTagsMock.class, + GceComputeServiceTwoNodesDifferentTagsMock.Plugin.class.getName(), Settings.EMPTY); // We expect having 2 nodes as part of the cluster, let's test that @@ -114,10 +115,10 @@ public class GceComputeEngineTest extends ESIntegTestCase { @Test public void nodes_with_different_tags_and_one_tag_set() { startNode(1, - GceComputeServiceTwoNodesDifferentTagsMock.class, + GceComputeServiceTwoNodesDifferentTagsMock.Plugin.class.getName(), Settings.settingsBuilder().put(Fields.TAGS, "elasticsearch").build()); startNode(2, - GceComputeServiceTwoNodesDifferentTagsMock.class, + GceComputeServiceTwoNodesDifferentTagsMock.Plugin.class.getName(), Settings.settingsBuilder().put(Fields.TAGS, "elasticsearch").build()); // We expect having 1 nodes as part of the cluster, let's test that @@ -133,11 +134,11 @@ public class GceComputeEngineTest extends ESIntegTestCase { @Test public void nodes_with_different_tags_and_two_tag_set() { startNode(1, - GceComputeServiceTwoNodesDifferentTagsMock.class, - Settings.settingsBuilder().put(Fields.TAGS, Lists.newArrayList("elasticsearch", "dev")).build()); + GceComputeServiceTwoNodesDifferentTagsMock.Plugin.class.getName(), + Settings.settingsBuilder().put(Fields.TAGS, Lists.newArrayList("elasticsearch", "dev")).build()); startNode(2, - GceComputeServiceTwoNodesDifferentTagsMock.class, - Settings.settingsBuilder().put(Fields.TAGS, Lists.newArrayList("elasticsearch", "dev")).build()); + GceComputeServiceTwoNodesDifferentTagsMock.Plugin.class.getName(), + Settings.settingsBuilder().put(Fields.TAGS, Lists.newArrayList("elasticsearch", "dev")).build()); // We expect having 1 nodes as part of the cluster, let's test that checkNumberOfNodes(1); @@ -146,10 +147,10 @@ public class GceComputeEngineTest extends ESIntegTestCase { @Test public void nodes_with_same_tags_and_no_tag_set() { startNode(1, - GceComputeServiceTwoNodesSameTagsMock.class, + GceComputeServiceTwoNodesSameTagsMock.Plugin.class.getName(), Settings.EMPTY); startNode(2, - GceComputeServiceTwoNodesSameTagsMock.class, + GceComputeServiceTwoNodesSameTagsMock.Plugin.class.getName(), Settings.EMPTY); // We expect having 2 nodes as part of the cluster, let's test that @@ -159,11 +160,11 @@ public class GceComputeEngineTest extends ESIntegTestCase { @Test public void nodes_with_same_tags_and_one_tag_set() { startNode(1, - GceComputeServiceTwoNodesSameTagsMock.class, - Settings.settingsBuilder().put(Fields.TAGS, "elasticsearch").build()); + GceComputeServiceTwoNodesSameTagsMock.Plugin.class.getName(), + Settings.settingsBuilder().put(Fields.TAGS, "elasticsearch").build()); startNode(2, - GceComputeServiceTwoNodesSameTagsMock.class, - Settings.settingsBuilder().put(Fields.TAGS, "elasticsearch").build()); + GceComputeServiceTwoNodesSameTagsMock.Plugin.class.getName(), + Settings.settingsBuilder().put(Fields.TAGS, "elasticsearch").build()); // We expect having 2 nodes as part of the cluster, let's test that checkNumberOfNodes(2); @@ -172,10 +173,10 @@ public class GceComputeEngineTest extends ESIntegTestCase { @Test public void nodes_with_same_tags_and_two_tags_set() { startNode(1, - GceComputeServiceTwoNodesSameTagsMock.class, - Settings.settingsBuilder().put(Fields.TAGS, Lists.newArrayList("elasticsearch", "dev")).build()); + GceComputeServiceTwoNodesSameTagsMock.Plugin.class.getName(), + Settings.settingsBuilder().put(Fields.TAGS, Lists.newArrayList("elasticsearch", "dev")).build()); startNode(2, - GceComputeServiceTwoNodesSameTagsMock.class, + GceComputeServiceTwoNodesSameTagsMock.Plugin.class.getName(), Settings.settingsBuilder().put(Fields.TAGS, Lists.newArrayList("elasticsearch", "dev")).build()); // We expect having 2 nodes as part of the cluster, let's test that @@ -185,13 +186,13 @@ public class GceComputeEngineTest extends ESIntegTestCase { @Test public void multiple_zones_and_two_nodes_in_same_zone() { startNode(1, - GceComputeServiceTwoNodesOneZoneMock.class, + GceComputeServiceTwoNodesOneZoneMock.Plugin.class.getName(), Settings.settingsBuilder().put(Fields.ZONE, Lists.newArrayList("us-central1-a", "us-central1-b", "us-central1-f", "europe-west1-a", "europe-west1-b")).build()); startNode(2, - GceComputeServiceTwoNodesOneZoneMock.class, - Settings.settingsBuilder().put(Fields.ZONE, Lists.newArrayList("us-central1-a", "us-central1-b", - "us-central1-f", "europe-west1-a", "europe-west1-b")).build()); + GceComputeServiceTwoNodesOneZoneMock.Plugin.class.getName(), + Settings.settingsBuilder().put(Fields.ZONE, Lists.newArrayList("us-central1-a", "us-central1-b", + "us-central1-f", "europe-west1-a", "europe-west1-b")).build()); // We expect having 2 nodes as part of the cluster, let's test that checkNumberOfNodes(2); @@ -200,11 +201,11 @@ public class GceComputeEngineTest extends ESIntegTestCase { @Test public void multiple_zones_and_two_nodes_in_different_zones() { startNode(1, - GceComputeServiceTwoNodesTwoZonesMock.class, + GceComputeServiceTwoNodesTwoZonesMock.Plugin.class.getName(), Settings.settingsBuilder().put(Fields.ZONE, Lists.newArrayList("us-central1-a", "us-central1-b", "us-central1-f", "europe-west1-a", "europe-west1-b")).build()); startNode(2, - GceComputeServiceTwoNodesTwoZonesMock.class, + GceComputeServiceTwoNodesTwoZonesMock.Plugin.class.getName(), Settings.settingsBuilder().put(Fields.ZONE, Lists.newArrayList("us-central1-a", "us-central1-b", "us-central1-f", "europe-west1-a", "europe-west1-b")).build()); @@ -218,9 +219,9 @@ public class GceComputeEngineTest extends ESIntegTestCase { @Test public void zero_node_43() { startNode(1, - GceComputeServiceZeroNodeMock.class, - Settings.settingsBuilder().put(Fields.ZONE, Lists.newArrayList("us-central1-a", "us-central1-b", - "us-central1-f", "europe-west1-a", "europe-west1-b")).build()); + GceComputeServiceZeroNodeMock.Plugin.class.getName(), + Settings.settingsBuilder().put(Fields.ZONE, Lists.newArrayList("us-central1-a", "us-central1-b", + "us-central1-f", "europe-west1-a", "europe-west1-b")).build()); } } diff --git a/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceAbstractMock.java b/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceAbstractMock.java index e885162c22f..25bcec1c8a7 100644 --- a/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceAbstractMock.java +++ b/plugins/cloud-gce/src/test/java/org/elasticsearch/discovery/gce/mock/GceComputeServiceAbstractMock.java @@ -39,7 +39,7 @@ import static com.carrotsearch.randomizedtesting.RandomizedTest.randomInt; /** * */ -public abstract class GceComputeServiceAbstractMock extends AbstractLifecycleComponent +public abstract class GceComputeServiceAbstractMock extends AbstractLifecycleComponent implements GceComputeService { protected abstract List> getTags(); diff --git a/plugins/jvm-example/LICENSE.txt b/plugins/jvm-example/LICENSE.txt new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/plugins/jvm-example/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. diff --git a/plugins/jvm-example/NOTICE.txt b/plugins/jvm-example/NOTICE.txt new file mode 100644 index 00000000000..48809049486 --- /dev/null +++ b/plugins/jvm-example/NOTICE.txt @@ -0,0 +1,8 @@ +Elasticsearch +Copyright 2009-2015 Elasticsearch + +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). + +The LICENSE and NOTICE files for all dependencies may be found in the licenses/ +directory. diff --git a/plugins/jvm-example/README.md b/plugins/jvm-example/README.md new file mode 100644 index 00000000000..09c0559ead1 --- /dev/null +++ b/plugins/jvm-example/README.md @@ -0,0 +1,5 @@ +Example JVM Plugin for Elasticsearch +================================== +Leniency is the root of all evil + + diff --git a/plugins/jvm-example/pom.xml b/plugins/jvm-example/pom.xml new file mode 100644 index 00000000000..b9bf5cc868b --- /dev/null +++ b/plugins/jvm-example/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + + org.elasticsearch.plugin + elasticsearch-plugin + 2.0.0-beta1-SNAPSHOT + + + elasticsearch-jvm-example + Elasticsearch example JVM plugin + Demonstrates all the pluggable Java entry points in Elasticsearch + + + org.elasticsearch.plugin.example.JvmExamplePlugin + jvm_example + false + true + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + diff --git a/plugins/jvm-example/rest-api-spec/test/jvm_example/10_basic.yaml b/plugins/jvm-example/rest-api-spec/test/jvm_example/10_basic.yaml new file mode 100644 index 00000000000..169b924f83d --- /dev/null +++ b/plugins/jvm-example/rest-api-spec/test/jvm_example/10_basic.yaml @@ -0,0 +1,14 @@ +# Integration tests for JVM Example Plugin +# +"JVM Example loaded": + - do: + cluster.state: {} + + # Get master node id + - set: { master_node: master } + + - do: + nodes.info: {} + + - match: { nodes.$master.plugins.0.name: jvm-example } + - match: { nodes.$master.plugins.0.jvm: true } diff --git a/plugins/jvm-example/src/main/java/org/elasticsearch/plugin/example/JvmExamplePlugin.java b/plugins/jvm-example/src/main/java/org/elasticsearch/plugin/example/JvmExamplePlugin.java new file mode 100644 index 00000000000..950040bcd0b --- /dev/null +++ b/plugins/jvm-example/src/main/java/org/elasticsearch/plugin/example/JvmExamplePlugin.java @@ -0,0 +1,115 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch 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.example; + +import org.elasticsearch.common.component.LifecycleComponent; +import org.elasticsearch.common.inject.Module; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.repositories.RepositoriesModule; + +import java.io.Closeable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +/** + * + */ +public class JvmExamplePlugin implements Plugin { + + private final Settings settings; + + public JvmExamplePlugin(Settings settings) { + this.settings = settings; + } + + @Override + public String name() { + return "jvm-example"; + } + + @Override + public String description() { + return "A plugin that extends all extension points"; + } + + @Override + public Collection> modules() { + return Collections.emptyList(); + } + + @Override + public Collection modules(Settings settings) { + Collection modules = new ArrayList<>(); + return modules; + } + + @Override + public Collection> services() { + Collection> services = new ArrayList<>(); + return services; + } + + @Override + public Collection> indexModules() { + return Collections.emptyList(); + } + + @Override + public Collection indexModules(Settings settings) { + return Collections.emptyList(); + } + + @Override + public Collection> indexServices() { + return Collections.emptyList(); + } + + @Override + public Collection> shardModules() { + return Collections.emptyList(); + } + + @Override + public Collection shardModules(Settings settings) { + return Collections.emptyList(); + } + + @Override + public Collection> shardServices() { + return Collections.emptyList(); + } + + @Override + public void processModule(Module module) { + + } + + @Override + public Settings additionalSettings() { + return Settings.EMPTY; + } + + public void onModule(RepositoriesModule repositoriesModule) { + } + + +} diff --git a/core/src/main/java/org/elasticsearch/cache/recycler/DefaultPageCacheRecyclerModule.java b/plugins/jvm-example/src/test/java/org/elasticsearch/plugin/example/JvmExampleRestIT.java similarity index 53% rename from core/src/main/java/org/elasticsearch/cache/recycler/DefaultPageCacheRecyclerModule.java rename to plugins/jvm-example/src/test/java/org/elasticsearch/plugin/example/JvmExampleRestIT.java index 1eafcc72e91..74573a79289 100644 --- a/core/src/main/java/org/elasticsearch/cache/recycler/DefaultPageCacheRecyclerModule.java +++ b/plugins/jvm-example/src/test/java/org/elasticsearch/plugin/example/JvmExampleRestIT.java @@ -17,23 +17,25 @@ * under the License. */ -package org.elasticsearch.cache.recycler; +package org.elasticsearch.plugin.example; -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.settings.Settings; +import com.carrotsearch.randomizedtesting.annotations.Name; +import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; +import org.elasticsearch.test.rest.ESRestTestCase; +import org.elasticsearch.test.rest.RestTestCandidate; +import org.elasticsearch.test.rest.parser.RestTestParseException; -/** - */ -public class DefaultPageCacheRecyclerModule extends AbstractModule { +import java.io.IOException; - private final Settings settings; +public class JvmExampleRestIT extends ESRestTestCase { - public DefaultPageCacheRecyclerModule(Settings settings) { - this.settings = settings; + public JvmExampleRestIT(@Name("yaml") RestTestCandidate testCandidate) { + super(testCandidate); } - @Override - protected void configure() { - bind(PageCacheRecycler.class).asEagerSingleton(); + @ParametersFactory + public static Iterable parameters() throws IOException, RestTestParseException { + return ESRestTestCase.createParameters(0, 1); } } + diff --git a/plugins/pom.xml b/plugins/pom.xml index f0c7d22a10c..f45f7f54851 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -437,6 +437,7 @@ lang-python lang-javascript mapper-size + jvm-example site-example diff --git a/qa/smoke-test-plugins/pom.xml b/qa/smoke-test-plugins/pom.xml index 4a02c591306..6a294402f52 100644 --- a/qa/smoke-test-plugins/pom.xml +++ b/qa/smoke-test-plugins/pom.xml @@ -349,6 +349,14 @@ true + + org.elasticsearch.plugin + elasticsearch-jvm-example + ${elasticsearch.version} + zip + true + + From 1b3cd504a5558567611a352c4ce8dd45ef2715eb Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Mon, 10 Aug 2015 16:57:02 -0700 Subject: [PATCH 04/10] test: quiet netty integ test --- .../transport/netty/NettyTransportMultiPortIntegrationIT.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java b/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java index 132462e875d..00747192349 100644 --- a/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java +++ b/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java @@ -18,6 +18,7 @@ */ package org.elasticsearch.transport.netty; +import org.apache.lucene.util.LuceneTestCase; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus; import org.elasticsearch.action.admin.cluster.node.info.NodeInfo; @@ -38,6 +39,7 @@ import static org.elasticsearch.test.ESIntegTestCase.Scope; import static org.hamcrest.Matchers.*; @ClusterScope(scope = Scope.SUITE, numDataNodes = 1, numClientNodes = 0) +@LuceneTestCase.AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/12788") public class NettyTransportMultiPortIntegrationIT extends ESIntegTestCase { private static int randomPort = -1; From 3354a816fca4b8ce5af622c848bcd5fd1161e3b7 Mon Sep 17 00:00:00 2001 From: Igor Motov Date: Fri, 7 Aug 2015 17:09:08 -0400 Subject: [PATCH 05/10] Changes in unassigned info and version might not be transferred as part of cluster state diffs The equalTo logic of ShardRouting doesn't take version and unassignedInfo into the account when compares shard routings. Since cluster state diff relies on equal to detect the changes that needs to be sent to other cluster, this omission might lead to changes not being properly propagated to other nodes in the cluster. Closes #12387 --- .../cluster/routing/ShardRouting.java | 9 +- .../cluster/routing/UnassignedInfo.java | 23 +++++ .../cluster/ClusterStateDiffIT.java | 30 ++++++- .../routing/RandomShardRoutingMutator.java | 88 +++++++++++++++++++ .../elasticsearch/test/ESIntegTestCase.java | 5 +- .../elasticsearch/test/XContentTestUtils.java | 58 ++++++++---- 6 files changed, 187 insertions(+), 26 deletions(-) create mode 100644 core/src/test/java/org/elasticsearch/cluster/routing/RandomShardRoutingMutator.java diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/ShardRouting.java b/core/src/main/java/org/elasticsearch/cluster/routing/ShardRouting.java index e1b499fc606..9c0af60a16f 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/ShardRouting.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/ShardRouting.java @@ -608,7 +608,12 @@ public final class ShardRouting implements Streamable, ToXContent { return false; } ShardRouting that = (ShardRouting) o; - // TODO: add version + unassigned info check. see #12387 + if (version != that.version) { + return false; + } + if (unassignedInfo != null ? !unassignedInfo.equals(that.unassignedInfo) : that.unassignedInfo != null) { + return false; + } return equalsIgnoringMetaData(that); } @@ -626,8 +631,10 @@ public final class ShardRouting implements Streamable, ToXContent { result = 31 * result + (relocatingNodeId != null ? relocatingNodeId.hashCode() : 0); result = 31 * result + (primary ? 1 : 0); result = 31 * result + (state != null ? state.hashCode() : 0); + result = 31 * result + (int) (version ^ (version >>> 32)); result = 31 * result + (restoreSource != null ? restoreSource.hashCode() : 0); result = 31 * result + (allocationId != null ? allocationId.hashCode() : 0); + result = 31 * result + (unassignedInfo != null ? unassignedInfo.hashCode() : 0); return hashCode = result; } diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java b/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java index 1c602491f26..e6dc7184cc3 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java @@ -293,4 +293,27 @@ public class UnassignedInfo implements ToXContent, Writeable { builder.endObject(); return builder; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + UnassignedInfo that = (UnassignedInfo) o; + + if (timestamp != that.timestamp) return false; + if (reason != that.reason) return false; + if (message != null ? !message.equals(that.message) : that.message != null) return false; + return !(failure != null ? !failure.equals(that.failure) : that.failure != null); + + } + + @Override + public int hashCode() { + int result = reason != null ? reason.hashCode() : 0; + result = 31 * result + (int) (timestamp ^ (timestamp >>> 32)); + result = 31 * result + (message != null ? message.hashCode() : 0); + result = 31 * result + (failure != null ? failure.hashCode() : 0); + return result; + } } diff --git a/core/src/test/java/org/elasticsearch/cluster/ClusterStateDiffIT.java b/core/src/test/java/org/elasticsearch/cluster/ClusterStateDiffIT.java index a33730b8342..edd6254b511 100644 --- a/core/src/test/java/org/elasticsearch/cluster/ClusterStateDiffIT.java +++ b/core/src/test/java/org/elasticsearch/cluster/ClusterStateDiffIT.java @@ -47,8 +47,10 @@ import org.junit.Test; import java.util.List; import static org.elasticsearch.cluster.metadata.AliasMetaData.newAliasMetaDataBuilder; +import static org.elasticsearch.cluster.routing.RandomShardRoutingMutator.randomChange; +import static org.elasticsearch.cluster.routing.RandomShardRoutingMutator.randomReason; import static org.elasticsearch.test.XContentTestUtils.convertToMap; -import static org.elasticsearch.test.XContentTestUtils.mapsEqualIgnoringArrayOrder; +import static org.elasticsearch.test.XContentTestUtils.differenceBetweenMapsIgnoringArrayOrder; import static org.elasticsearch.test.VersionUtils.randomVersion; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; @@ -151,7 +153,7 @@ public class ClusterStateDiffIT extends ESIntegTestCase { assertThat(clusterStateFromDiffs.metaData().equalsAliases(clusterState.metaData()), is(true)); // JSON Serialization test - make sure that both states produce similar JSON - assertThat(mapsEqualIgnoringArrayOrder(convertToMap(clusterStateFromDiffs), convertToMap(clusterState)), equalTo(true)); + assertNull(differenceBetweenMapsIgnoringArrayOrder(convertToMap(clusterStateFromDiffs), convertToMap(clusterState))); // Smoke test - we cannot compare bytes to bytes because some elements might get serialized in different order // however, serialized size should remain the same @@ -200,7 +202,7 @@ public class ClusterStateDiffIT extends ESIntegTestCase { if (randomBoolean()) { builder.remove(index); } else { - builder.add(randomIndexRoutingTable(index, clusterState.nodes().nodes().keys().toArray(String.class))); + builder.add(randomChangeToIndexRoutingTable(clusterState.routingTable().indicesRouting().get(index), clusterState.nodes().nodes().keys().toArray(String.class))); } } } @@ -222,14 +224,34 @@ public class ClusterStateDiffIT extends ESIntegTestCase { IndexShardRoutingTable.Builder indexShard = new IndexShardRoutingTable.Builder(new ShardId(index, i)); int replicaCount = randomIntBetween(1, 10); for (int j = 0; j < replicaCount; j++) { + UnassignedInfo unassignedInfo = null; + if (randomInt(5) == 1) { + unassignedInfo = new UnassignedInfo(randomReason(), randomAsciiOfLength(10)); + } indexShard.addShard( - TestShardRouting.newShardRouting(index, i, randomFrom(nodeIds), null, null, j == 0, ShardRoutingState.fromValue((byte) randomIntBetween(2, 4)), 1)); + TestShardRouting.newShardRouting(index, i, randomFrom(nodeIds), null, null, j == 0, + ShardRoutingState.fromValue((byte) randomIntBetween(2, 4)), 1, unassignedInfo)); } builder.addIndexShard(indexShard.build()); } return builder.build(); } + /** + * Randomly updates index routing table in the cluster state + */ + private IndexRoutingTable randomChangeToIndexRoutingTable(IndexRoutingTable original, String[] nodes) { + IndexRoutingTable.Builder builder = IndexRoutingTable.builder(original.getIndex()); + for (ObjectCursor indexShardRoutingTable : original.shards().values()) { + for (ShardRouting shardRouting : indexShardRoutingTable.value.shards()) { + final ShardRouting newShardRouting = new ShardRouting(shardRouting); + randomChange(newShardRouting, nodes); + builder.addShard(indexShardRoutingTable.value, newShardRouting); + } + } + return builder.build(); + } + /** * Randomly creates or removes cluster blocks */ diff --git a/core/src/test/java/org/elasticsearch/cluster/routing/RandomShardRoutingMutator.java b/core/src/test/java/org/elasticsearch/cluster/routing/RandomShardRoutingMutator.java new file mode 100644 index 00000000000..4ca849d8ae4 --- /dev/null +++ b/core/src/test/java/org/elasticsearch/cluster/routing/RandomShardRoutingMutator.java @@ -0,0 +1,88 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch 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.cluster.routing; + +import static org.elasticsearch.test.ESTestCase.randomAsciiOfLength; +import static org.elasticsearch.test.ESTestCase.randomFrom; +import static org.elasticsearch.test.ESTestCase.randomInt; + +/** + * Utility class the makes random modifications to ShardRouting + */ +public final class RandomShardRoutingMutator { + private RandomShardRoutingMutator() { + + } + + public static void randomChange(ShardRouting shardRouting, String[] nodes) { + switch (randomInt(3)) { + case 0: + if (shardRouting.unassigned() == false) { + shardRouting.moveToUnassigned(new UnassignedInfo(randomReason(), randomAsciiOfLength(10))); + } else if (shardRouting.unassignedInfo() != null) { + shardRouting.updateUnassignedInfo(new UnassignedInfo(randomReason(), randomAsciiOfLength(10))); + } + break; + case 1: + if (shardRouting.unassigned()) { + shardRouting.initialize(randomFrom(nodes)); + } + break; + case 2: + if (shardRouting.primary()) { + shardRouting.moveFromPrimary(); + } else { + shardRouting.moveToPrimary(); + } + break; + case 3: + if (shardRouting.initializing()) { + shardRouting.moveToStarted(); + } + break; + } + } + + + public static UnassignedInfo.Reason randomReason() { + switch (randomInt(9)) { + case 0: + return UnassignedInfo.Reason.INDEX_CREATED; + case 1: + return UnassignedInfo.Reason.CLUSTER_RECOVERED; + case 2: + return UnassignedInfo.Reason.INDEX_REOPENED; + case 3: + return UnassignedInfo.Reason.DANGLING_INDEX_IMPORTED; + case 4: + return UnassignedInfo.Reason.NEW_INDEX_RESTORED; + case 5: + return UnassignedInfo.Reason.EXISTING_INDEX_RESTORED; + case 6: + return UnassignedInfo.Reason.REPLICA_ADDED; + case 7: + return UnassignedInfo.Reason.ALLOCATION_FAILED; + case 8: + return UnassignedInfo.Reason.NODE_LEFT; + default: + return UnassignedInfo.Reason.REROUTE_CANCELLED; + } + } +} diff --git a/core/src/test/java/org/elasticsearch/test/ESIntegTestCase.java b/core/src/test/java/org/elasticsearch/test/ESIntegTestCase.java index 0784d2a75f3..8d4b7c4cb51 100644 --- a/core/src/test/java/org/elasticsearch/test/ESIntegTestCase.java +++ b/core/src/test/java/org/elasticsearch/test/ESIntegTestCase.java @@ -67,7 +67,6 @@ import org.elasticsearch.client.Client; import org.elasticsearch.client.Requests; import org.elasticsearch.cluster.ClusterService; import org.elasticsearch.cluster.ClusterState; -import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.metadata.MappingMetaData; import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.routing.IndexRoutingTable; @@ -140,7 +139,7 @@ import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF import static org.elasticsearch.common.settings.Settings.settingsBuilder; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.test.XContentTestUtils.convertToMap; -import static org.elasticsearch.test.XContentTestUtils.mapsEqualIgnoringArrayOrder; +import static org.elasticsearch.test.XContentTestUtils.differenceBetweenMapsIgnoringArrayOrder; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*; import static org.hamcrest.Matchers.*; @@ -1072,7 +1071,7 @@ public abstract class ESIntegTestCase extends ESTestCase { // but we can compare serialization sizes - they should be the same assertEquals("clusterstate size does not match", masterClusterStateSize, localClusterStateSize); // Compare JSON serialization - assertTrue("clusterstate JSON serialization does not match", mapsEqualIgnoringArrayOrder(masterStateMap, localStateMap)); + assertNull("clusterstate JSON serialization does not match", differenceBetweenMapsIgnoringArrayOrder(masterStateMap, localStateMap)); } catch (AssertionError error) { logger.error("Cluster state from master:\n{}\nLocal cluster state:\n{}", masterClusterState.toString(), localClusterState.toString()); throw error; diff --git a/core/src/test/java/org/elasticsearch/test/XContentTestUtils.java b/core/src/test/java/org/elasticsearch/test/XContentTestUtils.java index 917c66a452b..647930398b6 100644 --- a/core/src/test/java/org/elasticsearch/test/XContentTestUtils.java +++ b/core/src/test/java/org/elasticsearch/test/XContentTestUtils.java @@ -46,58 +46,80 @@ public final class XContentTestUtils { /** - * Compares to maps generated from XContentObjects. The order of elements in arrays is ignored + * Compares to maps generated from XContentObjects. The order of elements in arrays is ignored. + * + * @return null if maps are equal or path to the element where the difference was found */ - public static boolean mapsEqualIgnoringArrayOrder(Map first, Map second) { + public static String differenceBetweenMapsIgnoringArrayOrder(Map first, Map second) { + return differenceBetweenMapsIgnoringArrayOrder("", first, second); + } + + private static String differenceBetweenMapsIgnoringArrayOrder(String path, Map first, Map second) { if (first.size() != second.size()) { - return false; + return path + ": sizes of the maps don't match: " + first.size() + " != " + second.size(); } for (String key : first.keySet()) { - if (objectsEqualIgnoringArrayOrder(first.get(key), second.get(key)) == false) { - return false; + String reason = differenceBetweenObjectsIgnoringArrayOrder(path + "/" + key, first.get(key), second.get(key)); + if (reason != null) { + return reason; } } - return true; + return null; } @SuppressWarnings("unchecked") - private static boolean objectsEqualIgnoringArrayOrder(Object first, Object second) { - if (first == null ) { - return second == null; + private static String differenceBetweenObjectsIgnoringArrayOrder(String path, Object first, Object second) { + if (first == null) { + if (second == null) { + return null; + } else { + return path + ": first element is null, the second element is not null"; + } } else if (first instanceof List) { - if (second instanceof List) { + if (second instanceof List) { List secondList = Lists.newArrayList((List) second); List firstList = (List) first; if (firstList.size() == secondList.size()) { + String reason = path + ": no matches found"; for (Object firstObj : firstList) { boolean found = false; for (Object secondObj : secondList) { - if (objectsEqualIgnoringArrayOrder(firstObj, secondObj)) { + reason = differenceBetweenObjectsIgnoringArrayOrder(path + "/*", firstObj, secondObj); + if (reason == null) { secondList.remove(secondObj); found = true; break; } } if (found == false) { - return false; + return reason; } } - return secondList.isEmpty(); + if (secondList.isEmpty()) { + return null; + } else { + return path + ": the second list is not empty"; + } } else { - return false; + return path + ": sizes of the arrays don't match: " + firstList.size() + " != " + secondList.size(); } } else { - return false; + return path + ": the second element is not an array"; } } else if (first instanceof Map) { if (second instanceof Map) { - return mapsEqualIgnoringArrayOrder((Map) first, (Map) second); + return differenceBetweenMapsIgnoringArrayOrder(path, (Map) first, (Map) second); } else { - return false; + return path + ": the second element is not a map"; } } else { - return first.equals(second); + if (first.equals(second)) { + return null; + } else { + return path + ": the elements don't match: [" + first + "] != [" + second + "]"; + } + } } From 6fea6c542cca57710191ab23c76029e28e3f217b Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Mon, 10 Aug 2015 20:55:47 -0700 Subject: [PATCH 06/10] Test: Fix netty integ test to ensure local mode is not used. closes #12788 --- .../transport/netty/NettyTransportMultiPortIntegrationIT.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java b/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java index 00747192349..34636a62fd0 100644 --- a/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java +++ b/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java @@ -39,7 +39,7 @@ import static org.elasticsearch.test.ESIntegTestCase.Scope; import static org.hamcrest.Matchers.*; @ClusterScope(scope = Scope.SUITE, numDataNodes = 1, numClientNodes = 0) -@LuceneTestCase.AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/12788") +//@LuceneTestCase.AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/12788") public class NettyTransportMultiPortIntegrationIT extends ESIntegTestCase { private static int randomPort = -1; @@ -56,6 +56,7 @@ public class NettyTransportMultiPortIntegrationIT extends ESIntegTestCase { .put("network.host", "127.0.0.1") .put(TransportModule.TRANSPORT_TYPE_KEY, "netty") .put("node.mode", "network") + .put("node.local", false) // ensure randomization doesn't set local mode, since this has higher precedence .put("transport.profiles.client1.port", randomPortRange) .put("transport.profiles.client1.publish_host", "127.0.0.7") .put("transport.profiles.client1.publish_port", "4321") From 8a587ead8972a7d68e1e3cab93e0b154913fe113 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Mon, 10 Aug 2015 21:56:33 -0700 Subject: [PATCH 07/10] Mappings: Validate parsed document does not have trailing garbage that is invalid json See #2315 --- .../elasticsearch/index/mapper/DocumentParser.java | 8 ++++++++ .../mapper/source/DefaultSourceMappingTests.java | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java b/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java index 6aa66f20d6f..9e60ef5caa8 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java @@ -25,6 +25,7 @@ import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexableField; import org.apache.lucene.util.CloseableThreadLocal; +import org.elasticsearch.Version; import org.elasticsearch.common.Strings; import org.elasticsearch.common.joda.FormatDateTimeFormatter; import org.elasticsearch.common.settings.Settings; @@ -127,6 +128,13 @@ class DocumentParser implements Closeable { parser.nextToken(); } + // try to parse the next token, this should be null if the object is ended properly + // but will throw a JSON exception if the extra tokens is not valid JSON (this will be handled by the catch) + if (Version.indexCreated(indexSettings).onOrAfter(Version.V_2_0_0_beta1)) { + token = parser.nextToken(); + assert token == null; // double check, in tests, that we didn't end parsing early + } + for (MetadataFieldMapper metadataMapper : mapping.metadataMappers) { metadataMapper.postParse(context); } diff --git a/core/src/test/java/org/elasticsearch/index/mapper/source/DefaultSourceMappingTests.java b/core/src/test/java/org/elasticsearch/index/mapper/source/DefaultSourceMappingTests.java index 6e055f7403d..f6a4c30c863 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/source/DefaultSourceMappingTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/source/DefaultSourceMappingTests.java @@ -309,4 +309,18 @@ public class DefaultSourceMappingTests extends ESSingleNodeTestCase { .endObject().endObject().string(); assertFalse(parser.parse(mapping).sourceMapper().isComplete()); } + + public void testSourceObjectContainsExtraTokens() throws Exception { + String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string(); + DocumentMapper documentMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping); + + try { + documentMapper.parse("test", "type", "1", new BytesArray("{}}")); // extra end object (invalid JSON) + fail("Expected parse exception"); + } catch (MapperParsingException e) { + assertNotNull(e.getRootCause()); + String message = e.getRootCause().getMessage(); + assertTrue(message, message.contains("Unexpected close marker '}'")); + } + } } From b81f5f61424631958328c1b3c991f4989e893907 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Mon, 10 Aug 2015 23:13:19 -0700 Subject: [PATCH 08/10] Revert "Merge pull request #11414 from rjernst/fix/2315" This reverts commit 937732b17d5f64d1f92957193dafc7a73bed7bc9, reversing changes made to 6fea6c542cca57710191ab23c76029e28e3f217b. --- .../elasticsearch/index/mapper/DocumentParser.java | 8 -------- .../mapper/source/DefaultSourceMappingTests.java | 14 -------------- 2 files changed, 22 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java b/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java index 9e60ef5caa8..6aa66f20d6f 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java @@ -25,7 +25,6 @@ import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexableField; import org.apache.lucene.util.CloseableThreadLocal; -import org.elasticsearch.Version; import org.elasticsearch.common.Strings; import org.elasticsearch.common.joda.FormatDateTimeFormatter; import org.elasticsearch.common.settings.Settings; @@ -128,13 +127,6 @@ class DocumentParser implements Closeable { parser.nextToken(); } - // try to parse the next token, this should be null if the object is ended properly - // but will throw a JSON exception if the extra tokens is not valid JSON (this will be handled by the catch) - if (Version.indexCreated(indexSettings).onOrAfter(Version.V_2_0_0_beta1)) { - token = parser.nextToken(); - assert token == null; // double check, in tests, that we didn't end parsing early - } - for (MetadataFieldMapper metadataMapper : mapping.metadataMappers) { metadataMapper.postParse(context); } diff --git a/core/src/test/java/org/elasticsearch/index/mapper/source/DefaultSourceMappingTests.java b/core/src/test/java/org/elasticsearch/index/mapper/source/DefaultSourceMappingTests.java index f6a4c30c863..6e055f7403d 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/source/DefaultSourceMappingTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/source/DefaultSourceMappingTests.java @@ -309,18 +309,4 @@ public class DefaultSourceMappingTests extends ESSingleNodeTestCase { .endObject().endObject().string(); assertFalse(parser.parse(mapping).sourceMapper().isComplete()); } - - public void testSourceObjectContainsExtraTokens() throws Exception { - String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string(); - DocumentMapper documentMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping); - - try { - documentMapper.parse("test", "type", "1", new BytesArray("{}}")); // extra end object (invalid JSON) - fail("Expected parse exception"); - } catch (MapperParsingException e) { - assertNotNull(e.getRootCause()); - String message = e.getRootCause().getMessage(); - assertTrue(message, message.contains("Unexpected close marker '}'")); - } - } } From f4827e55e38fbbdb2d918081409a48caf29cd38e Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Tue, 11 Aug 2015 00:43:29 -0700 Subject: [PATCH 09/10] Test: More attempts at forcing netty test to always use netty --- .../netty/NettyTransportMultiPortIntegrationIT.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java b/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java index 34636a62fd0..a930f4b8553 100644 --- a/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java +++ b/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java @@ -18,7 +18,6 @@ */ package org.elasticsearch.transport.netty; -import org.apache.lucene.util.LuceneTestCase; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus; import org.elasticsearch.action.admin.cluster.node.info.NodeInfo; @@ -28,6 +27,8 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.junit.annotations.Network; +import org.elasticsearch.test.transport.AssertingLocalTransport; +import org.elasticsearch.test.transport.MockTransportService; import org.elasticsearch.transport.TransportModule; import org.junit.Test; @@ -39,7 +40,6 @@ import static org.elasticsearch.test.ESIntegTestCase.Scope; import static org.hamcrest.Matchers.*; @ClusterScope(scope = Scope.SUITE, numDataNodes = 1, numClientNodes = 0) -//@LuceneTestCase.AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/12788") public class NettyTransportMultiPortIntegrationIT extends ESIntegTestCase { private static int randomPort = -1; @@ -51,7 +51,7 @@ public class NettyTransportMultiPortIntegrationIT extends ESIntegTestCase { randomPort = randomIntBetween(49152, 65525); randomPortRange = String.format(Locale.ROOT, "%s-%s", randomPort, randomPort+10); } - return settingsBuilder() + Settings.Builder builder = settingsBuilder() .put(super.nodeSettings(nodeOrdinal)) .put("network.host", "127.0.0.1") .put(TransportModule.TRANSPORT_TYPE_KEY, "netty") @@ -60,8 +60,11 @@ public class NettyTransportMultiPortIntegrationIT extends ESIntegTestCase { .put("transport.profiles.client1.port", randomPortRange) .put("transport.profiles.client1.publish_host", "127.0.0.7") .put("transport.profiles.client1.publish_port", "4321") - .put("transport.profiles.client1.reuse_address", true) - .build(); + .put("transport.profiles.client1.reuse_address", true); + // more things that might have been randomized to remove to ensure a real network stack + builder.removeArrayElement("plugin.types", MockTransportService.Plugin.class.getName()); + builder.removeArrayElement("plugin.types", AssertingLocalTransport.Plugin.class.getName()); + return builder.build(); } @Test From f9487f74510e239c49e0fe7267df3155e0646923 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Tue, 11 Aug 2015 10:06:55 +0200 Subject: [PATCH 10/10] Apply additional plugin settings only if settings are not explicit We have a way to allow a plugin to specify additional settings. These settings should only be applied if they are not already existing in the node settings. --- .../common/settings/Settings.java | 37 ------------------- .../org/elasticsearch/plugins/Plugin.java | 3 +- .../elasticsearch/plugins/PluginsService.java | 5 +-- .../test/ESBackcompatTestCase.java | 4 +- .../NettyTransportMultiPortIntegrationIT.java | 4 -- 5 files changed, 6 insertions(+), 47 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/common/settings/Settings.java b/core/src/main/java/org/elasticsearch/common/settings/Settings.java index bbbde3886c0..2671874f86f 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/Settings.java +++ b/core/src/main/java/org/elasticsearch/common/settings/Settings.java @@ -786,43 +786,6 @@ public final class Settings implements ToXContent { return map.remove(key); } - /** - * Removes the specified value from the given key. - * Returns true if the value was found and removed, false otherwise. - */ - public boolean removeArrayElement(String key, String value) { - // TODO: this is too crazy, we should just have a multimap... - String oldValue = get(key); - if (oldValue != null) { - // single valued case - boolean match = oldValue.equals(value); - if (match) { - remove(key); - } - return match; - } - - // multi valued - int i = 0; - while (true) { - String toCheck = map.get(key + '.' + i++); - if (toCheck == null) { - return false; - } else if (toCheck.equals(value)) { - break; - } - } - // found the value, shift values after it back one index - int j = i + 1; - while (true) { - String toMove = map.get(key + '.' + j++); - if (toMove == null) { - return true; - } - put(key + '.' + i++, toMove); - } - } - /** * Returns a setting value based on the setting key. */ diff --git a/core/src/main/java/org/elasticsearch/plugins/Plugin.java b/core/src/main/java/org/elasticsearch/plugins/Plugin.java index c5ee0fcd7f6..0a459a55277 100644 --- a/core/src/main/java/org/elasticsearch/plugins/Plugin.java +++ b/core/src/main/java/org/elasticsearch/plugins/Plugin.java @@ -99,7 +99,8 @@ public interface Plugin { void processModule(Module module); /** - * Additional node settings loaded by the plugin + * Additional node settings loaded by the plugin. Note that settings that are explicit in the nodes settings can't be + * overwritten with the additional settings. These settings added if they don't exist. */ Settings additionalSettings(); } diff --git a/core/src/main/java/org/elasticsearch/plugins/PluginsService.java b/core/src/main/java/org/elasticsearch/plugins/PluginsService.java index 64e3bc39662..c895bf96e18 100644 --- a/core/src/main/java/org/elasticsearch/plugins/PluginsService.java +++ b/core/src/main/java/org/elasticsearch/plugins/PluginsService.java @@ -202,12 +202,11 @@ public class PluginsService extends AbstractComponent { } public Settings updatedSettings() { - Settings.Builder builder = Settings.settingsBuilder() - .put(this.settings); + final Settings.Builder builder = Settings.settingsBuilder(); for (Tuple plugin : plugins) { builder.put(plugin.v2().additionalSettings()); } - return builder.build(); + return builder.put(this.settings).build(); } public Collection> modules() { diff --git a/core/src/test/java/org/elasticsearch/test/ESBackcompatTestCase.java b/core/src/test/java/org/elasticsearch/test/ESBackcompatTestCase.java index 4fab1c0bb3d..4c8c0f976de 100644 --- a/core/src/test/java/org/elasticsearch/test/ESBackcompatTestCase.java +++ b/core/src/test/java/org/elasticsearch/test/ESBackcompatTestCase.java @@ -251,9 +251,9 @@ public abstract class ESBackcompatTestCase extends ESIntegTestCase { protected Settings commonNodeSettings(int nodeOrdinal) { Settings.Builder builder = Settings.builder().put(requiredSettings()); - builder.removeArrayElement("plugin.types", MockTransportService.Plugin.class.getName()); - builder.removeArrayElement("plugin.types", AssertingLocalTransport.class.getName()); builder.put(TransportModule.TRANSPORT_TYPE_KEY, "netty"); // run same transport / disco as external + builder.put("node.mode", "network"); + if (compatibilityVersion().before(Version.V_1_3_2)) { // if we test against nodes before 1.3.2 we disable all the compression due to a known bug // see #7210 diff --git a/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java b/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java index a930f4b8553..78ba16ac750 100644 --- a/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java +++ b/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportMultiPortIntegrationIT.java @@ -56,14 +56,10 @@ public class NettyTransportMultiPortIntegrationIT extends ESIntegTestCase { .put("network.host", "127.0.0.1") .put(TransportModule.TRANSPORT_TYPE_KEY, "netty") .put("node.mode", "network") - .put("node.local", false) // ensure randomization doesn't set local mode, since this has higher precedence .put("transport.profiles.client1.port", randomPortRange) .put("transport.profiles.client1.publish_host", "127.0.0.7") .put("transport.profiles.client1.publish_port", "4321") .put("transport.profiles.client1.reuse_address", true); - // more things that might have been randomized to remove to ensure a real network stack - builder.removeArrayElement("plugin.types", MockTransportService.Plugin.class.getName()); - builder.removeArrayElement("plugin.types", AssertingLocalTransport.Plugin.class.getName()); return builder.build(); }