diff --git a/elasticsearch/license/licensor/bin/key-pair-generator b/elasticsearch/license-tools/bin/key-pair-generator similarity index 100% rename from elasticsearch/license/licensor/bin/key-pair-generator rename to elasticsearch/license-tools/bin/key-pair-generator diff --git a/elasticsearch/license/licensor/bin/license-generator b/elasticsearch/license-tools/bin/license-generator similarity index 100% rename from elasticsearch/license/licensor/bin/license-generator rename to elasticsearch/license-tools/bin/license-generator diff --git a/elasticsearch/license/licensor/bin/verify-license b/elasticsearch/license-tools/bin/verify-license similarity index 100% rename from elasticsearch/license/licensor/bin/verify-license rename to elasticsearch/license-tools/bin/verify-license diff --git a/elasticsearch/license/licensor/build.gradle b/elasticsearch/license-tools/build.gradle similarity index 66% rename from elasticsearch/license/licensor/build.gradle rename to elasticsearch/license-tools/build.gradle index 33f66883b2f..2fbc288b337 100644 --- a/elasticsearch/license/licensor/build.gradle +++ b/elasticsearch/license-tools/build.gradle @@ -1,9 +1,13 @@ apply plugin: 'elasticsearch.build' dependencies { - compile project(':x-plugins:elasticsearch:license:base') + compile project(':x-plugins:elasticsearch:x-pack') compile "org.elasticsearch:elasticsearch:${version}" testCompile "org.elasticsearch.test:framework:${version}" } +project.forbiddenPatterns { + exclude '**/*.key' +} + dependencyLicenses.enabled = false diff --git a/elasticsearch/license/licensor/dev-tools/integration-tests.xml b/elasticsearch/license-tools/dev-tools/integration-tests.xml similarity index 100% rename from elasticsearch/license/licensor/dev-tools/integration-tests.xml rename to elasticsearch/license-tools/dev-tools/integration-tests.xml diff --git a/elasticsearch/license/licensor/sample/license_spec.json b/elasticsearch/license-tools/sample/license_spec.json similarity index 100% rename from elasticsearch/license/licensor/sample/license_spec.json rename to elasticsearch/license-tools/sample/license_spec.json diff --git a/elasticsearch/license/licensor/src/main/java/org/elasticsearch/license/licensor/LicenseSigner.java b/elasticsearch/license-tools/src/main/java/org/elasticsearch/license/licensor/LicenseSigner.java similarity index 95% rename from elasticsearch/license/licensor/src/main/java/org/elasticsearch/license/licensor/LicenseSigner.java rename to elasticsearch/license-tools/src/main/java/org/elasticsearch/license/licensor/LicenseSigner.java index 0bebf26532f..ab6b9a61d5b 100644 --- a/elasticsearch/license/licensor/src/main/java/org/elasticsearch/license/licensor/LicenseSigner.java +++ b/elasticsearch/license-tools/src/main/java/org/elasticsearch/license/licensor/LicenseSigner.java @@ -7,13 +7,12 @@ package org.elasticsearch.license.licensor; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRefIterator; -import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.license.core.CryptUtils; -import org.elasticsearch.license.core.License; +import org.elasticsearch.license.CryptUtils; +import org.elasticsearch.license.License; import java.io.IOException; import java.nio.ByteBuffer; diff --git a/elasticsearch/license/licensor/src/main/java/org/elasticsearch/license/licensor/tools/KeyPairGeneratorTool.java b/elasticsearch/license-tools/src/main/java/org/elasticsearch/license/licensor/tools/KeyPairGeneratorTool.java similarity index 95% rename from elasticsearch/license/licensor/src/main/java/org/elasticsearch/license/licensor/tools/KeyPairGeneratorTool.java rename to elasticsearch/license-tools/src/main/java/org/elasticsearch/license/licensor/tools/KeyPairGeneratorTool.java index 0e31670f864..ba3a0c82d50 100644 --- a/elasticsearch/license/licensor/src/main/java/org/elasticsearch/license/licensor/tools/KeyPairGeneratorTool.java +++ b/elasticsearch/license-tools/src/main/java/org/elasticsearch/license/licensor/tools/KeyPairGeneratorTool.java @@ -20,8 +20,8 @@ import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; -import static org.elasticsearch.license.core.CryptUtils.writeEncryptedPrivateKey; -import static org.elasticsearch.license.core.CryptUtils.writeEncryptedPublicKey; +import static org.elasticsearch.license.CryptUtils.writeEncryptedPrivateKey; +import static org.elasticsearch.license.CryptUtils.writeEncryptedPublicKey; public class KeyPairGeneratorTool extends Command { diff --git a/elasticsearch/license/licensor/src/main/java/org/elasticsearch/license/licensor/tools/LicenseGeneratorTool.java b/elasticsearch/license-tools/src/main/java/org/elasticsearch/license/licensor/tools/LicenseGeneratorTool.java similarity index 98% rename from elasticsearch/license/licensor/src/main/java/org/elasticsearch/license/licensor/tools/LicenseGeneratorTool.java rename to elasticsearch/license-tools/src/main/java/org/elasticsearch/license/licensor/tools/LicenseGeneratorTool.java index feaa4dc3a74..de1b9e52428 100644 --- a/elasticsearch/license/licensor/src/main/java/org/elasticsearch/license/licensor/tools/LicenseGeneratorTool.java +++ b/elasticsearch/license-tools/src/main/java/org/elasticsearch/license/licensor/tools/LicenseGeneratorTool.java @@ -20,7 +20,7 @@ import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.license.core.License; +import org.elasticsearch.license.License; import org.elasticsearch.license.licensor.LicenseSigner; public class LicenseGeneratorTool extends Command { diff --git a/elasticsearch/license/licensor/src/main/java/org/elasticsearch/license/licensor/tools/LicenseVerificationTool.java b/elasticsearch/license-tools/src/main/java/org/elasticsearch/license/licensor/tools/LicenseVerificationTool.java similarity index 97% rename from elasticsearch/license/licensor/src/main/java/org/elasticsearch/license/licensor/tools/LicenseVerificationTool.java rename to elasticsearch/license-tools/src/main/java/org/elasticsearch/license/licensor/tools/LicenseVerificationTool.java index 9a6d67bceef..90cf11afea5 100644 --- a/elasticsearch/license/licensor/src/main/java/org/elasticsearch/license/licensor/tools/LicenseVerificationTool.java +++ b/elasticsearch/license-tools/src/main/java/org/elasticsearch/license/licensor/tools/LicenseVerificationTool.java @@ -20,8 +20,8 @@ import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.core.LicenseVerifier; +import org.elasticsearch.license.License; +import org.elasticsearch.license.LicenseVerifier; public class LicenseVerificationTool extends Command { diff --git a/elasticsearch/license/licensor/src/test/java/org/elasticsearch/license/licensor/LicenseVerificationTests.java b/elasticsearch/license-tools/src/test/java/org/elasticsearch/license/licensor/LicenseVerificationTests.java similarity index 95% rename from elasticsearch/license/licensor/src/test/java/org/elasticsearch/license/licensor/LicenseVerificationTests.java rename to elasticsearch/license-tools/src/test/java/org/elasticsearch/license/licensor/LicenseVerificationTests.java index 37cc3f024a4..fc0b459a80a 100644 --- a/elasticsearch/license/licensor/src/test/java/org/elasticsearch/license/licensor/LicenseVerificationTests.java +++ b/elasticsearch/license-tools/src/test/java/org/elasticsearch/license/licensor/LicenseVerificationTests.java @@ -6,9 +6,9 @@ package org.elasticsearch.license.licensor; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.license.core.DateUtils; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.core.LicenseVerifier; +import org.elasticsearch.license.DateUtils; +import org.elasticsearch.license.License; +import org.elasticsearch.license.LicenseVerifier; import org.elasticsearch.test.ESTestCase; import org.junit.After; import org.junit.Before; diff --git a/elasticsearch/license/licensor/src/test/java/org/elasticsearch/license/licensor/TestUtils.java b/elasticsearch/license-tools/src/test/java/org/elasticsearch/license/licensor/TestUtils.java similarity index 99% rename from elasticsearch/license/licensor/src/test/java/org/elasticsearch/license/licensor/TestUtils.java rename to elasticsearch/license-tools/src/test/java/org/elasticsearch/license/licensor/TestUtils.java index 3dc45d2d0ad..14e1c95b415 100644 --- a/elasticsearch/license/licensor/src/test/java/org/elasticsearch/license/licensor/TestUtils.java +++ b/elasticsearch/license-tools/src/test/java/org/elasticsearch/license/licensor/TestUtils.java @@ -13,8 +13,8 @@ import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.license.core.DateUtils; -import org.elasticsearch.license.core.License; +import org.elasticsearch.license.DateUtils; +import org.elasticsearch.license.License; import org.elasticsearch.test.ESTestCase; import org.hamcrest.MatcherAssert; import org.joda.time.format.DateTimeFormatter; diff --git a/elasticsearch/license/licensor/src/test/java/org/elasticsearch/license/licensor/tools/KeyPairGenerationToolTests.java b/elasticsearch/license-tools/src/test/java/org/elasticsearch/license/licensor/tools/KeyPairGenerationToolTests.java similarity index 100% rename from elasticsearch/license/licensor/src/test/java/org/elasticsearch/license/licensor/tools/KeyPairGenerationToolTests.java rename to elasticsearch/license-tools/src/test/java/org/elasticsearch/license/licensor/tools/KeyPairGenerationToolTests.java diff --git a/elasticsearch/license/licensor/src/test/java/org/elasticsearch/license/licensor/tools/LicenseGenerationToolTests.java b/elasticsearch/license-tools/src/test/java/org/elasticsearch/license/licensor/tools/LicenseGenerationToolTests.java similarity index 98% rename from elasticsearch/license/licensor/src/test/java/org/elasticsearch/license/licensor/tools/LicenseGenerationToolTests.java rename to elasticsearch/license-tools/src/test/java/org/elasticsearch/license/licensor/tools/LicenseGenerationToolTests.java index e75e1509887..b763d5c115a 100644 --- a/elasticsearch/license/licensor/src/test/java/org/elasticsearch/license/licensor/tools/LicenseGenerationToolTests.java +++ b/elasticsearch/license-tools/src/test/java/org/elasticsearch/license/licensor/tools/LicenseGenerationToolTests.java @@ -13,7 +13,7 @@ import org.elasticsearch.cli.Command; import org.elasticsearch.cli.CommandTestCase; import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.cli.UserException; -import org.elasticsearch.license.core.License; +import org.elasticsearch.license.License; import org.elasticsearch.license.licensor.TestUtils; import org.junit.Before; diff --git a/elasticsearch/license/licensor/src/test/java/org/elasticsearch/license/licensor/tools/LicenseVerificationToolTests.java b/elasticsearch/license-tools/src/test/java/org/elasticsearch/license/licensor/tools/LicenseVerificationToolTests.java similarity index 98% rename from elasticsearch/license/licensor/src/test/java/org/elasticsearch/license/licensor/tools/LicenseVerificationToolTests.java rename to elasticsearch/license-tools/src/test/java/org/elasticsearch/license/licensor/tools/LicenseVerificationToolTests.java index f35dfa84de1..66e2d6eef64 100644 --- a/elasticsearch/license/licensor/src/test/java/org/elasticsearch/license/licensor/tools/LicenseVerificationToolTests.java +++ b/elasticsearch/license-tools/src/test/java/org/elasticsearch/license/licensor/tools/LicenseVerificationToolTests.java @@ -14,7 +14,7 @@ import org.elasticsearch.cli.CommandTestCase; import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.cli.UserException; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.license.core.License; +import org.elasticsearch.license.License; import org.elasticsearch.license.licensor.TestUtils; import org.junit.Before; diff --git a/elasticsearch/license/base/src/test/resources/log4j.properties b/elasticsearch/license-tools/src/test/resources/log4j.properties similarity index 100% rename from elasticsearch/license/base/src/test/resources/log4j.properties rename to elasticsearch/license-tools/src/test/resources/log4j.properties diff --git a/elasticsearch/license/base/src/test/resources/private.key b/elasticsearch/license-tools/src/test/resources/private.key similarity index 100% rename from elasticsearch/license/base/src/test/resources/private.key rename to elasticsearch/license-tools/src/test/resources/private.key diff --git a/elasticsearch/license/base/src/test/resources/public.key b/elasticsearch/license-tools/src/test/resources/public.key similarity index 100% rename from elasticsearch/license/base/src/test/resources/public.key rename to elasticsearch/license-tools/src/test/resources/public.key diff --git a/elasticsearch/license/README.md b/elasticsearch/license/README.md deleted file mode 100644 index 37aecd4c25f..00000000000 --- a/elasticsearch/license/README.md +++ /dev/null @@ -1,36 +0,0 @@ -elasticsearch-license -===================== - -Elasticsearch Licensing core, tools and plugin - -## Core - -Contains core data structures, utilities used by **Licensor** and **Plugin**. - -See `core/` and `core-shaded/` - -## Licensor - -Contains a collection of tools to generate key-pairs, licenses and validate licenses. - -See `licensor/` - -see [wiki] (https://github.com/elasticsearch/elasticsearch-license/wiki) for documentation on -[Licensing Tools Usage & Reference] (https://github.com/elasticsearch/elasticsearch-license/wiki/License-Tools-Usage-&-Reference) - -## Plugin - -**NOTE**: The license plugin has to be packaged with the right public key when being deployed to public repositories in maven -or uploaded to s3. Use `-Dkeys.path=` with maven command to package the plugin with a specified key. - -See `plugin/` - -see [Getting Started] (https://github.com/elasticsearch/elasticsearch-license/blob/master/docs/getting-started.asciidoc) to install license plugin. - -see [Licensing REST APIs] (https://github.com/elasticsearch/elasticsearch-license/blob/master/docs/license.asciidoc) -to use the license plugin from an elasticsearch deployment. - -see [wiki] (https://github.com/elasticsearch/elasticsearch-license/wiki) for documentation on - - [License Plugin Consumer Interface] (https://github.com/elasticsearch/elasticsearch-license/wiki/License---Consumer-Interface) - - [License Plugin Release Process] (https://github.com/elasticsearch/elasticsearch-license/wiki/Plugin-Release-Process) - - [License Plugin Design] (https://github.com/elasticsearch/elasticsearch-license/wiki/License-Plugin--Design) diff --git a/elasticsearch/license/base/build.gradle b/elasticsearch/license/base/build.gradle deleted file mode 100644 index c76fb7c7579..00000000000 --- a/elasticsearch/license/base/build.gradle +++ /dev/null @@ -1,20 +0,0 @@ -apply plugin: 'elasticsearch.build' - -dependencies { - compile "org.elasticsearch:elasticsearch:${version}" - testCompile "org.elasticsearch.test:framework:${version}" -} - -compactProfile = 'full' - -dependencyLicenses.enabled = false - -jar { - baseName = 'license-core' -} - -modifyPom { - project { - artifactId 'license-core' - } -} diff --git a/elasticsearch/license/build.gradle b/elasticsearch/license/build.gradle deleted file mode 100644 index b4e221e7884..00000000000 --- a/elasticsearch/license/build.gradle +++ /dev/null @@ -1,7 +0,0 @@ -subprojects { - project.afterEvaluate { - project.forbiddenPatterns { - exclude '**/*.key' - } - } -} diff --git a/elasticsearch/license/licensor/src/test/resources/log4j.properties b/elasticsearch/license/licensor/src/test/resources/log4j.properties deleted file mode 100644 index 76defc8660c..00000000000 --- a/elasticsearch/license/licensor/src/test/resources/log4j.properties +++ /dev/null @@ -1,11 +0,0 @@ -es.logger.level=INFO -log4j.rootLogger=${es.logger.level}, out - -log4j.logger.org.apache.http=INFO, out -log4j.additivity.org.apache.http=false - -log4j.logger.org.elasticsearch.license=TRACE - -log4j.appender.out=org.apache.log4j.ConsoleAppender -log4j.appender.out.layout=org.apache.log4j.PatternLayout -log4j.appender.out.layout.conversionPattern=[%d{ISO8601}][%-5p][%-25c] %m%n diff --git a/elasticsearch/license/licensor/src/test/resources/private.key b/elasticsearch/license/licensor/src/test/resources/private.key deleted file mode 100644 index 1f545803d87..00000000000 Binary files a/elasticsearch/license/licensor/src/test/resources/private.key and /dev/null differ diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/build.gradle b/elasticsearch/qa/messy-test-xpack-with-mustache/build.gradle deleted file mode 100644 index f2a8648e82e..00000000000 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/build.gradle +++ /dev/null @@ -1,11 +0,0 @@ - -/* - * Messy tests that depend on mustache directly. Fix these! - */ - -apply plugin: 'elasticsearch.messy-test' - -dependencies { - testCompile project(path: ':x-plugins:elasticsearch:x-pack', configuration: 'testArtifacts') - testCompile project(path: ':modules:lang-mustache', configuration: 'runtime') -} diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/SearchInputIT.java b/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/SearchInputIT.java deleted file mode 100644 index dcb2e95263e..00000000000 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/SearchInputIT.java +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.messy.tests; - -import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequest; -import org.elasticsearch.action.search.SearchRequest; -import org.elasticsearch.action.search.SearchType; -import org.elasticsearch.common.bytes.BytesArray; -import org.elasticsearch.common.io.Streams; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.common.xcontent.ToXContent; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.common.xcontent.json.JsonXContent; -import org.elasticsearch.common.xcontent.support.XContentMapValues; -import org.elasticsearch.indices.query.IndicesQueriesRegistry; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.plugins.ScriptPlugin; -import org.elasticsearch.script.ScriptContext; -import org.elasticsearch.script.ScriptService; -import org.elasticsearch.script.mustache.MustachePlugin; -import org.elasticsearch.search.aggregations.AggregatorParsers; -import org.elasticsearch.search.builder.SearchSourceBuilder; -import org.elasticsearch.search.suggest.Suggesters; -import org.elasticsearch.test.ESIntegTestCase; -import org.elasticsearch.test.ESIntegTestCase.ClusterScope; -import org.elasticsearch.xpack.common.text.TextTemplate; -import org.elasticsearch.xpack.watcher.actions.ActionWrapper; -import org.elasticsearch.xpack.watcher.actions.ExecutableActions; -import org.elasticsearch.xpack.watcher.condition.always.ExecutableAlwaysCondition; -import org.elasticsearch.xpack.watcher.execution.TriggeredExecutionContext; -import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext; -import org.elasticsearch.xpack.watcher.input.Input; -import org.elasticsearch.xpack.watcher.input.search.ExecutableSearchInput; -import org.elasticsearch.xpack.watcher.input.search.SearchInput; -import org.elasticsearch.xpack.watcher.input.search.SearchInputFactory; -import org.elasticsearch.xpack.watcher.input.simple.ExecutableSimpleInput; -import org.elasticsearch.xpack.watcher.input.simple.SimpleInput; -import org.elasticsearch.xpack.watcher.support.WatcherScript; -import org.elasticsearch.xpack.watcher.support.init.proxy.WatcherClientProxy; -import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateRequest; -import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateService; -import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource; -import org.elasticsearch.xpack.watcher.trigger.schedule.IntervalSchedule; -import org.elasticsearch.xpack.watcher.trigger.schedule.ScheduleTrigger; -import org.elasticsearch.xpack.watcher.trigger.schedule.ScheduleTriggerEvent; -import org.elasticsearch.xpack.watcher.watch.Payload; -import org.elasticsearch.xpack.watcher.watch.Watch; -import org.elasticsearch.xpack.watcher.watch.WatchStatus; -import org.joda.time.DateTime; -import org.joda.time.chrono.ISOChronology; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import static java.util.Collections.emptyMap; -import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds; -import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; -import static org.elasticsearch.index.query.QueryBuilders.boolQuery; -import static org.elasticsearch.index.query.QueryBuilders.matchQuery; -import static org.elasticsearch.index.query.QueryBuilders.rangeQuery; -import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource; -import static org.elasticsearch.test.ESIntegTestCase.Scope.SUITE; -import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.getRandomSupportedSearchType; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.joda.time.DateTimeZone.UTC; - -/** - */ -@ClusterScope(scope = SUITE, numClientNodes = 0, transportClientRatio = 0, randomDynamicTemplates = false, supportsDedicatedMasters = false, - numDataNodes = 1) -public class SearchInputIT extends ESIntegTestCase { - - @Override - protected Collection> nodePlugins() { - Collection> types = new ArrayList<>(); - types.addAll(super.nodePlugins()); - types.add(MustachePlugin.class); - types.add(CustomScriptContextPlugin.class); - return types; - } - - private static final String TEMPLATE_QUERY = "{\"query\":{\"bool\":{\"must\":{\"match\":{\"event_type\":{\"query\":\"a\"," + - "\"type\":\"boolean\"}}},\"filter\":{\"range\":{\"_timestamp\":" + - "{\"from\":\"{{ctx.trigger.scheduled_time}}||-{{seconds_param}}\",\"to\":\"{{ctx.trigger.scheduled_time}}\"," + - "\"include_lower\":true,\"include_upper\":true}}}}}}"; - - @Override - public Settings nodeSettings(int nodeOrdinal) { - final Path tempDir = createTempDir(); - final Path configPath = tempDir.resolve("config"); - final Path scriptPath = configPath.resolve("scripts"); - try { - Files.createDirectories(scriptPath); - } catch (IOException e) { - throw new RuntimeException("failed to create config dir"); - - } - try (InputStream stream = SearchInputIT.class.getResourceAsStream("/org/elasticsearch/xpack/watcher/input/search/config/scripts" + - "/test_disk_template.mustache"); - OutputStream out = Files.newOutputStream(scriptPath.resolve("test_disk_template.mustache"))) { - Streams.copy(stream, out); - } catch (IOException e) { - throw new RuntimeException("failed to copy mustache template"); - } - - - //Set path so ScriptService will pick up the test scripts - return Settings.builder().put(super.nodeSettings(nodeOrdinal)) - .put("path.conf", configPath).build(); - } - - @Override - protected Settings transportClientSettings() { - return Settings.builder() - .put(super.transportClientSettings()) - .build(); - } - - public void testExecute() throws Exception { - SearchSourceBuilder searchSourceBuilder = searchSource().query( - boolQuery().must(matchQuery("event_type", "a")).must(rangeQuery("_timestamp") - .from("{{ctx.trigger.scheduled_time}}||-30s").to("{{ctx.trigger.triggered_time}}"))); - SearchRequest searchRequest = client() - .prepareSearch() - .setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE) - .request() - .source(searchSourceBuilder); - - WatcherSearchTemplateRequest request = new WatcherSearchTemplateRequest(searchRequest); - ExecutableSearchInput searchInput = new ExecutableSearchInput(new SearchInput(request, null, null, null), logger, - WatcherClientProxy.of(client()), watcherSearchTemplateService(), null); - WatchExecutionContext ctx = new TriggeredExecutionContext( - new Watch("test-watch", - new ScheduleTrigger(new IntervalSchedule(new IntervalSchedule.Interval(1, IntervalSchedule.Interval.Unit.MINUTES))), - new ExecutableSimpleInput(new SimpleInput(new Payload.Simple()), logger), - new ExecutableAlwaysCondition(logger), - null, - null, - new ExecutableActions(new ArrayList()), - null, - new WatchStatus(new DateTime(0, UTC), emptyMap())), - new DateTime(0, UTC), - new ScheduleTriggerEvent("test-watch", new DateTime(0, UTC), new DateTime(0, UTC)), - timeValueSeconds(5)); - SearchInput.Result result = searchInput.execute(ctx, new Payload.Simple()); - - assertThat(XContentMapValues.extractValue("hits.total", result.payload().data()), equalTo(0)); - assertNotNull(result.executedRequest()); - assertThat(result.status(), is(Input.Result.Status.SUCCESS)); - assertEquals(result.executedRequest().searchType(), request.getRequest().searchType()); - assertArrayEquals(result.executedRequest().indices(), request.getRequest().indices()); - assertEquals(result.executedRequest().indicesOptions(), request.getRequest().indicesOptions()); - - XContentSource source = toXContentSource(result); - assertThat(source.getValue("query.bool.must.1.range._timestamp.from"), equalTo("1970-01-01T00:00:00.000Z||-30s")); - assertThat(source.getValue("query.bool.must.1.range._timestamp.to"), equalTo("1970-01-01T00:00:00.000Z")); - } - - public void testSearchInlineTemplate() throws Exception { - WatchExecutionContext ctx = createContext(); - - Map triggerParams = new HashMap(); - triggerParams.put("triggered_time", new DateTime(1970, 01, 01, 00, 01, 00, 000, ISOChronology.getInstanceUTC())); - triggerParams.put("scheduled_time", new DateTime(1970, 01, 01, 00, 01, 00, 000, ISOChronology.getInstanceUTC())); - Map ctxParams = new HashMap(); - ctxParams.put("id", ctx.id().value()); - ctxParams.put("metadata", null); - ctxParams.put("vars", new HashMap()); - ctxParams.put("watch_id", "test-watch"); - ctxParams.put("trigger", triggerParams); - ctxParams.put("payload", new Payload.Simple().data()); - ctxParams.put("execution_time", new DateTime(1970, 01, 01, 00, 01, 00, 000, ISOChronology.getInstanceUTC())); - Map expectedParams = new HashMap(); - expectedParams.put("seconds_param", "30s"); - expectedParams.put("ctx", ctxParams); - Map params = new HashMap<>(); - params.put("seconds_param", "30s"); - - WatcherScript template = WatcherScript.inline(TEMPLATE_QUERY).lang("mustache").params(params).build(); - - SearchRequest request = client().prepareSearch() - .setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE) - .setIndices("test-search-index").request(); - - SearchInput.Result executedResult = executeSearchInput(request, template, ctx); - - assertNotNull(executedResult.executedRequest()); - assertThat(executedResult.status(), is(Input.Result.Status.SUCCESS)); - if (getNumShards("test-search-index").numPrimaries > 1) { - assertEquals(executedResult.executedRequest().searchType(), request.searchType()); - } - assertArrayEquals(executedResult.executedRequest().indices(), request.indices()); - assertEquals(executedResult.executedRequest().indicesOptions(), request.indicesOptions()); - - XContentSource source = toXContentSource(executedResult); - assertThat(source.getValue("query.bool.filter.0.range._timestamp.from"), equalTo("1970-01-01T00:01:00.000Z||-30s")); - assertThat(source.getValue("query.bool.filter.0.range._timestamp.to"), equalTo("1970-01-01T00:01:00.000Z")); - } - - public void testSearchIndexedTemplate() throws Exception { - WatchExecutionContext ctx = createContext(); - - PutStoredScriptRequest indexedScriptRequest = client().admin().cluster().preparePutStoredScript() - .setId("test-template") - .setScriptLang("mustache") - .setSource(new BytesArray(TEMPLATE_QUERY)) - .request(); - assertThat(client().admin().cluster().putStoredScript(indexedScriptRequest).actionGet().isAcknowledged(), is(true)); - - Map params = new HashMap<>(); - params.put("seconds_param", "30s"); - - WatcherScript template = WatcherScript.indexed("test-template").lang("mustache").params(params).build(); - - jsonBuilder().value(TextTemplate.indexed("test-template").params(params).build()).bytes(); - SearchRequest request = client().prepareSearch().setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE) - .setIndices("test-search-index").request(); - - SearchInput.Result executedResult = executeSearchInput(request, template, ctx); - - assertNotNull(executedResult.executedRequest()); - assertThat(executedResult.status(), is(Input.Result.Status.SUCCESS)); - if (getNumShards("test-search-index").numPrimaries > 1) { - assertEquals(executedResult.executedRequest().searchType(), request.searchType()); - } - assertArrayEquals(executedResult.executedRequest().indices(), request.indices()); - assertEquals(executedResult.executedRequest().indicesOptions(), request.indicesOptions()); - - XContentSource source = toXContentSource(executedResult); - assertThat(source.getValue("query.bool.filter.0.range._timestamp.from"), equalTo("1970-01-01T00:01:00.000Z||-30s")); - assertThat(source.getValue("query.bool.filter.0.range._timestamp.to"), equalTo("1970-01-01T00:01:00.000Z")); - - } - - public void testSearchOnDiskTemplate() throws Exception { - WatchExecutionContext ctx = createContext(); - - Map params = new HashMap<>(); - params.put("seconds_param", "30s"); - - WatcherScript template = WatcherScript.file("test_disk_template").lang("mustache").params(params).build(); - SearchRequest request = client().prepareSearch().setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE) - .setIndices("test-search-index").request(); - - SearchInput.Result executedResult = executeSearchInput(request, template, ctx); - - assertNotNull(executedResult.executedRequest()); - assertThat(executedResult.status(), is(Input.Result.Status.SUCCESS)); - assertArrayEquals(executedResult.executedRequest().indices(), request.indices()); - assertEquals(executedResult.executedRequest().indicesOptions(), request.indicesOptions()); - } - - public void testDifferentSearchType() throws Exception { - SearchSourceBuilder searchSourceBuilder = searchSource().query( - boolQuery().must(matchQuery("event_type", "a")).must(rangeQuery("_timestamp") - .from("{{ctx.trigger.scheduled_time}}||-30s").to("{{ctx.trigger.triggered_time}}")) - ); - SearchType searchType = getRandomSupportedSearchType(); - - SearchRequest searchRequest = client() - .prepareSearch() - .setSearchType(searchType) - .request() - .source(searchSourceBuilder); - - WatcherSearchTemplateRequest request = new WatcherSearchTemplateRequest(searchRequest); - - ExecutableSearchInput searchInput = new ExecutableSearchInput(new SearchInput(request, null, null, null), logger, - WatcherClientProxy.of(client()), watcherSearchTemplateService(), null); - WatchExecutionContext ctx = new TriggeredExecutionContext( - new Watch("test-watch", - new ScheduleTrigger(new IntervalSchedule(new IntervalSchedule.Interval(1, IntervalSchedule.Interval.Unit.MINUTES))), - new ExecutableSimpleInput(new SimpleInput(new Payload.Simple()), logger), - new ExecutableAlwaysCondition(logger), - null, - null, - new ExecutableActions(new ArrayList()), - null, - new WatchStatus(new DateTime(0, UTC), emptyMap())), - new DateTime(0, UTC), - new ScheduleTriggerEvent("test-watch", new DateTime(0, UTC), new DateTime(0, UTC)), - timeValueSeconds(5)); - SearchInput.Result result = searchInput.execute(ctx, new Payload.Simple()); - - assertThat(XContentMapValues.extractValue("hits.total", result.payload().data()), equalTo(0)); - assertNotNull(result.executedRequest()); - assertThat(result.status(), is(Input.Result.Status.SUCCESS)); - assertEquals(result.executedRequest().searchType(), searchType); - assertArrayEquals(result.executedRequest().indices(), searchRequest.indices()); - assertEquals(result.executedRequest().indicesOptions(), searchRequest.indicesOptions()); - - XContentSource source = toXContentSource(result); - assertThat(source.getValue("query.bool.must.1.range._timestamp.from"), equalTo("1970-01-01T00:00:00.000Z||-30s")); - assertThat(source.getValue("query.bool.must.1.range._timestamp.to"), equalTo("1970-01-01T00:00:00.000Z")); - } - - public void testParserValid() throws Exception { - SearchRequest searchRequest = client().prepareSearch() - .setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE) - .request() - .source(searchSource() - .query(boolQuery().must(matchQuery("event_type", "a")).must(rangeQuery("_timestamp") - .from("{{ctx.trigger.scheduled_time}}||-30s").to("{{ctx.trigger.triggered_time}}")))); - - TimeValue timeout = randomBoolean() ? TimeValue.timeValueSeconds(randomInt(10)) : null; - XContentBuilder builder = jsonBuilder().value( - new SearchInput(new WatcherSearchTemplateRequest(searchRequest), null, timeout, null)); - XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes()); - parser.nextToken(); - - IndicesQueriesRegistry indicesQueryRegistry = internalCluster().getInstance(IndicesQueriesRegistry.class); - SearchInputFactory factory = new SearchInputFactory(Settings.EMPTY, WatcherClientProxy.of(client()), indicesQueryRegistry, - null, null, scriptService()); - - SearchInput searchInput = factory.parseInput("_id", parser); - assertEquals(SearchInput.TYPE, searchInput.type()); - assertThat(searchInput.getTimeout(), equalTo(timeout)); - } - - private WatchExecutionContext createContext() { - return new TriggeredExecutionContext( - new Watch("test-watch", - new ScheduleTrigger(new IntervalSchedule(new IntervalSchedule.Interval(1, IntervalSchedule.Interval.Unit.MINUTES))), - new ExecutableSimpleInput(new SimpleInput(new Payload.Simple()), logger), - new ExecutableAlwaysCondition(logger), - null, - null, - new ExecutableActions(new ArrayList()), - null, - new WatchStatus(new DateTime(50000, UTC), emptyMap())), - new DateTime(60000, UTC), - new ScheduleTriggerEvent("test-watch", new DateTime(60000, UTC), new DateTime(60000, UTC)), - timeValueSeconds(5)); - } - - private SearchInput.Result executeSearchInput(SearchRequest request, WatcherScript template, - WatchExecutionContext ctx) throws IOException { - createIndex("test-search-index"); - ensureGreen("test-search-index"); - SearchInput.Builder siBuilder = SearchInput.builder(new WatcherSearchTemplateRequest(request, template)); - - SearchInput si = siBuilder.build(); - - ExecutableSearchInput searchInput = new ExecutableSearchInput(si, logger, WatcherClientProxy.of(client()), - watcherSearchTemplateService(), null); - return searchInput.execute(ctx, new Payload.Simple()); - } - - protected WatcherSearchTemplateService watcherSearchTemplateService() { - String master = internalCluster().getMasterName(); - return new WatcherSearchTemplateService(internalCluster().clusterService(master).getSettings(), - internalCluster().getInstance(ScriptService.class, master), - internalCluster().getInstance(IndicesQueriesRegistry.class, master), - internalCluster().getInstance(AggregatorParsers.class, master), - internalCluster().getInstance(Suggesters.class, master) - ); - } - - protected ScriptService scriptService() { - return internalCluster().getInstance(ScriptService.class); - } - - private XContentSource toXContentSource(SearchInput.Result result) throws IOException { - try (XContentBuilder builder = jsonBuilder()) { - result.executedRequest().source().toXContent(builder, ToXContent.EMPTY_PARAMS); - return new XContentSource(builder); - } - } - - /** - * Custom plugin that registers XPack script context. - */ - public static class CustomScriptContextPlugin extends Plugin implements ScriptPlugin { - - @Override - public ScriptContext.Plugin getCustomScriptContexts() { - return WatcherScript.CTX_PLUGIN; - } - } -} diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/package-info.java b/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/package-info.java deleted file mode 100644 index c6429e0f4df..00000000000 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -/** - * This package contains tests that use mustache to test what looks - * to be unrelated functionality, or functionality that should be - * tested with a mock instead. Instead of doing an epic battle - * with these tests, they are temporarily moved here to the mustache - * module's tests, but that is likely not where they belong. Please - * help by cleaning them up and we can remove this package! - * - *
    - *
  • If the test is testing templating integration with another core subsystem, - * fix it to use a mock instead, so it can be in the core tests again
  • - *
  • If the test is just being lazy, and does not really need templating to test - * something, clean it up!
  • - *
- */ - -package org.elasticsearch.messy.tests; diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/resources/org/elasticsearch/xpack/watcher/input/search/config/scripts/test_disk_template.mustache b/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/resources/org/elasticsearch/xpack/watcher/input/search/config/scripts/test_disk_template.mustache deleted file mode 100644 index cdc73453c0a..00000000000 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/resources/org/elasticsearch/xpack/watcher/input/search/config/scripts/test_disk_template.mustache +++ /dev/null @@ -1,26 +0,0 @@ -{ - "query": { - "bool": { - "must" : [ - { - "match": { - "event_type": { - "query": "a", - "type": "boolean" - } - } - }, - { - "range": { - "_timestamp": { - "from": "{{ctx.trigger.scheduled_time}}||-{{seconds_param}}", - "to": "{{ctx.trigger.scheduled_time}}", - "include_lower": true, - "include_upper": true - } - } - } - ] - } - } -} \ No newline at end of file diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/resources/org/elasticsearch/xpack/watcher/transform/search/config/scripts/test_disk_template.mustache b/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/resources/org/elasticsearch/xpack/watcher/transform/search/config/scripts/test_disk_template.mustache deleted file mode 100644 index cdc73453c0a..00000000000 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/resources/org/elasticsearch/xpack/watcher/transform/search/config/scripts/test_disk_template.mustache +++ /dev/null @@ -1,26 +0,0 @@ -{ - "query": { - "bool": { - "must" : [ - { - "match": { - "event_type": { - "query": "a", - "type": "boolean" - } - } - }, - { - "range": { - "_timestamp": { - "from": "{{ctx.trigger.scheduled_time}}||-{{seconds_param}}", - "to": "{{ctx.trigger.scheduled_time}}", - "include_lower": true, - "include_upper": true - } - } - } - ] - } - } -} \ No newline at end of file diff --git a/elasticsearch/qa/reindex-tests-with-security/build.gradle b/elasticsearch/qa/reindex-tests-with-security/build.gradle index 3beea6c57f7..4f7aba7b6db 100644 --- a/elasticsearch/qa/reindex-tests-with-security/build.gradle +++ b/elasticsearch/qa/reindex-tests-with-security/build.gradle @@ -8,6 +8,8 @@ integTest { cluster { setting 'script.inline', 'true' plugin ':x-plugins:elasticsearch:x-pack' + // Whitelist reindexing from the local node so we can test it. + setting 'reindex.remote.whitelist', 'myself' extraConfigFile 'x-pack/roles.yml', 'roles.yml' [ test_admin: 'superuser', diff --git a/elasticsearch/qa/reindex-tests-with-security/roles.yml b/elasticsearch/qa/reindex-tests-with-security/roles.yml index 483afd67760..41bef8dc3a7 100644 --- a/elasticsearch/qa/reindex-tests-with-security/roles.yml +++ b/elasticsearch/qa/reindex-tests-with-security/roles.yml @@ -10,6 +10,8 @@ admin: # Search and write on both source and destination indices. It should work if you could just search on the source and # write to the destination but that isn't how security works. minimal: + cluster: + - cluster:monitor/main indices: - names: source privileges: @@ -26,18 +28,24 @@ minimal: # Read only operations on indices readonly: + cluster: + - cluster:monitor/main indices: - names: '*' privileges: [ read ] # Write operations on destination index, none on source index dest_only: + cluster: + - cluster:monitor/main indices: - names: dest privileges: [ write ] # Search and write on both source and destination indices with document level security filtering out some docs. can_not_see_hidden_docs: + cluster: + - cluster:monitor/main indices: - names: source privileges: @@ -59,6 +67,8 @@ can_not_see_hidden_docs: # Search and write on both source and destination indices with field level security. can_not_see_hidden_fields: + cluster: + - cluster:monitor/main indices: - names: source privileges: diff --git a/elasticsearch/qa/reindex-tests-with-security/src/test/resources/rest-api-spec/test/10_reindex.yaml b/elasticsearch/qa/reindex-tests-with-security/src/test/resources/rest-api-spec/test/10_reindex.yaml index 5cad08a1de2..0c74bc19585 100644 --- a/elasticsearch/qa/reindex-tests-with-security/src/test/resources/rest-api-spec/test/10_reindex.yaml +++ b/elasticsearch/qa/reindex-tests-with-security/src/test/resources/rest-api-spec/test/10_reindex.yaml @@ -147,10 +147,9 @@ indices.refresh: {} - do: - headers: {es-security-runas-user: dest_only_user} + headers: {es-security-runas-user: minimal_user} catch: forbidden reindex: - refresh: true body: source: index: source diff --git a/elasticsearch/qa/reindex-tests-with-security/src/test/resources/rest-api-spec/test/15_reindex_from_remote.yaml b/elasticsearch/qa/reindex-tests-with-security/src/test/resources/rest-api-spec/test/15_reindex_from_remote.yaml new file mode 100644 index 00000000000..9b6f51ed21e --- /dev/null +++ b/elasticsearch/qa/reindex-tests-with-security/src/test/resources/rest-api-spec/test/15_reindex_from_remote.yaml @@ -0,0 +1,418 @@ +--- +"Reindex from remote as superuser works": + - skip: + features: catch_unauthorized + + - do: + index: + index: source + type: foo + id: 1 + body: { "text": "test" } + - do: + indices.refresh: {} + + # Fetch the http host. We use the host of the master because we know there will always be a master. + - do: + cluster.state: {} + - set: { master_node: master } + - do: + nodes.info: + metric: [ http ] + - is_true: nodes.$master.http.publish_address + - set: {nodes.$master.http.publish_address: host} + - do: + reindex: + body: + source: + remote: + host: http://${host} + username: test_admin + password: changeme + index: source + dest: + index: dest + - match: {created: 1} + +--- +"Reindex from remote searching as user with minimal privileges works": + - skip: + features: catch_unauthorized + + - do: + index: + index: source + type: foo + id: 1 + body: { "text": "test" } + - do: + indices.refresh: {} + + # Fetch the http host. We use the host of the master because we know there will always be a master. + - do: + cluster.state: {} + - set: { master_node: master } + - do: + nodes.info: + metric: [ http ] + - is_true: nodes.$master.http.publish_address + - set: {nodes.$master.http.publish_address: host} + - do: + reindex: + refresh: true + body: + source: + remote: + host: http://${host} + username: minimal_user + password: changeme + index: source + dest: + index: dest + - match: {created: 1} + + - do: + search: + index: dest + body: + query: + match: + text: test + - match: { hits.total: 1 } + +--- +"Reindex from remote reading as readonly user works when the indexing user is allowed to index": + - skip: + features: catch_unauthorized + + - do: + index: + index: source + type: foo + id: 1 + body: { "text": "test" } + - do: + indices.refresh: {} + + # Fetch the http host. We use the host of the master because we know there will always be a master. + - do: + cluster.state: {} + - set: { master_node: master } + - do: + nodes.info: + metric: [ http ] + - is_true: nodes.$master.http.publish_address + - set: {nodes.$master.http.publish_address: host} + - do: + reindex: + refresh: true + body: + source: + remote: + host: http://${host} + username: readonly_user + password: changeme + index: source + dest: + index: dest + + - do: + search: + index: dest + body: + query: + match: + text: test + - match: { hits.total: 1 } + +--- +"Reindex from remote as user that can't read from the source is forbidden": + - skip: + features: catch_unauthorized + + - do: + index: + index: source + type: foo + id: 1 + body: { "text": "test" } + - do: + indices.refresh: {} + + # Fetch the http host. We use the host of the master because we know there will always be a master. + - do: + cluster.state: {} + - set: { master_node: master } + - do: + nodes.info: + metric: [ http ] + - is_true: nodes.$master.http.publish_address + - set: {nodes.$master.http.publish_address: host} + - do: + catch: forbidden + reindex: + body: + source: + remote: + host: http://${host} + username: dest_only_user + password: changeme + index: source + dest: + index: dest + +--- +"Using a script to write to an index to which you don't have access is forbidden even if you read as a superuser": + - do: + index: + index: source + type: tweet + id: 1 + body: { "user": "kimchy" } + - do: + index: + index: source + type: tweet + id: 2 + body: { "user": "another" } + - do: + indices.refresh: {} + + # Fetch the http host. We use the host of the master because we know there will always be a master. + - do: + cluster.state: {} + - set: { master_node: master } + - do: + nodes.info: + metric: [ http ] + - is_true: nodes.$master.http.publish_address + - set: {nodes.$master.http.publish_address: host} + - do: + headers: {es-security-runas-user: minimal_user} + catch: forbidden + reindex: + body: + source: + remote: + host: http://${host} + username: test_admin + password: changeme + index: source + dest: + index: dest + script: + inline: if (ctx._source.user == "kimchy") {ctx._index = 'other_dest'} + + - do: + indices.refresh: {} + + # The index to which the user tried the unauthorized write didn't even get created + - do: + catch: missing + search: + index: other_dest + + # Even the authorized index won't have made it because it was in the same batch as the unauthorized one. + # If there had been lots of documents being copied then some might have made it into the authorized index. + - do: + catch: missing + search: + index: dest + +--- +"Reindex from remote misses hidden docs": + - skip: + features: catch_unauthorized + + - do: + index: + index: source + type: foo + id: 1 + body: { "text": "test" } + - do: + index: + index: source + type: foo + id: 2 + body: { "text": "test", "hidden": true } + - do: + indices.refresh: {} + + # Fetch the http host. We use the host of the master because we know there will always be a master. + - do: + cluster.state: {} + - set: { master_node: master } + - do: + nodes.info: + metric: [ http ] + - is_true: nodes.$master.http.publish_address + - set: {nodes.$master.http.publish_address: host} + - do: + reindex: + refresh: true + body: + source: + remote: + host: http://${host} + username: can_not_see_hidden_docs_user + password: changeme + index: source + dest: + index: dest + - match: {created: 1} + + # We copied just one doc, presumably the one without the hidden field + - do: + search: + index: dest + body: + query: + match: + text: test + - match: { hits.total: 1 } + + # We didn't copy the doc with the hidden field + - do: + search: + index: dest + body: + query: + match: + hidden: true + - match: { hits.total: 0 } + +--- +"Reindex misses hidden fields": + - skip: + features: catch_unauthorized + + - do: + index: + index: source + type: foo + id: 1 + body: { "text": "test", "foo": "z", "bar": "z" } + - do: + indices.refresh: {} + + # Fetch the http host. We use the host of the master because we know there will always be a master. + - do: + cluster.state: {} + - set: { master_node: master } + - do: + nodes.info: + metric: [ http ] + - is_true: nodes.$master.http.publish_address + - set: {nodes.$master.http.publish_address: host} + - do: + reindex: + refresh: true + body: + source: + remote: + host: http://${host} + username: can_not_see_hidden_fields_user + password: changeme + index: source + dest: + index: dest + - match: {created: 1} + + - do: + search: + index: dest + body: + query: + match: + foo: z + - match: { hits.total: 1 } + + - do: + search: + index: dest + body: + query: + match: + bar: z + - match: { hits.total: 1 } + + - do: + search: + index: dest + body: + query: + match: + text: test + - match: { hits.total: 0 } + + +--- +"Reindex from remote with bad password is unauthorized": + - skip: + features: catch_unauthorized + + - do: + index: + index: source + type: foo + id: 1 + body: { "text": "test" } + - do: + indices.refresh: {} + + # Fetch the http host. We use the host of the master because we know there will always be a master. + - do: + cluster.state: {} + - set: { master_node: master } + - do: + nodes.info: + metric: [ http ] + - is_true: nodes.$master.http.publish_address + - set: {nodes.$master.http.publish_address: host} + - do: + catch: unauthorized + reindex: + body: + source: + remote: + host: http://${host} + username: test_admin + password: badpass + index: source + dest: + index: dest + +--- +"Reindex from remote with no username or password is unauthorized": + - skip: + features: catch_unauthorized + + - do: + index: + index: source + type: foo + id: 1 + body: { "text": "test" } + - do: + indices.refresh: {} + + # Fetch the http host. We use the host of the master because we know there will always be a master. + - do: + cluster.state: {} + - set: { master_node: master } + - do: + nodes.info: + metric: [ http ] + - is_true: nodes.$master.http.publish_address + - set: {nodes.$master.http.publish_address: host} + - do: + catch: unauthorized + reindex: + body: + source: + remote: + host: http://${host} + index: source + dest: + index: dest diff --git a/elasticsearch/qa/smoke-test-plugins-ssl/build.gradle b/elasticsearch/qa/smoke-test-plugins-ssl/build.gradle index d83db1a8deb..049086e3811 100644 --- a/elasticsearch/qa/smoke-test-plugins-ssl/build.gradle +++ b/elasticsearch/qa/smoke-test-plugins-ssl/build.gradle @@ -154,12 +154,12 @@ project.rootProject.subprojects.findAll { it.path.startsWith(':plugins:') }.each integTest { cluster { setting 'xpack.monitoring.collection.interval', '3s' - setting 'xpack.monitoring.collection.exporters._http.type', 'http' - setting 'xpack.monitoring.collection.exporters._http.enabled', 'false' - setting 'xpack.monitoring.collection.exporters._http.ssl.truststore.path', clientKeyStore.name - setting 'xpack.monitoring.collection.exporters._http.ssl.truststore.password', 'keypass' - setting 'xpack.monitoring.collection.exporters._http.auth.username', 'monitoring_agent' - setting 'xpack.monitoring.collection.exporters._http.auth.password', 'changeme' + setting 'xpack.monitoring.exporters._http.type', 'http' + setting 'xpack.monitoring.exporters._http.enabled', 'false' + setting 'xpack.monitoring.exporters._http.ssl.truststore.path', clientKeyStore.name + setting 'xpack.monitoring.exporters._http.ssl.truststore.password', 'keypass' + setting 'xpack.monitoring.exporters._http.auth.username', 'monitoring_agent' + setting 'xpack.monitoring.exporters._http.auth.password', 'changeme' setting 'xpack.security.transport.ssl.enabled', 'true' setting 'xpack.security.http.ssl.enabled', 'true' diff --git a/elasticsearch/qa/smoke-test-plugins-ssl/src/test/java/org/elasticsearch/smoketest/SmokeTestMonitoringWithSecurityIT.java b/elasticsearch/qa/smoke-test-plugins-ssl/src/test/java/org/elasticsearch/smoketest/SmokeTestMonitoringWithSecurityIT.java index b9e72faf3f3..d141b08ef2b 100644 --- a/elasticsearch/qa/smoke-test-plugins-ssl/src/test/java/org/elasticsearch/smoketest/SmokeTestMonitoringWithSecurityIT.java +++ b/elasticsearch/qa/smoke-test-plugins-ssl/src/test/java/org/elasticsearch/smoketest/SmokeTestMonitoringWithSecurityIT.java @@ -74,8 +74,8 @@ public class SmokeTestMonitoringWithSecurityIT extends ESIntegTestCase { URI uri = new URI("https", null, httpAddress.getHostString(), httpAddress.getPort(), "/", null, null); Settings exporterSettings = Settings.builder() - .put("xpack.monitoring.collection.exporters._http.enabled", true) - .put("xpack.monitoring.collection.exporters._http.host", uri.toString()) + .put("xpack.monitoring.exporters._http.enabled", true) + .put("xpack.monitoring.exporters._http.host", uri.toString()) .build(); assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(exporterSettings)); } @@ -83,8 +83,8 @@ public class SmokeTestMonitoringWithSecurityIT extends ESIntegTestCase { @After public void disableExporter() { Settings exporterSettings = Settings.builder() - .putNull("xpack.monitoring.collection.exporters._http.enabled") - .putNull("xpack.monitoring.collection.exporters._http.host") + .putNull("xpack.monitoring.exporters._http.enabled") + .putNull("xpack.monitoring.exporters._http.host") .build(); assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(exporterSettings)); } diff --git a/elasticsearch/qa/smoke-test-plugins-ssl/src/test/resources/rest-api-spec/test/smoke_test_plugins_ssl/20_settings_filter.yaml b/elasticsearch/qa/smoke-test-plugins-ssl/src/test/resources/rest-api-spec/test/smoke_test_plugins_ssl/20_settings_filter.yaml index a96b8b45786..ad463a39487 100644 --- a/elasticsearch/qa/smoke-test-plugins-ssl/src/test/resources/rest-api-spec/test/smoke_test_plugins_ssl/20_settings_filter.yaml +++ b/elasticsearch/qa/smoke-test-plugins-ssl/src/test/resources/rest-api-spec/test/smoke_test_plugins_ssl/20_settings_filter.yaml @@ -11,9 +11,9 @@ metric: [ settings ] - is_true: nodes - - is_true: nodes.$master.settings.xpack.monitoring.collection.exporters._http.type + - is_true: nodes.$master.settings.xpack.monitoring.exporters._http.type - - is_false: nodes.$master.settings.xpack.monitoring.collection.exporters._http.auth.username - - is_false: nodes.$master.settings.xpack.monitoring.collection.exporters._http.auth.password - - is_false: nodes.$master.settings.xpack.monitoring.collection.exporters._http.ssl.truststore.path - - is_false: nodes.$master.settings.xpack.monitoring.collection.exporters._http.ssl.truststore.password + - is_false: nodes.$master.settings.xpack.monitoring.exporters._http.auth.username + - is_false: nodes.$master.settings.xpack.monitoring.exporters._http.auth.password + - is_false: nodes.$master.settings.xpack.monitoring.exporters._http.ssl.truststore.path + - is_false: nodes.$master.settings.xpack.monitoring.exporters._http.ssl.truststore.password diff --git a/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherTemplateTests.java b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherTemplateIT.java similarity index 99% rename from elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherTemplateTests.java rename to elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherTemplateIT.java index a1bf631233e..5a652984247 100644 --- a/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherTemplateTests.java +++ b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherTemplateIT.java @@ -35,7 +35,7 @@ import java.util.Map; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; -public class WatcherTemplateTests extends ESTestCase { +public class WatcherTemplateIT extends ESTestCase { private TextTemplateEngine engine; diff --git a/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/resources/rest-api-spec/test/watcher_mustache/30_search_input_and_transform.yaml b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/resources/rest-api-spec/test/watcher_mustache/30_search_input_and_transform.yaml new file mode 100644 index 00000000000..a8c7c9308bc --- /dev/null +++ b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/resources/rest-api-spec/test/watcher_mustache/30_search_input_and_transform.yaml @@ -0,0 +1,157 @@ +--- +setup: + - do: + cluster.health: + wait_for_status: yellow + - do: {xpack.watcher.stats:{}} + - do: + index: + index: idx + type: type + id: 1 + body: > + { + "date" : "2015-01-01T00:00:00", + "value" : "val_1" + } + - do: + index: + index: idx + type: type + id: 2 + body: > + { + "date" : "2015-01-02T00:00:00", + "value" : "val_2" + } + - do: + index: + index: idx + type: type + id: 3 + body: > + { + "date" : "2015-01-03T00:00:00", + "value" : "val_3" + } + - do: + index: + index: idx + type: type + id: 4 + body: > + { + "date" : "2015-01-04T00:00:00", + "value" : "val_4" + } + - do: + indices.refresh: + index: idx + +--- +"Test input mustache integration": + - do: + xpack.watcher.execute_watch: + body: > + { + "trigger_data" : { + "scheduled_time" : "2015-01-04T00:00:00" + }, + "watch" : { + "trigger" : { "schedule" : { "interval" : "10s" } }, + "actions" : { + "dummy" : { + "logging" : { + "text" : "executed!" + } + } + }, + "input" : { + "search" : { + "request" : { + "indices" : "idx", + "body" : { + "query" : { + "bool" : { + "filter" : [ + { + "range" : { + "date" : { + "lte" : "{{ctx.trigger.scheduled_time}}", + "gte" : "{{ctx.trigger.scheduled_time}}||-3d" + } + } + } + ] + } + } + } + } + } + } + } + } + - match: { "watch_record.result.input.type": "search" } + - match: { "watch_record.result.input.status": "success" } + - match: { "watch_record.result.input.payload.hits.total": 4 } + # makes sure that the mustache template snippets have been resolved correctly: + - match: { "watch_record.result.input.search.request.body.query.bool.filter.0.range.date.from": "2015-01-04T00:00:00.000Z||-3d" } + - match: { "watch_record.result.input.search.request.body.query.bool.filter.0.range.date.to": "2015-01-04T00:00:00.000Z" } + +--- +"Test transform mustache integration": + - do: + xpack.watcher.execute_watch: + body: > + { + "trigger_data" : { + "scheduled_time" : "2015-01-04T00:00:00" + }, + "watch" : { + "trigger" : { "schedule" : { "interval" : "10s" } }, + "input" : { "simple" : { "value" : "val_3" } }, + "actions" : { + "dummy" : { + "logging" : { + "text" : "executed!" + } + } + }, + "transform" : { + "search" : { + "request" : { + "indices" : "idx", + "body" : { + "query" : { + "bool" : { + "filter" : [ + { + "range" : { + "date" : { + "lte" : "{{ctx.trigger.scheduled_time}}", + "gte" : "{{ctx.trigger.scheduled_time}}||-1d" + } + } + }, + { + "term" : { + "value" : "{{ctx.payload.value}}" + } + } + ] + } + } + } + } + } + } + } + } + - match: { "watch_record.result.transform.type": "search" } + - match: { "watch_record.result.transform.status": "success" } + - match: { "watch_record.result.transform.payload.hits.total": 1 } + - match: { "watch_record.result.transform.payload.hits.hits.0._id": "3" } + # makes sure that the mustache template snippets have been resolved correctly: + - match: { "watch_record.result.transform.search.request.body.query.bool.filter.0.range.date.from": "2015-01-04T00:00:00.000Z||-1d" } + - match: { "watch_record.result.transform.search.request.body.query.bool.filter.0.range.date.to": "2015-01-04T00:00:00.000Z" } + - match: { "watch_record.result.transform.search.request.body.query.bool.filter.1.term.value.value": "val_3" } diff --git a/elasticsearch/x-pack/LICENSE.txt b/elasticsearch/x-pack/LICENSE.txt deleted file mode 100644 index 27603586ce4..00000000000 --- a/elasticsearch/x-pack/LICENSE.txt +++ /dev/null @@ -1,440 +0,0 @@ -SOFTWARE END USER LICENSE AGREEMENT - - READ THIS AGREEMENT CAREFULLY, WHICH CONSTITUTES A LEGALLY BINDING AGREEMENT AND GOVERNS YOUR USE OF -ELASTICSEARCH’S PROPRIETARY SOFTWARE. BY INSTALLING AND/OR USING SUCH SOFTWARE, YOU ARE INDICATING THAT YOU AGREE TO THE -TERMS AND CONDITIONS SET FORTH IN THIS AGREEMENT. IF YOU DO NOT AGREE WITH SUCH TERMS AND CONDITIONS, YOU MAY NOT -INSTALL OR USE ANY OF THE SOFTWARE. - - This END USER LICENSE AGREEMENT (this “Agreement") is entered into by and between the applicable Elasticsearch -entity referenced in Attachment 1 hereto (“Elasticsearch”) and the person or entity (“You”) that has downloaded any of -Elasticsearch’s proprietary software to which this Agreement is attached or in connection with which this Agreement is -presented to You (collectively, the “Software”). This Agreement is effective upon the earlier of the date on the -commencement of any License granted pursuant to Section 1.1. below (as applicable, the “Effective Date”). - -1. SOFTWARE LICENSE AND RESTRICTIONS -1.1 License Grants. - (a) Trial Version License. Subject to the terms and conditions of this Agreement, Elasticsearch agrees to -grant, and does hereby grant to You, for a period of thirty (30) days from the date on which You first install the -Software (the “Trial Term”), a License to the to use the Eligible Features and Functions of the Software that are -applicable to the Trial Version of the Software.   You understand and agree that upon the expiration of a Trial Term, -You will no longer be able to use the Software, unless you either (i) purchase a Subscription, in which case You will -receive a License under Section 1.1(b) below to use the Eligible Features and Functions of the Software that are -applicable to the Subscription that You purchase, (ii) undertake the Registration of Your use of the Software with -Elasticsearch, in which case You will receive a License under Section 1.1(c) below to the Basic Version of the Software -or (iii) obtain from Elasticsearch written consent (e-mail sufficient) to extend the Trial Term, which may be granted by -Elasticsearch in its sole and absolute discretion. - (b) Subscription License. Subject to the terms and conditions of this Agreement and complete payment of any and -all applicable Subscription fees, Elasticsearch agrees to grant, and does hereby grant to You during the Subscription -Term, and for the restricted scope of this Agreement, a License (i) to use the Eligible Features and Functions of the -Software that are applicable to the Subscription level that You have purchased, (ii) for the number of Nodes (as defined -in the Elasticsearch Support Services Policy) and (iii) for the specific project for which you have purchased a -Subscription. The level of Subscription, the number of Nodes and specific project for which you have purchased such -Subscription, are set forth on the applicable ordering document entered into by Elasticsearch and You for the purchase -of the applicable Subscription (“Order Form”). - (c) Basic Version License. Subject to the terms and conditions of this Agreement, and in consideration of the -Registration of Your use the Software, Elasticsearch agrees to grant, and does hereby grant to You, for a period of one -(1) year from the date of Registration (“Basic Term”), a License to use the Eligible Features and Functions of the -Software that are applicable to the Basic Version of the Software. -1.2 Reservation of Rights; Restrictions. As between Elasticsearch and You, Elasticsearch owns all right title and -interest in and to the Software and any derivative works thereof, and except as expressly set forth in Section 1.1 -above, no other license to the Software is granted to You by implication, estoppel or otherwise. You agree not to: (i) -reverse engineer or decompile, decrypt, disassemble or otherwise reduce any Software or any portion thereof to -human-readable form, except and only to the extent any such restriction is prohibited by applicable law, (ii) deploy the -Software on more Nodes (as defined in Elasticsearch’s Support Services Policy) than are permitted under the applicable -License grant in Section 1.1 above (iii) where You have purchased a Subscription, use the Software in connection with -any project other than the project for which you have purchased such Subscription, as identified on the applicable Order -Form, (iv) prepare derivative works from, modify, copy or use the Software in any manner except as expressly permitted -in this Agreement; (v) except as expressly permitted in Section 1.1 above, transfer, sell, rent, lease, distribute, -sublicense, loan or otherwise transfer the Software in whole or in part to any third party; (vi) except as may be -expressly permitted on an applicable Order Form, use the Software for providing time-sharing services, any -software-as-a-service offering (“SaaS”), service bureau services or as part of an application services provider or other -service offering; (vii) circumvent the limitations on use of the Software that are imposed or preserved by any License -Key, (viii) alter or remove any proprietary notices in the Software; or (ix) make available to any third party any -analysis of the results of operation of the Software, including benchmarking results, without the prior written consent -of Elasticsearch. The Software may contain or be provided with open source libraries, components, utilities and other -open source software (collectively, “Open Source Software”), which Open Source Software may have applicable license -terms as identified on a website designated by Elasticsearch or otherwise provided with the Software or Documentation. -Notwithstanding anything to the contrary herein, use of the Open Source Software shall be subject to the license terms -and conditions applicable to such Open Source Software, to the extent required by the applicable licensor (which terms -shall not restrict the license rights granted to You hereunder, but may contain additional rights). -1.3 Audit Rights. You agree that, unless such right is waived in writing by Elasticsearch, Elasticsearch shall have the -right, upon fifteen (15) days’ notice to You, to audit Your use of the Software for compliance with any quantitative -limitations on Your use of the Software that are set forth in the applicable Order Form. You agree to provide -Elasticsearch with the necessary access to the Software to conduct such an audit either (i) remotely, or (ii) if remote -performance is not possible, at Your facilities, during normal business hours and no more than one (1) time in any -twelve (12) month period. In the event any such audit reveals that You have used the Software in excess of the -applicable quantitative limitations, You agree to solely for Your internal business operations, a limited, -non-exclusive, non-transferable, fully paid up,  right and license (without the right to grant or authorize sublicenses) -promptly pay to Elasticsearch an amount equal to the difference between the fees actually paid and the fees that You -should have paid to remain in compliance with such quantitative limitations. This Section 1.3 shall survive for a -period of two (2) years from the termination or expiration of this Agreement. -1.4 Cluster Metadata. You understand and agree that once deployed, and on a daily basis, the Software may provide -metadata to Elasticsearch about Your cluster statistics and associates that metadata with Your IP address. However, no -other information is provided to Elasticsearch by the Software, including any information about the data You process or -store in connection with your use of the Software. Instructions for disabling this feature are contained in the -Software, however leaving this feature active enables Elasticsearch to gather cluster statistics and provide an improved -level of support to You. - -2. TERM AND TERMINATION -2.1 Term. Unless earlier terminated under Section 2.2 below, this Agreement shall commence on the Effective Date, and -shall continue in force for the term of the last to expire applicable license set forth in Section 1.1 above. -2.2 Termination. Either party may, upon written notice to the other party, terminate this Agreement for material breach -by the other party automatically and without any other formality, if such party has failed to cure such material breach -within thirty (30) days of receiving written notice of such material breach from the non-breaching party. -Notwithstanding the foregoing, this Agreement shall automatically terminate in the event that You intentionally breach -the scope of the license granted in Section 1.1 of this Agreement, provided that Elasticsearch reserves the right to -retroactively waive such automatic termination upon written notice to You. -2.3 Post Termination or Expiration. Upon termination or expiration of this Agreement, for any reason, You shall -promptly cease the use of the Software and Documentation and destroy (and certify to Elasticsearch in writing the fact -of such destruction), or return to Elasticsearch, all copies of the Software and Documentation then in Your possession -or under Your control. -2.4 Survival. Sections 2.3, 2.4, 3, 4 and 5 (as any such Sections may be modified by Attachment 1, if applicable) shall -survive any termination or expiration of this Agreement. -3. LIMITED WARRANTY AND DISCLAIMER OF WARRANTIES -3.1 Limited Performance Warranty. Subject to You purchasing a Subscription, Elasticsearch warrants that during the -applicable Subscription Term, the Software will perform in all material respects in accordance with the Documentation. -In the event of a breach of the foregoing warranty, Elasticsearch’s sole obligation, and Your exclusive remedy shall be -for Elasticsearch to (i) correct any failure(s) of the Software to perform in all material respects in accordance with -the Documentation or (ii) if Elasticsearch is unable to provide such a correction within thirty (30) days of receipt of -notice of the applicable non-conformity, promptly refund to Customer any pre-paid, unused fees paid by You to -Elasticsearch for the applicable Subscription. The warranty set forth in this Section 3.1 does not apply if the -applicable Software or any portion thereof: (a) has been altered, except by or on behalf Elasticsearch; (b) has not been -used, installed, operated, repaired, or maintained in accordance with this Agreement and/or the Documentation; (c) has -been subjected to abnormal physical or electrical stress, misuse, negligence, or accident; or (d) is used on equipment, -products, or systems not meeting specifications identified by Elasticsearch in the Documentation. Additionally, the -warranties set forth herein only apply when notice of a warranty claim is provided to Elasticsearch within the -applicable warranty period specified herein and do not apply to any bug, defect or error caused by or attributable to -software or hardware not supplied by Elasticsearch. -3.2 Malicious Code. Elasticsearch represents and warrants that prior to making it available for delivery to You, -Elasticsearch will use standard industry practices including, without limitation, the use of an updated commercial -anti-virus program, to test the Software for Malicious Code and remove any Malicious Code it discovers. In the event of -a breach of the foregoing warranty, Elasticsearch’s sole obligation, and Your exclusive remedy shall be for -Elasticsearch to replace the Software with Software that does not contain any Malicious Code. -3.3 Warranty Disclaimer. TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, THE SOFTWARE IS PROVIDED “AS IS” WITHOUT -WARRANTY OF ANY KIND, AND ELASTICSEARCH AND ITS LICENSORS MAKE NO WARRANTIES WHETHER EXPRESSED, IMPLIED OR STATUTORY -REGARDING OR RELATING TO THE SOFTWARE OR DOCUMENTATION. TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, -ELASTICSEARCH AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NON-INFRINGEMENT WITH RESPECT TO THE SOFTWARE AND DOCUMENTATION, AND WITH RESPECT TO THE USE OF -THE FOREGOING. FURTHER, ELASTICSEARCH DOES NOT WARRANT RESULTS OF USE OR THAT THE SOFTWARE WILL BE ERROR FREE OR THAT -THE USE OF THE SOFTWARE WILL BE UNINTERRUPTED. -4. LIMITATION OF LIABILITY -The provisions of this Section 4 apply if You have not purchased a Subscription. If you have purchased a Subscription, -then the limitations of liability set forth in the applicable Subscription Agreement will apply in lieu of those set -forth in this Section 4. -4.1 Disclaimer of Certain Damages. IN NO EVENT SHALL YOU OR ELASTICSEARCH OR ITS LICENSORS BE LIABLE FOR ANY LOSS OF -PROFITS, LOSS OF USE, BUSINESS INTERRUPTION, LOSS OF DATA, COST OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, -SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH OR ARISING OUT OF THE USE OR INABILITY TO -USE THE SOFTWARE, OR THE PERFORMANCE OF OR FAILURE TO PERFORM THIS AGREEMENT, WHETHER ALLEGED AS A BREACH OF CONTRACT OR -TORTIOUS CONDUCT, INCLUDING NEGLIGENCE, EVEN IF THE RESPONSIBLE PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. THE LIMITATIONS OF LIABILITY SET FORTH IN THIS SECTION 4.1 SHALL NOT APPLY TO A BREACH THROUGH GROSS NEGLIGENCE -OR INTENTIONAL MISCONDUCT BY YOU OF THE SCOPE OF THE LICENSE GRANTED IN SECTION 1.1 OR TO ANY OTHER LIABILITY THAT -CANNOT BE EXCLUDED OR LIMITED UNDER APPLICABLE LAW. -4.2 Damages Cap. IN NO EVENT SHALL ELASTICSEARCH’S OR ITS LICENSORS’ AGGREGATE, CUMULATIVE LIABILITY UNDER THIS -AGREEMENT EXCEED ONE THOUSAND DOLLARS ($1,000). -4.3 YOU AGREE THAT THE FOREGOING LIMITATIONS, EXCLUSIONS AND DISCLAIMERS ARE A REASONABLE ALLOCATION OF THE RISK BETWEEN -THE PARTIES AND WILL APPLY TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, EVEN IF ANY REMEDY FAILS IN ITS ESSENTIAL -PURPOSE. -5. DEFINITIONS -The following terms have the meanings ascribed: -5.1 “License” means a limited, non-exclusive, non-transferable, fully paid up, right and license (without the right to -grant or authorize sublicenses) solely for Your internal business operations to (i) install and use, in object code -format, the applicable Eligible Features and Functions of the Software, (ii) use, and distribute internally a reasonable -number of copies of the Documentation, provided that You must include on such copies all Marks and Notices; (iii) permit -Contractors to use the Software and Documentation as set forth in (i) and (ii) above, provided that such use must be -solely for Your benefit, and You shall be responsible for all acts and omissions of such Contractors in connection with -their use of the Software that are contrary to the terms and conditions of this Agreement.. -5.2 “License Key” means an alphanumeric code that enables the Eligible Features and Functions of the Software. -5.3 “Basic Version” means that version of the Software available for use without the purchase of a Qualifying -Subscription, but which does require Registration. -5.4 “Contractor” means third party contractors performing services on Your behalf. -5.5 “Documentation” means the published end user documentation provided by Elasticsearch with the Software. -5.6 “Eligible Features and Functions” means those features and functions of the Software that are eligible for use with -respect to a particular version of the Software or level of the Subscription. A list of the Eligible Features and -Functions that correspond to each version of the Software and Subscription levels may be found at -https://www.elastic.co/subscriptions. -5.7 “Malicious Code” means any code that is designed to harm, or otherwise disrupt in any unauthorized manner, the -operation of a recipient’s computer programs or computer systems or destroy or damage recipient’s data. For clarity, -Malicious Code shall not include any software bugs or errors handled through Support Services, or any standard features -of functions of the Software and/or any License Key that are intended to enforce the temporal and other limitations on -the scope of the use of the Software to the scope of the license purchased by You. -5.8 “Marks and Notices” means all Elasticsearch trademarks, trade names, logos and notices present on the Documentation -as originally provided by Elasticsearch. -5.9 “Registration” means Elasticsearch’s then-current process under which You may register Your use of the Software with -Elasticsearch by providing certain information to Elasticsearch regarding your use of the Software. -5.10 “Subscription” means the right to receive Support Services and a License to the Software. -5.11 “Subscription Term” means the period of time for which You have purchased a Subscription. -5.12 “Trial Version” means that version of the Software available for use without the purchase of a Qualifying -Subscription and without Registration. -6. MISCELLANEOUS -This Agreement, including Attachment 1 hereto, which is hereby incorporated herein by this reference, completely and -exclusively states the entire agreement of the parties regarding the subject matter herein, and it supersedes, and its -terms govern, all prior proposals, agreements, or other communications between the parties, oral or written, regarding -such subject matter. For the avoidance of doubt, the parties hereby expressly acknowledge and agree that if You issue -any purchase order or similar document in connection with its purchase of a license to the Software, You will do so only -for Your internal, administrative purposes and not with the intent to provide any contractual terms. This Agreement may -not be modified except by a subsequently dated, written amendment that expressly amends this Agreement and which is -signed on behalf of Elasticsearch and You, by duly authorized representatives. If any provision hereof is held -unenforceable, this Agreement will continue without said provision and be interpreted to reflect the original intent of -the parties. - - -ATTACHMENT 1 -ADDITIONAL TERMS AND CONDITIONS - -A. The following additional terms and conditions apply to all Customers with principal offices in the United States -of America: - -(1) Applicable Elasticsearch Entity. The entity providing the license is Elasticsearch, Inc., a Delaware corporation. - -(2) Government Rights. The Software product is "Commercial Computer Software," as that term is defined in 48 C.F.R. -2.101, and as the term is used in 48 C.F.R. Part 12, and is a Commercial Item comprised of "commercial computer -software" and "commercial computer software documentation". If acquired by or on behalf of a civilian agency, the U.S. -Government acquires this commercial computer software and/or commercial computer software documentation subject to the -terms of this Agreement, as specified in 48 C.F.R. 12.212 (Computer Software) and 12.211 (Technical Data) of the Federal -Acquisition Regulation ("FAR") and its successors. If acquired by or on behalf of any agency within the Department of -Defense ("DOD"), the U.S. Government acquires this commercial computer software and/or commercial computer software -documentation subject to the terms of the Elasticsearch Software License Agreement as specified in 48 C.F.R. 227.7202-3 -and 48 C.F.R. 227.7202-4 of the DOD FAR Supplement ("DFARS") and its successors, and consistent with 48 C.F.R. 227.7202. - This U.S. Government Rights clause, consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202 is in lieu of, and -supersedes, any other FAR, DFARS, or other clause or provision that addresses Government rights in computer software, -computer software documentation or technical data related to the Software under this Agreement and in any Subcontract -under which this commercial computer software and commercial computer software documentation is acquired or licensed. - -(3) Export Control. You acknowledge that the goods, software and technology acquired from Elasticsearch are subject -to U.S. export control laws and regulations, including but not limited to the International Traffic In Arms Regulations -(“ITAR”) (22 C.F.R. Parts 120-130 (2010)); the Export Administration Regulations ("EAR") (15 C.F.R. Parts 730-774 -(2010)); the U.S. antiboycott regulations in the EAR and U.S. Department of the Treasury regulations; the economic -sanctions regulations and guidelines of the U.S. Department of the Treasury, Office of Foreign Assets Control, and the -USA Patriot Act (Title III of Pub. L. 107-56, signed into law October 26, 2001), as amended.  You are now and will -remain in the future compliant with all such export control laws and regulations, and will not export, re-export, -otherwise transfer any Elasticsearch goods, software or technology or disclose any Elasticsearch software or technology -to any person contrary to such laws or regulations.  You acknowledge that remote access to the Software may in certain -circumstances be considered a re-export of Software, and accordingly, may not be granted in contravention of U.S. export -control laws and regulations. -(4) Governing Law, Jurisdiction and Venue. -(a) Customers in California. If Customer is located in California (as determined by the Customer address on the -applicable Order Form, or for a trial license under 1.1(a), the location of person who installed the Software), this -Agreement will be governed by the laws of the State of California, without regard to its conflict of laws principles, -and all suits hereunder will be brought solely in Federal Court for the Northern District of California, or if that -court lacks subject matter jurisdiction, in any California State Court located in Santa Clara County. -(b) Customers Outside of California. If Customer is located anywhere other than California (as determined by the -Customer address on the applicable Order Form, or for a trial license under 1.1(a), the location of person who installed -the Software), this Agreement will be governed by the laws of the State of Delaware, without regard to its conflict of -laws principles, and all suits hereunder will be brought solely in Federal Court for the District of Delaware, or if -that court lacks subject matter jurisdiction, in any Delaware State Court located in Wilmington, Delaware. -(c) All Customers. This Agreement shall not be governed by the 1980 UN Convention on Contracts for the International -Sale of Goods. The parties hereby irrevocably waive any and all claims and defenses either might otherwise have in any -action or proceeding in any of the applicable courts set forth in (a) or (b) above, based upon any alleged lack of -personal jurisdiction, improper venue, forum non conveniens, or any similar claim or defense. -(d) Equitable Relief. A breach or threatened breach, by either party of Section 4 may cause irreparable harm for -which the non-breaching party shall be entitled to seek injunctive relief without being required to post a bond. - -B. The following additional terms and conditions apply to all Customers with principal offices in Canada: - -(1) Applicable Elasticsearch Entity. The entity providing the license is Elasticsearch B.C. Ltd., a corporation -incorporated under laws of the Province of British Columbia. - -(2) Export Control. You acknowledge that the goods, software and technology acquired from Elasticsearch are subject -to the restrictions and controls set out in Section A(3) above as well as those imposed by the Export and Import Permits -Act (Canada) and the regulations thereunder and that you will comply with all applicable laws and regulations. Without -limitation, You acknowledge that the Marvel Software, or any portion thereof, will not be exported: (a) to any country -on Canada's Area Control List; (b) to any country subject to UN Security Council embargo or action; or (c) contrary to -Canada's Export Control List Item 5505. You are now and will remain in the future compliant with all such export control -laws and regulations, and will not export, re-export, otherwise transfer any Elasticsearch goods, software or technology -or disclose any Elasticsearch software or technology to any person contrary to such laws or regulations.  You will not -export or re-export the Marvel Software, or any portion thereof, directly or indirectly, in violation of the Canadian -export administration laws and regulations to any country or end user, or to any end user who you know or have reason to -know will utilize them in the design, development or production of nuclear, chemical or biological weapons. You further -acknowledge that the Marvel Software product may include technical data subject to such Canadian export regulations. -Elasticsearch does not represent that the Marvel Software is appropriate or available for use in all countries. -Elasticsearch prohibits accessing materials from countries or states where contents are illegal. You are using the -Marvel Software on your own initiative and you are responsible for compliance with all applicable laws. You hereby agree -to indemnify Elasticsearch and its affiliates from any claims, actions, liability or expenses (including reasonable -lawyers' fees) resulting from Your failure to act in accordance with the acknowledgements, agreements, and -representations in this Section B(2). - (3) Governing Law and Dispute Resolution. This Agreement shall be governed by the Province of Ontario and the -federal laws of Canada applicable therein without regard to conflict of laws provisions. The parties hereby irrevocably -waive any and all claims and defenses either might otherwise have in any such action or proceeding in any of such courts -based upon any alleged lack of personal jurisdiction, improper venue, forum non conveniens or any similar claim or -defense. Any dispute, claim or controversy arising out of or relating to this Agreement or the existence, breach, -termination, enforcement, interpretation or validity thereof, including the determination of the scope or applicability -of this agreement to arbitrate, (each, a “Dispute”), which the parties are unable to resolve after good faith -negotiations, shall be submitted first to the upper management level of the parties. The parties, through their upper -management level representatives shall meet within thirty (30) days of the Dispute being referred to them and if the -parties are unable to resolve such Dispute within thirty (30) days of meeting, the parties agree to seek to resolve the -Dispute through mediation with ADR Chambers in the City of Toronto, Ontario, Canada before pursuing any other -proceedings. The costs of the mediator shall be shared equally by the parties. If the Dispute has not been resolved -within thirty (30) days of the notice to desire to mediate, any party may terminate the mediation and proceed to -arbitration and the matter shall be referred to and finally resolved by arbitration at ADR Chambers pursuant to the -general ADR Chambers Rules for Arbitration in the City of Toronto, Ontario, Canada. The arbitration shall proceed in -accordance with the provisions of the Arbitration Act (Ontario). The arbitral panel shall consist of three (3) -arbitrators, selected as follows: each party shall appoint one (1) arbitrator; and those two (2) arbitrators shall -discuss and select a chairman. If the two (2) party-appointed arbitrators are unable to agree on the chairman, the -chairman shall be selected in accordance with the applicable rules of the arbitration body. Each arbitrator shall be -independent of each of the parties. The arbitrators shall have the authority to grant specific performance and to -allocate between the parties the costs of arbitration (including service fees, arbitrator fees and all other fees -related to the arbitration) in such equitable manner as the arbitrators may determine. The prevailing party in any -arbitration shall be entitled to receive reimbursement of its reasonable expenses incurred in connection therewith. -Judgment upon the award so rendered may be entered in a court having jurisdiction or application may be made to such -court for judicial acceptance of any award and an order of enforcement, as the case may be. Notwithstanding the -foregoing, Elasticsearch shall have the right to institute an action in a court of proper jurisdiction for preliminary -injunctive relief pending a final decision by the arbitrator, provided that a permanent injunction and damages shall -only be awarded by the arbitrator. The language to be used in the arbitral proceedings shall be English. - (4) Language. Any translation of this Agreement is done for local requirements and in the event of a dispute -between the English and any non-English version, the English version of this Agreement shall govern. At the request of -the parties, the official language of this Agreement and all communications and documents relating hereto is the English -language, and the English-language version shall govern all interpretation of the Agreement.  À la demande des parties, -la langue officielle de la présente convention ainsi que toutes communications et tous documents s'y rapportant est la -langue anglaise, et la version anglaise est celle qui régit toute interprétation de la présente convention. -(5) Warranty Disclaimer. For Customers with principal offices in the Province of Québec, the following new sentence -is to be added to the end of Section 3.3: “SOME JURISDICTIONS DO NOT ALLOW LIMITATIONS OR EXCLUSIONS OF CERTAIN TYPES OF -DAMAGES AND/OR WARRANTIES AND CONDITIONS. THE LIMITATIONS, EXCLUSIONS AND DISCLAIMERS SET FORTH IN THIS AGREEMENT SHALL -NOT APPLY IF AND ONLY IF AND TO THE EXTENT THAT THE LAWS OF A COMPETENT JURISDICTION REQUIRE LIABILITIES BEYOND AND -DESPITE THESE LIMITATIONS, EXCLUSIONS AND DISCLAIMERS.” -(6) Limitation of Liability. For Customers with principal offices in the Province of Québec, the following new -sentence is to be added to the end of Section 4.1: “SOME JURISDICTIONS DO NOT ALLOW LIMITATIONS OR EXCLUSIONS OF CERTAIN -TYPES OF DAMAGES AND/OR WARRANTIES AND CONDITIONS.  THE LIMITATIONS, EXCLUSIONS AND DISCLAIMERS SET FORTH IN THIS -AGREEMENT SHALL NOT APPLY IF AND ONLY IF AND TO THE EXTENT THAT THE LAWS OF A COMPETENT JURISDICTION REQUIRE LIABILITIES -BEYOND AND DESPITE THESE LIMITATIONS, EXCLUSIONS AND DISCLAIMERS.” - -C. The following additional terms and conditions apply to all Customers with principal offices outside of the United -States of America and Canada: - -(1) Applicable Elasticsearch Entity. The entity providing the license in Germany is Elasticsearch Gmbh; in France is -Elasticsearch SARL, in the United Kingdom is Elasticsearch Ltd, in Australia is Elasticsearch Pty Ltd., in Japan is -Elasticsearch KK, in Sweden is Elasticsearch AB, in Norway is Elasticsearch AS and in all other countries is -Elasticsearch BV. - -(2) Choice of Law. This Agreement shall be governed by and construed in accordance with the laws of the State of New -York, without reference to or application of choice of law rules or principles. Notwithstanding any choice of law -provision or otherwise, the Uniform Computer Information Transactions Act (UCITA) and the United Nations Convention on -the International Sale of Goods shall not apply. - -(3) Arbitration. Any dispute, claim or controversy arising out of or relating to this Agreement or the existence, -breach, termination, enforcement, interpretation or validity thereof, including the determination of the scope or -applicability of this agreement to arbitrate, (each, a “Dispute”) shall be referred to and finally resolved by -arbitration under the rules and at the location identified below. The arbitral panel shall consist of three (3) -arbitrators, selected as follows: each party shall appoint one (1) arbitrator; and those two (2) arbitrators shall -discuss and select a chairman. If the two party-appointed arbitrators are unable to agree on the chairman, the chairman -shall be selected in accordance with the applicable rules of the arbitration body. Each arbitrator shall be independent -of each of the parties. The arbitrators shall have the authority to grant specific performance and to allocate between -the parties the costs of arbitration (including service fees, arbitrator fees and all other fees related to the -arbitration) in such equitable manner as the arbitrators may determine. The prevailing party in any arbitration shall -be entitled to receive reimbursement of its reasonable expenses incurred in connection therewith. Judgment upon the -award so rendered may be entered in a court having jurisdiction or application may be made to such court for judicial -acceptance of any award and an order of enforcement, as the case may be. Notwithstanding the foregoing, Elasticsearch -shall have the right to institute an action in a court of proper jurisdiction for preliminary injunctive relief pending -a final decision by the arbitrator, provided that a permanent injunction and damages shall only be awarded by the -arbitrator. The language to be used in the arbitral proceedings shall be English. - -In addition, the following terms only apply to Customers with principal offices within Europe, the Middle East or Africa -(EMEA): - -Arbitration Rules and Location. Any Dispute shall be referred to and finally resolved by arbitration under the London -Court of International Arbitration (“LCIA”) Rules (which Rules are deemed to be incorporated by reference into this -clause) on the basis that the governing law is the law of the State of New York, USA. The seat, or legal place, of -arbitration shall be London, England. - -(b) In addition, the following terms only apply to Customers with principal offices within Asia Pacific, Australia & -New Zealand: - -Arbitration Rules and Location. Any Dispute shall be referred to and finally resolved by arbitration under the Rules of -Conciliation and Arbitration of the International Chamber of Commerce (“ICC”) in force on the date when the notice of -arbitration is submitted in accordance with such Rules (which Rules are deemed to be incorporated by reference into this -clause) on the basis that the governing law is the law of the State of New York, USA. The seat, or legal place, of -arbitration shall be Singapore. - -(c) In addition, the following terms only apply to Customers with principal offices within the Americas (excluding -North America): - -Arbitration Rules and Location. Any Dispute shall be referred to and finally resolved by arbitration under -International Dispute Resolution Procedures of the American Arbitration Association (“AAA”) in force on the date when -the notice of arbitration is submitted in accordance with such Procedures (which Procedures are deemed to be -incorporated by reference into this clause) on the basis that the governing law is the law of the State of New York, -USA. The seat, or legal place, of arbitration shall be New York, New York, USA. - -(4) In addition, for Customers with principal offices within the UK, the following new sentence is added to the end -of Section 4.1: - -Nothing in this Agreement shall have effect so as to limit or exclude a party’s liability for death or personal injury -caused by negligence or for fraud including fraudulent misrepresentation and this Section 4.1 shall take effect subject -to this provision. - -(5) In addition, for Customers with principal offices within France, Sections 1.2, 3 and 4.1 of the Agreement are -deleted and replaced with the following new Sections 1.2, 3.3 and 4.1: -1.2 Reservation of Rights; Restrictions. Elasticsearch owns all right title and interest in and to the Software and -any derivative works thereof, and except as expressly set forth in Section 1.1 above, no other license to the Software -is granted to You by implication, or otherwise. You agree not to prepare derivative works from, modify, copy or use the -Software in any manner except as expressly permitted in this Agreement; provided that You may copy the Software for -archival purposes, only where such software is provided on a non-durable medium; and You may decompile the Software, -where necessary for interoperability purposes and where necessary for the correction of errors making the software unfit -for its intended purpose, if such right is not reserved by Elasticsearch as editor of the Software. Pursuant to article -L122-6-1 of the French intellectual property code, Elasticsearch reserves the right to correct any bugs as necessary for -the Software to serve its intended purpose. You agree not to: (i) transfer, sell, rent, lease, distribute, sublicense, -loan or otherwise transfer the Software in whole or in part to any third party; (ii) use the Software for providing -time-sharing services, any software-as-a-service offering (“SaaS”), service bureau services or as part of an application -services provider or other service offering; (iii) alter or remove any proprietary notices in the Software; or (iv) make -available to any third party any analysis of the results of operation of the Software, including benchmarking results, -without the prior written consent of Elasticsearch. -3.3 Warranty Disclaimer. TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, THE SOFTWARE IS PROVIDED “AS IS” -WITHOUT WARRANTY OF ANY KIND, AND ELASTICSEARCH AND ITS LICENSORS MAKE NO WARRANTIES WHETHER EXPRESSED, IMPLIED OR -STATUTORY REGARDING OR RELATING TO THE SOFTWARE OR DOCUMENTATION. TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, -ELASTICSEARCH AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE WITH -RESPECT TO THE SOFTWARE AND DOCUMENTATION, AND WITH RESPECT TO THE USE OF THE FOREGOING. FURTHER, ELASTICSEARCH DOES -NOT WARRANT RESULTS OF USE OR THAT THE SOFTWARE WILL BE ERROR FREE OR THAT THE USE OF THE SOFTWARE WILL BE -UNINTERRUPTED. -4.1 Disclaimer of Certain Damages. IN NO EVENT SHALL YOU OR ELASTICSEARCH OR ITS LICENSORS BE LIABLE FOR ANY LOSS OF -PROFITS, LOSS OF USE, BUSINESS INTERRUPTION, LOSS OF DATA, COST OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT OR -UNFORESEEABLE DAMAGES OF ANY KIND IN CONNECTION WITH OR ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE, OR THE -PERFORMANCE OF OR FAILURE TO PERFORM THIS AGREEMENT, WHETHER ALLEGED AS A BREACH OF CONTRACT OR TORTIOUS CONDUCT, -INCLUDING NEGLIGENCE. THE LIMITATIONS OF LIABILITY SET FORTH IN THIS SECTION 4.1 SHALL NOT APPLY TO A BREACH, THROUGH -GROSS NEGLIGENCE OR INTENTIONAL MISCONDUCT BY YOU, OF THE SCOPE OF THE LICENSE GRANTED IN SECTION 1.1, OR IN CASE OF -DEATH OR PERSONAL INJURY. -(6) In addition, for Customers with principal offices within Australia, Sections 4.1, 4.2 and 4.3 of the Agreement -are deleted and replaced with the following new Sections 4.1, 4.2 and 4.3: -4.1 Disclaimer of Certain Damages. Subject to clause 4.3, a party is not liable for Consequential Loss however -caused (including by the negligence of that party) suffered or incurred by the other party in connection with this -agreement. “Consequential Loss” means loss of revenues, loss of reputation, indirect loss, loss of profits, -consequential loss, loss of actual or anticipated savings, indirect loss, lost opportunities, including opportunities to -enter into arrangements with third parties, loss or damage in connection with claims against by third parties, or loss -or corruption or data. -4.2 Damages Cap. SUBJECT TO CLAUSES 4.1 AND 4.3, ANY LIABILITY OF ELASTICSEARCH FOR ANY LOSS OR DAMAGE, HOWEVER -CAUSED (INCLUDING BY THE NEGLIGENCE OF ELASTICSEARCH), SUFFERED BY YOU IN CONNECTION WITH THIS AGREEMENT IS LIMITED TO -THE AMOUNT YOU PAID, IN THE TWELVE (12) MONTHS IMMEDIATELY PRIOR TO THE EVENT GIVING RISE TO LIABILITY, UNDER THE -ELASTICSEARCH SUPPORT SERVICES AGREEMENT IN CONNECTION WITH WHICH YOU OBTAINED THE LICENSE TO USE THE SOFTWARE. THE -LIMITATION SET OUT IN THIS SECTION 4.2 IS AN AGGREGATE LIMIT FOR ALL CLAIMS, WHENEVER MADE. -4.3 Limitation and Disclaimer Exceptions. If the Competition and Consumer Act 2010 (Cth) or any other legislation or -any other legislation states that there is a guarantee in relation to any good or service supplied by Elasticsearch in -connection with this agreement, and Elasticsearch’s liability for failing to comply with that guarantee cannot be -excluded but may be limited, Sections 4.1 and 4.2 do not apply to that liability and instead Elasticsearch’s liability -for such failure is limited (at Elasticsearch’s election) to, in the case of a supply of goods, the Elasticsearch -replacing the goods or supplying equivalent goods or repairing the goods, or in the case of a supply of services, -Elasticsearch supplying the services again or paying the cost of having the services supplied again. -(7) In addition, for Customers with principal offices within Japan, Sections 1.2, 3 and 4.1 of the Agreement are -deleted and replaced with the following new Sections 1.2, 3.3 and 4.1: -1.2 Reservation of Rights; Restrictions. As between Elasticsearch and You, Elasticsearch owns all right title and -interest in and to the Software and any derivative works thereof, and except as expressly set forth in Section 1.1 -above, no other license to the Software is granted to You by implication or otherwise. You agree not to: (i) prepare -derivative works from, modify, copy or use the Software in any manner except as expressly permitted in this Agreement or -applicable law; (ii) transfer, sell, rent, lease, distribute, sublicense, loan or otherwise transfer the Software in -whole or in part to any third party; (iii) use the Software for providing time-sharing services, any -software-as-a-service offering (“SaaS”), service bureau services or as part of an application services provider or other -service offering; (iv) alter or remove any proprietary notices in the Software; or (v) make available to any third party -any analysis of the results of operation of the Software, including benchmarking results, without the prior written -consent of Elasticsearch. -3.3 Warranty Disclaimer. TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, THE SOFTWARE IS PROVIDED “AS IS” -WITHOUT WARRANTY OF ANY KIND, AND ELASTICSEARCH AND ITS LICENSORS MAKE NO WARRANTIES WHETHER EXPRESSED, IMPLIED OR -STATUTORY REGARDING OR RELATING TO THE SOFTWARE OR DOCUMENTATION. TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, -ELASTICSEARCH AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NON-INFRINGEMENT WITH RESPECT TO THE SOFTWARE AND DOCUMENTATION, AND WITH RESPECT TO THE USE OF -THE FOREGOING. FURTHER, ELASTICSEARCH DOES NOT WARRANT RESULTS OF USE OR THAT THE SOFTWARE WILL BE ERROR FREE OR THAT -THE USE OF THE SOFTWARE WILL BE UNINTERRUPTED. -4.1 Disclaimer of Certain Damages. IN NO EVENT SHALL YOU OR ELASTICSEARCH OR ITS LICENSORS BE LIABLE FOR ANY LOSS OF -PROFITS, LOSS OF USE, BUSINESS INTERRUPTION, LOSS OF DATA, COST OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY -SPECIALINDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH OR ARISING OUT OF THE USE -OR INABILITY TO USE THE SOFTWARE, OR THE PERFORMANCE OF OR FAILURE TO PERFORM THIS AGREEMENT, WHETHER ALLEGED AS A -BREACH OF CONTRACT OR TORTIOUS CONDUCT, INCLUDING NEGLIGENCE, EVEN IF THE RESPONSIBLE PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. THE LIMITATIONS OF LIABILITY SET FORTH IN THIS SECTION 4.1 SHALL NOT APPLY TO A BREACH -THROUGH GROSS NEGLIGENCE OR INTENTIONAL MISCONDUCT BY YOU OF THE SCOPE OF THE LICENSE GRANTED IN SECTION 1.1 OR TO ANY -OTHER LIABILITY THAT CANNOT BE EXCLUDED OR LIMITED UNDER APPLICABLE LAW. - diff --git a/elasticsearch/x-pack/build.gradle b/elasticsearch/x-pack/build.gradle index 5c67a941b00..6e0a02b86a2 100644 --- a/elasticsearch/x-pack/build.gradle +++ b/elasticsearch/x-pack/build.gradle @@ -1,6 +1,5 @@ import org.elasticsearch.gradle.MavenFilteringHack import org.elasticsearch.gradle.test.NodeInfo - import java.nio.charset.StandardCharsets group 'org.elasticsearch.plugin' @@ -27,10 +26,6 @@ licenseHeaders { } dependencies { - // license deps - compile project(':x-plugins:elasticsearch:license:base') - testCompile project(':x-plugins:elasticsearch:license:licensor') - // security deps compile project(path: ':modules:transport-netty3', configuration: 'runtime') compile 'dk.brics.automaton:automaton:1.11-8' @@ -78,6 +73,11 @@ for (String module : ['', 'license-plugin/', 'security/', 'watcher/', 'monitorin } } +// make LicenseSigner available for testing signed licenses +sourceSets.test.java { + srcDir '../license-tools/src/main/java' +} + compileJava.options.compilerArgs << "-Xlint:-deprecation,-rawtypes,-serial,-try,-unchecked" compileTestJava.options.compilerArgs << "-Xlint:-deprecation,-rawtypes,-serial,-try,-unchecked" @@ -117,8 +117,10 @@ forbiddenPatterns { // TODO: standardize packaging config for plugins bundlePlugin { - from(projectDir) { + from(project(':x-plugins').projectDir) { include 'LICENSE.txt' + } + from(projectDir) { include 'NOTICE.txt' } from('bin/x-pack') { @@ -236,29 +238,3 @@ thirdPartyAudit.excludes = [ 'javax.activation.URLDataSource', 'javax.activation.UnsupportedDataTypeException' ] - -modifyPom { MavenPom pom -> - pom.withXml { XmlProvider xml -> - // first find if we have dependencies at all, and grab the node - NodeList depsNodes = xml.asNode().get('dependencies') - if (depsNodes.isEmpty()) { - return - } - - // find the 'base' dependency and replace it with the correct name because the project name is - // always used even when the pom of the other project is correct - Iterator childNodeIter = depsNodes.get(0).children().iterator() - while (childNodeIter.hasNext()) { - Node depNode = childNodeIter.next() - String groupId = depNode.get('groupId').get(0).text() - Node artifactIdNode = depNode.get('artifactId').get(0) - String artifactId = artifactIdNode.text() - String scope = depNode.get("scope").get(0).text() - if (groupId.equals('org.elasticsearch') && artifactId.equals('base')) { - artifactIdNode.replaceNode(new Node(null, 'artifactId', 'license-core')) - } else if ('test'.equals(scope)) { - childNodeIter.remove() - } - } - } -} diff --git a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/GraphFeatureSet.java b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/GraphFeatureSet.java index 6f350bd9ceb..ca7c9721115 100644 --- a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/GraphFeatureSet.java +++ b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/GraphFeatureSet.java @@ -10,7 +10,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.XPackFeatureSet; import java.io.IOException; diff --git a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/action/TransportGraphExploreAction.java b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/action/TransportGraphExploreAction.java index 8312c23f519..4adaf31f2c2 100644 --- a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/action/TransportGraphExploreAction.java +++ b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/action/TransportGraphExploreAction.java @@ -23,8 +23,8 @@ import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; -import org.elasticsearch.license.plugin.core.LicenseUtils; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.LicenseUtils; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.AggregationBuilder; import org.elasticsearch.search.aggregations.bucket.sampler.DiversifiedAggregationBuilder; diff --git a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/rest/action/RestGraphAction.java b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/rest/action/RestGraphAction.java index 140984f8148..5115d010c0c 100644 --- a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/rest/action/RestGraphAction.java +++ b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/rest/action/RestGraphAction.java @@ -16,7 +16,6 @@ import java.util.Map; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.action.support.IndicesOptions; -import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesReference; @@ -27,23 +26,24 @@ import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.indices.query.IndicesQueriesRegistry; -import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestChannel; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.action.support.RestActions; import org.elasticsearch.rest.action.support.RestToXContentListener; +import org.elasticsearch.xpack.XPackClient; import org.elasticsearch.xpack.graph.action.GraphExploreRequest; import org.elasticsearch.xpack.graph.action.GraphExploreResponse; import org.elasticsearch.xpack.graph.action.Hop; import org.elasticsearch.xpack.graph.action.VertexRequest; import org.elasticsearch.xpack.graph.action.GraphExploreRequest.TermBoost; +import org.elasticsearch.xpack.rest.XPackRestHandler; /** * @see GraphExploreRequest */ -public class RestGraphAction extends BaseRestHandler { +public class RestGraphAction extends XPackRestHandler { private IndicesQueriesRegistry indicesQueriesRegistry; public static final ParseField TIMEOUT_FIELD = new ParseField("timeout"); @@ -68,21 +68,23 @@ public class RestGraphAction extends BaseRestHandler { @Inject public RestGraphAction(Settings settings, RestController controller, IndicesQueriesRegistry indicesQueriesRegistry) { super(settings); - // @deprecated TODO need to add deprecation support as per https://github.com/elastic/x-plugins/issues/1760#issuecomment-217507517 - controller.registerHandler(GET, "/{index}/_graph/explore", this); - controller.registerHandler(POST, "/{index}/_graph/explore", this); - controller.registerHandler(GET, "/{index}/{type}/_graph/explore", this); - controller.registerHandler(POST, "/{index}/{type}/_graph/explore", this); - // new REST endpoint - controller.registerHandler(GET, "/{index}/_xpack/graph/_explore", this); - controller.registerHandler(POST, "/{index}/_xpack/graph/_explore", this); - controller.registerHandler(GET, "/{index}/{type}/_xpack/graph/_explore", this); - controller.registerHandler(POST, "/{index}/{type}/_xpack/graph/_explore", this); + this.indicesQueriesRegistry = indicesQueriesRegistry; + + // @deprecated Remove in 6.0 + // NOTE: Old versions did not end with "/_explore"; they were just "/explore" + controller.registerWithDeprecatedHandler(GET, "/{index}" + URI_BASE + "/_graph/_explore", this, + GET, "/{index}/_graph/explore", deprecationLogger); + controller.registerWithDeprecatedHandler(POST, "/{index}" + URI_BASE + "/_graph/_explore", this, + POST, "/{index}/_graph/explore", deprecationLogger); + controller.registerWithDeprecatedHandler(GET, "/{index}/{type}" + URI_BASE + "/_graph/_explore", this, + GET, "/{index}/{type}/_graph/explore", deprecationLogger); + controller.registerWithDeprecatedHandler(POST, "/{index}/{type}" + URI_BASE + "/_graph/_explore", this, + POST, "/{index}/{type}/_graph/explore", deprecationLogger); } @Override - public void handleRequest(final RestRequest request, final RestChannel channel, final NodeClient client) throws IOException { + public void handleRequest(final RestRequest request, final RestChannel channel, final XPackClient client) throws IOException { GraphExploreRequest graphRequest = new GraphExploreRequest(Strings.splitStringByCommaToArray(request.param("index"))); graphRequest.indicesOptions(IndicesOptions.fromRequest(request, graphRequest.indicesOptions())); graphRequest.routing(request.param("routing")); @@ -109,7 +111,7 @@ public class RestGraphAction extends BaseRestHandler { } graphRequest.types(Strings.splitStringByCommaToArray(request.param("type"))); - client.execute(INSTANCE, graphRequest, new RestToXContentListener(channel)); + client.es().execute(INSTANCE, graphRequest, new RestToXContentListener(channel)); } private void parseHop(XContentParser parser, QueryParseContext context, Hop currentHop, diff --git a/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/GraphFeatureSetTests.java b/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/GraphFeatureSetTests.java index 8c612d17c57..57e7ec8e60c 100644 --- a/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/GraphFeatureSetTests.java +++ b/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/GraphFeatureSetTests.java @@ -7,7 +7,7 @@ package org.elasticsearch.xpack.graph; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.junit.Before; diff --git a/elasticsearch/x-pack/graph/src/test/resources/rest-api-spec/api/xpack.graph.explore.json b/elasticsearch/x-pack/graph/src/test/resources/rest-api-spec/api/xpack.graph.explore.json index ee4b05a8af0..4530b6027ab 100644 --- a/elasticsearch/x-pack/graph/src/test/resources/rest-api-spec/api/xpack.graph.explore.json +++ b/elasticsearch/x-pack/graph/src/test/resources/rest-api-spec/api/xpack.graph.explore.json @@ -3,8 +3,8 @@ "documentation": "https://www.elastic.co/guide/en/graph/current/explore.html", "methods": ["GET", "POST"], "url": { - "path": "/{index}/_xpack/graph/_explore", - "paths": ["/{index}/_xpack/graph/_explore", "/{index}/{type}/_xpack/graph/_explore"], + "path": "/{index}/_xpack/_graph/_explore", + "paths": ["/{index}/_xpack/_graph/_explore", "/{index}/{type}/_xpack/_graph/_explore"], "parts" : { "index": { "type" : "list", @@ -30,4 +30,4 @@ "description" : "Graph Query DSL" } } -} \ No newline at end of file +} diff --git a/elasticsearch/license/base/src/main/java/org/elasticsearch/license/core/CryptUtils.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/CryptUtils.java similarity index 99% rename from elasticsearch/license/base/src/main/java/org/elasticsearch/license/core/CryptUtils.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/CryptUtils.java index 6940d121402..c3c69d5bfcd 100644 --- a/elasticsearch/license/base/src/main/java/org/elasticsearch/license/core/CryptUtils.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/CryptUtils.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.core; +package org.elasticsearch.license; import javax.crypto.BadPaddingException; diff --git a/elasticsearch/license/base/src/main/java/org/elasticsearch/license/core/DateUtils.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/DateUtils.java similarity index 97% rename from elasticsearch/license/base/src/main/java/org/elasticsearch/license/core/DateUtils.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/DateUtils.java index 3a25ebebe50..74183ab5e05 100644 --- a/elasticsearch/license/base/src/main/java/org/elasticsearch/license/core/DateUtils.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/DateUtils.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.core; +package org.elasticsearch.license; import org.elasticsearch.common.joda.FormatDateTimeFormatter; import org.elasticsearch.common.joda.Joda; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/delete/DeleteLicenseAction.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/DeleteLicenseAction.java similarity index 94% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/delete/DeleteLicenseAction.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/DeleteLicenseAction.java index 9bb72c3da4a..de356870fbb 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/delete/DeleteLicenseAction.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/DeleteLicenseAction.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.action.delete; +package org.elasticsearch.license; import org.elasticsearch.action.Action; import org.elasticsearch.client.ElasticsearchClient; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/delete/DeleteLicenseRequest.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/DeleteLicenseRequest.java similarity index 94% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/delete/DeleteLicenseRequest.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/DeleteLicenseRequest.java index da52e8be014..29558cf9e42 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/delete/DeleteLicenseRequest.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/DeleteLicenseRequest.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.action.delete; +package org.elasticsearch.license; import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.support.master.AcknowledgedRequest; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/delete/DeleteLicenseRequestBuilder.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/DeleteLicenseRequestBuilder.java similarity index 94% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/delete/DeleteLicenseRequestBuilder.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/DeleteLicenseRequestBuilder.java index bbdc2574ca9..b554b005537 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/delete/DeleteLicenseRequestBuilder.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/DeleteLicenseRequestBuilder.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.action.delete; +package org.elasticsearch.license; import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder; import org.elasticsearch.client.ElasticsearchClient; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/delete/DeleteLicenseResponse.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/DeleteLicenseResponse.java similarity index 94% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/delete/DeleteLicenseResponse.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/DeleteLicenseResponse.java index 2b5d35edeae..c30890a0ff6 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/delete/DeleteLicenseResponse.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/DeleteLicenseResponse.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.action.delete; +package org.elasticsearch.license; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.common.io.stream.StreamInput; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/ExpirationCallback.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/ExpirationCallback.java similarity index 98% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/ExpirationCallback.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/ExpirationCallback.java index 4166ce3d423..3f0e6833c36 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/ExpirationCallback.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/ExpirationCallback.java @@ -3,16 +3,15 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import org.elasticsearch.common.logging.LoggerMessageFormat; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.license.core.License; import org.elasticsearch.xpack.scheduler.SchedulerEngine; import java.util.UUID; -public abstract class ExpirationCallback { +abstract class ExpirationCallback { static final String EXPIRATION_JOB_PREFIX = ".license_expiration_job_"; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/get/GetLicenseAction.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/GetLicenseAction.java similarity index 94% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/get/GetLicenseAction.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/GetLicenseAction.java index 805a45df6e6..47263410796 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/get/GetLicenseAction.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/GetLicenseAction.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.action.get; +package org.elasticsearch.license; import org.elasticsearch.action.Action; import org.elasticsearch.client.ElasticsearchClient; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/get/GetLicenseRequest.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/GetLicenseRequest.java similarity index 91% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/get/GetLicenseRequest.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/GetLicenseRequest.java index 499fdc68c2b..965308de0e4 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/get/GetLicenseRequest.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/GetLicenseRequest.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.action.get; +package org.elasticsearch.license; import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.support.master.MasterNodeReadRequest; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/get/GetLicenseRequestBuilder.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/GetLicenseRequestBuilder.java similarity index 94% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/get/GetLicenseRequestBuilder.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/GetLicenseRequestBuilder.java index 5b89c6a619c..7e92a54bce2 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/get/GetLicenseRequestBuilder.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/GetLicenseRequestBuilder.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.action.get; +package org.elasticsearch.license; import org.elasticsearch.action.support.master.MasterNodeReadOperationRequestBuilder; import org.elasticsearch.client.ElasticsearchClient; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/get/GetLicenseResponse.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/GetLicenseResponse.java similarity index 92% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/get/GetLicenseResponse.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/GetLicenseResponse.java index 1d5b9a67cdf..53339269560 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/get/GetLicenseResponse.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/GetLicenseResponse.java @@ -3,12 +3,11 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.action.get; +package org.elasticsearch.license; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.license.core.License; import java.io.IOException; diff --git a/elasticsearch/license/base/src/main/java/org/elasticsearch/license/core/License.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/License.java similarity index 99% rename from elasticsearch/license/base/src/main/java/org/elasticsearch/license/core/License.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/License.java index f07d38edeed..a4d3491b9d2 100644 --- a/elasticsearch/license/base/src/main/java/org/elasticsearch/license/core/License.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/License.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.core; +package org.elasticsearch.license; import org.apache.lucene.util.CollectionUtil; import org.elasticsearch.ElasticsearchException; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicenseService.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicenseService.java similarity index 98% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicenseService.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicenseService.java index 322bd925537..7e5ae2b0390 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicenseService.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicenseService.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; @@ -25,12 +25,6 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.env.Environment; import org.elasticsearch.gateway.GatewayService; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.core.LicenseVerifier; -import org.elasticsearch.license.core.OperationModeFileWatcher; -import org.elasticsearch.license.plugin.action.delete.DeleteLicenseRequest; -import org.elasticsearch.license.plugin.action.put.PutLicenseRequest; -import org.elasticsearch.license.plugin.action.put.PutLicenseResponse; import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.xpack.XPackPlugin; import org.elasticsearch.xpack.scheduler.SchedulerEngine; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicenseUtils.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicenseUtils.java similarity index 96% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicenseUtils.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicenseUtils.java index 2f7a3ca7470..42139471646 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicenseUtils.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicenseUtils.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.rest.RestStatus; diff --git a/elasticsearch/license/base/src/main/java/org/elasticsearch/license/core/LicenseVerifier.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicenseVerifier.java similarity index 98% rename from elasticsearch/license/base/src/main/java/org/elasticsearch/license/core/LicenseVerifier.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicenseVerifier.java index 49f8c0c2b14..af37ea0341c 100644 --- a/elasticsearch/license/base/src/main/java/org/elasticsearch/license/core/LicenseVerifier.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicenseVerifier.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.core; +package org.elasticsearch.license; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRefIterator; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicensesMetaData.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicensesMetaData.java new file mode 100644 index 00000000000..326f6eae907 --- /dev/null +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicensesMetaData.java @@ -0,0 +1,144 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.license; + +import org.elasticsearch.cluster.AbstractDiffable; +import org.elasticsearch.cluster.metadata.MetaData; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; + +import java.io.IOException; +import java.util.EnumSet; + +/** + * Contains metadata about registered licenses + */ +class LicensesMetaData extends AbstractDiffable implements MetaData.Custom { + + public static final String TYPE = "licenses"; + + /** + * When license is explicitly removed by a user, LICENSE_TOMBSTONE + * is used as a placeholder in the license metadata. This enables + * us to distinguish between the scenario when a cluster never + * had a license (null) and when a license was removed explicitly + * (LICENSE_TOMBSTONE). + * We rely on this to decide whether to generate a unsigned trial + * license or not. we should only generate a license if no license + * ever existed in the cluster state + */ + public static final License LICENSE_TOMBSTONE = License.builder() + .type("trial") + .issuer("elasticsearch") + .uid("TOMBSTONE") + .issuedTo("") + .maxNodes(0) + .issueDate(0) + .expiryDate(0) + .build(); + + public static final LicensesMetaData PROTO = new LicensesMetaData(null); + + private License license; + + public LicensesMetaData(License license) { + this.license = license; + } + + public License getLicense() { + return license; + } + + @Override + public String toString() { + if (license != null) { + return license.toString(); + } + return ""; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + LicensesMetaData that = (LicensesMetaData) o; + return !(license != null ? !license.equals(that.license) : that.license != null); + } + + @Override + public int hashCode() { + return license != null ? license.hashCode() : 0; + } + + @Override + public String type() { + return TYPE; + } + + @Override + public EnumSet context() { + return EnumSet.of(MetaData.XContentContext.GATEWAY); + } + + @Override + public LicensesMetaData fromXContent(XContentParser parser) throws IOException { + License license = LICENSE_TOMBSTONE; + XContentParser.Token token; + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + String fieldName = parser.currentName(); + if (fieldName != null) { + if (fieldName.equals(Fields.LICENSE)) { + token = parser.nextToken(); + if (token == XContentParser.Token.START_OBJECT) { + license = License.fromXContent(parser); + } else if (token == XContentParser.Token.VALUE_NULL) { + license = LICENSE_TOMBSTONE; + } + } + } + } + } + return new LicensesMetaData(license); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + if (license == LICENSE_TOMBSTONE) { + builder.nullField(Fields.LICENSE); + } else { + builder.startObject(Fields.LICENSE); + license.toInnerXContent(builder, params); + builder.endObject(); + } + return builder; + } + + @Override + public void writeTo(StreamOutput streamOutput) throws IOException { + if (license == LICENSE_TOMBSTONE) { + streamOutput.writeBoolean(false); // no license + } else { + streamOutput.writeBoolean(true); // has a license + license.writeTo(streamOutput); + } + } + + @Override + public LicensesMetaData readFrom(StreamInput streamInput) throws IOException { + License license = LICENSE_TOMBSTONE; + if (streamInput.readBoolean()) { + license = License.readLicense(streamInput); + } + return new LicensesMetaData(license); + } + + private static final class Fields { + private static final String LICENSE = "license"; + } +} diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicensesStatus.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicensesStatus.java similarity index 94% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicensesStatus.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicensesStatus.java index 3bd18d58770..91e0d7239cf 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicensesStatus.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicensesStatus.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; public enum LicensesStatus { VALID((byte) 0), diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/Licensing.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/Licensing.java similarity index 63% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/Licensing.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/Licensing.java index aeaca77fbeb..5d93ec95c22 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/Licensing.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/Licensing.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin; +package org.elasticsearch.license; import java.util.Arrays; import java.util.Collection; @@ -18,18 +18,6 @@ import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; -import org.elasticsearch.license.plugin.action.delete.DeleteLicenseAction; -import org.elasticsearch.license.plugin.action.delete.TransportDeleteLicenseAction; -import org.elasticsearch.license.plugin.action.get.GetLicenseAction; -import org.elasticsearch.license.plugin.action.get.TransportGetLicenseAction; -import org.elasticsearch.license.plugin.action.put.PutLicenseAction; -import org.elasticsearch.license.plugin.action.put.TransportPutLicenseAction; -import org.elasticsearch.license.plugin.core.LicensesMetaData; -import org.elasticsearch.license.plugin.core.LicenseService; -import org.elasticsearch.license.plugin.core.XPackLicenseState; -import org.elasticsearch.license.plugin.rest.RestDeleteLicenseAction; -import org.elasticsearch.license.plugin.rest.RestGetLicenseAction; -import org.elasticsearch.license.plugin.rest.RestPutLicenseAction; import org.elasticsearch.plugins.ActionPlugin; import org.elasticsearch.rest.RestHandler; import org.elasticsearch.watcher.ResourceWatcherService; @@ -57,10 +45,6 @@ public class Licensing implements ActionPlugin { isTribeNode = isTribeNode(settings); } - public Collection nodeModules() { - return Collections.emptyList(); - } - @Override public List, ? extends ActionResponse>> getActions() { if (isTribeNode) { @@ -81,14 +65,6 @@ public class Licensing implements ActionPlugin { RestDeleteLicenseAction.class); } - public Collection createComponents(ClusterService clusterService, Clock clock, Environment environment, - ResourceWatcherService resourceWatcherService, - XPackLicenseState licenseState) { - LicenseService licenseService = new LicenseService(settings, clusterService, clock, - environment, resourceWatcherService, licenseState); - return Arrays.asList(licenseService, licenseState); - } - public List> getSettings() { // TODO convert this wildcard to a real setting return Collections.singletonList(Setting.groupSetting("license.", Setting.Property.NodeScope)); diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/LicensingClient.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicensingClient.java similarity index 60% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/LicensingClient.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicensingClient.java index 203f1fb3e0d..882e5bcc85b 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/LicensingClient.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/LicensingClient.java @@ -3,23 +3,10 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin; +package org.elasticsearch.license; import org.elasticsearch.action.ActionListener; import org.elasticsearch.client.ElasticsearchClient; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.action.delete.DeleteLicenseAction; -import org.elasticsearch.license.plugin.action.delete.DeleteLicenseRequest; -import org.elasticsearch.license.plugin.action.delete.DeleteLicenseRequestBuilder; -import org.elasticsearch.license.plugin.action.delete.DeleteLicenseResponse; -import org.elasticsearch.license.plugin.action.get.GetLicenseAction; -import org.elasticsearch.license.plugin.action.get.GetLicenseRequest; -import org.elasticsearch.license.plugin.action.get.GetLicenseRequestBuilder; -import org.elasticsearch.license.plugin.action.get.GetLicenseResponse; -import org.elasticsearch.license.plugin.action.put.PutLicenseAction; -import org.elasticsearch.license.plugin.action.put.PutLicenseRequest; -import org.elasticsearch.license.plugin.action.put.PutLicenseRequestBuilder; -import org.elasticsearch.license.plugin.action.put.PutLicenseResponse; /** * diff --git a/elasticsearch/license/base/src/main/java/org/elasticsearch/license/core/OperationModeFileWatcher.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/OperationModeFileWatcher.java similarity index 95% rename from elasticsearch/license/base/src/main/java/org/elasticsearch/license/core/OperationModeFileWatcher.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/OperationModeFileWatcher.java index 3ba63e3cdd3..28c81530381 100644 --- a/elasticsearch/license/base/src/main/java/org/elasticsearch/license/core/OperationModeFileWatcher.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/OperationModeFileWatcher.java @@ -3,11 +3,11 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.core; +package org.elasticsearch.license; import org.elasticsearch.common.logging.ESLogger; -import org.elasticsearch.license.core.License.OperationMode; +import org.elasticsearch.license.License.OperationMode; import org.elasticsearch.watcher.FileChangesListener; import org.elasticsearch.watcher.FileWatcher; import org.elasticsearch.watcher.ResourceWatcherService; @@ -26,7 +26,7 @@ import java.util.concurrent.atomic.AtomicBoolean; * In case of failure to read a valid operation mode from licenseModePath, * the operation mode will default to PLATINUM */ -public final class OperationModeFileWatcher extends FileChangesListener { +public final class OperationModeFileWatcher implements FileChangesListener { private final ResourceWatcherService resourceWatcherService; private final Path licenseModePath; private final AtomicBoolean initialized = new AtomicBoolean(); diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/put/PutLicenseAction.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/PutLicenseAction.java similarity index 94% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/put/PutLicenseAction.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/PutLicenseAction.java index c4122dfa58d..4aee591b9c5 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/put/PutLicenseAction.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/PutLicenseAction.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.action.put; +package org.elasticsearch.license; import org.elasticsearch.action.Action; import org.elasticsearch.client.ElasticsearchClient; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/put/PutLicenseRequest.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/PutLicenseRequest.java similarity index 93% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/put/PutLicenseRequest.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/PutLicenseRequest.java index 7780908cce9..7b8e63f8f18 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/put/PutLicenseRequest.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/PutLicenseRequest.java @@ -3,14 +3,13 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.action.put; +package org.elasticsearch.license; import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.ValidateActions; import org.elasticsearch.action.support.master.AcknowledgedRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.license.core.License; import java.io.IOException; @@ -29,7 +28,7 @@ public class PutLicenseRequest extends AcknowledgedRequest { } /** - * Parses license from json format to an instance of {@link org.elasticsearch.license.core.License} + * Parses license from json format to an instance of {@link License} * * @param licenseDefinition licenses definition */ diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/put/PutLicenseRequestBuilder.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/PutLicenseRequestBuilder.java similarity index 93% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/put/PutLicenseRequestBuilder.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/PutLicenseRequestBuilder.java index 5759cc18f18..87750405efb 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/put/PutLicenseRequestBuilder.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/PutLicenseRequestBuilder.java @@ -3,11 +3,10 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.action.put; +package org.elasticsearch.license; import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder; import org.elasticsearch.client.ElasticsearchClient; -import org.elasticsearch.license.core.License; /** * Register license request builder diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/put/PutLicenseResponse.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/PutLicenseResponse.java similarity index 97% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/put/PutLicenseResponse.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/PutLicenseResponse.java index ea0870924d4..967bf9ef1be 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/put/PutLicenseResponse.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/PutLicenseResponse.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.action.put; +package org.elasticsearch.license; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.common.io.stream.StreamInput; @@ -11,7 +11,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; -import org.elasticsearch.license.plugin.core.LicensesStatus; +import org.elasticsearch.license.LicensesStatus; import java.io.IOException; import java.util.Collections; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/rest/RestDeleteLicenseAction.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/RestDeleteLicenseAction.java similarity index 90% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/rest/RestDeleteLicenseAction.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/RestDeleteLicenseAction.java index e92e5a24f75..1244f5b1264 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/rest/RestDeleteLicenseAction.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/RestDeleteLicenseAction.java @@ -3,12 +3,10 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.rest; +package org.elasticsearch.license; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.action.delete.DeleteLicenseAction; -import org.elasticsearch.license.plugin.action.delete.DeleteLicenseRequest; import org.elasticsearch.rest.RestChannel; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/rest/RestGetLicenseAction.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/RestGetLicenseAction.java similarity index 92% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/rest/RestGetLicenseAction.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/RestGetLicenseAction.java index 4851d0a1aae..309d6b8a3ed 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/rest/RestGetLicenseAction.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/RestGetLicenseAction.java @@ -3,16 +3,12 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.rest; +package org.elasticsearch.license; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.action.get.GetLicenseAction; -import org.elasticsearch.license.plugin.action.get.GetLicenseRequest; -import org.elasticsearch.license.plugin.action.get.GetLicenseResponse; import org.elasticsearch.rest.BytesRestResponse; import org.elasticsearch.rest.RestChannel; import org.elasticsearch.rest.RestController; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/rest/RestPutLicenseAction.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/RestPutLicenseAction.java similarity index 92% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/rest/RestPutLicenseAction.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/RestPutLicenseAction.java index a5138db8fd3..a0ccece2ed9 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/rest/RestPutLicenseAction.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/RestPutLicenseAction.java @@ -3,15 +3,12 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.rest; +package org.elasticsearch.license; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.license.plugin.action.put.PutLicenseAction; -import org.elasticsearch.license.plugin.action.put.PutLicenseRequest; -import org.elasticsearch.license.plugin.action.put.PutLicenseResponse; import org.elasticsearch.rest.BytesRestResponse; import org.elasticsearch.rest.RestChannel; import org.elasticsearch.rest.RestController; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/delete/TransportDeleteLicenseAction.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/TransportDeleteLicenseAction.java similarity index 96% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/delete/TransportDeleteLicenseAction.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/TransportDeleteLicenseAction.java index c9c6123aac1..a1d57684a17 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/delete/TransportDeleteLicenseAction.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/TransportDeleteLicenseAction.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.action.delete; +package org.elasticsearch.license; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; @@ -17,7 +17,6 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.LicenseService; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/get/TransportGetLicenseAction.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/TransportGetLicenseAction.java similarity index 95% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/get/TransportGetLicenseAction.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/TransportGetLicenseAction.java index 98bd9b6fb72..c5085b54765 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/get/TransportGetLicenseAction.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/TransportGetLicenseAction.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.action.get; +package org.elasticsearch.license; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; @@ -16,7 +16,6 @@ import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.LicenseService; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/put/TransportPutLicenseAction.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/TransportPutLicenseAction.java similarity index 95% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/put/TransportPutLicenseAction.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/TransportPutLicenseAction.java index bd7931be486..9cc2101e501 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/action/put/TransportPutLicenseAction.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/TransportPutLicenseAction.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.action.put; +package org.elasticsearch.license; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; @@ -16,7 +16,6 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.LicenseService; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/TrialLicense.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/TrialLicense.java similarity index 91% rename from elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/TrialLicense.java rename to elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/TrialLicense.java index 7f71d81d885..bc24032f643 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/TrialLicense.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/TrialLicense.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.xcontent.ToXContent; @@ -11,17 +11,16 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.license.core.License; import java.io.IOException; import java.nio.ByteBuffer; import java.util.Base64; import java.util.Collections; -import static org.elasticsearch.license.core.CryptUtils.decrypt; -import static org.elasticsearch.license.core.CryptUtils.encrypt; +import static org.elasticsearch.license.CryptUtils.decrypt; +import static org.elasticsearch.license.CryptUtils.encrypt; -public class TrialLicense { +class TrialLicense { public static License create(License.Builder specBuilder) { License spec = specBuilder diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/package-info.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/package-info.java new file mode 100644 index 00000000000..25373122ea6 --- /dev/null +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/** + * Licensing for xpack. + * + * A {@link org.elasticsearch.license.License} is a signed set of json properties that determine what features + * are available in a running cluster. Licenses are registered through a + * {@link org.elasticsearch.license.PutLicenseRequest}. This action is handled by the master node, which places + * the signed license into the cluster state. Each node listens for cluster state updates via the + * {@link org.elasticsearch.license.LicenseService}, and updates its local copy of the license when it detects + * changes in the cluster state. + * + * The logic for which features are available given the current license is handled by + * {@link org.elasticsearch.license.XPackLicenseState}, which is updated by the + * {@link org.elasticsearch.license.LicenseService} when the license changes. + */ +package org.elasticsearch.license; \ No newline at end of file diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicensesMetaData.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicensesMetaData.java deleted file mode 100644 index afba390049b..00000000000 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicensesMetaData.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.license.plugin.core; - -import org.apache.lucene.util.CollectionUtil; -import org.elasticsearch.Version; -import org.elasticsearch.cluster.AbstractDiffable; -import org.elasticsearch.cluster.metadata.MetaData; -import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.xcontent.ToXContent; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentFactory; -import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.license.core.License; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Base64; -import java.util.Collections; -import java.util.EnumSet; -import java.util.List; - -import static org.elasticsearch.license.core.CryptUtils.decrypt; -import static org.elasticsearch.license.core.CryptUtils.encrypt; - -/** - * Contains metadata about registered licenses - */ -public class LicensesMetaData extends AbstractDiffable implements MetaData.Custom { - - public static final String TYPE = "licenses"; - - /** - * When license is explicitly removed by a user, LICENSE_TOMBSTONE - * is used as a placeholder in the license metadata. This enables - * us to distinguish between the scenario when a cluster never - * had a license (null) and when a license was removed explicitly - * (LICENSE_TOMBSTONE). - * We rely on this to decide whether to generate a unsigned trial - * license or not. we should only generate a license if no license - * ever existed in the cluster state - */ - public static final License LICENSE_TOMBSTONE = License.builder() - .type("trial") - .issuer("elasticsearch") - .uid("TOMBSTONE") - .issuedTo("") - .maxNodes(0) - .issueDate(0) - .expiryDate(0) - .build(); - - public static final LicensesMetaData PROTO = new LicensesMetaData(null); - - private License license; - - public LicensesMetaData(License license) { - this.license = license; - } - - public License getLicense() { - return license; - } - - @Override - public String toString() { - if (license != null) { - return license.toString(); - } - return ""; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - LicensesMetaData that = (LicensesMetaData) o; - return !(license != null ? !license.equals(that.license) : that.license != null); - } - - @Override - public int hashCode() { - return license != null ? license.hashCode() : 0; - } - - @Override - public String type() { - return TYPE; - } - - @Override - public EnumSet context() { - return EnumSet.of(MetaData.XContentContext.GATEWAY); - } - - @Override - public LicensesMetaData fromXContent(XContentParser parser) throws IOException { - List pre20Licenses = new ArrayList<>(1); - License license = LICENSE_TOMBSTONE; - XContentParser.Token token; - while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { - if (token == XContentParser.Token.FIELD_NAME) { - String fieldName = parser.currentName(); - if (fieldName != null) { - // for back compat with 1.x license metadata - if (fieldName.equals(Fields.TRIAL_LICENSES) || fieldName.equals(Fields.SIGNED_LICENCES)) { - token = parser.nextToken(); - if (token == XContentParser.Token.START_ARRAY) { - while (parser.nextToken() != XContentParser.Token.END_ARRAY) { - if (parser.currentToken().isValue()) { - // trial license - byte[] data = decrypt(Base64.getDecoder().decode(parser.text())); - try (XContentParser trialLicenseParser = - XContentFactory.xContent(XContentType.JSON).createParser(data)) { - trialLicenseParser.nextToken(); - License pre20TrialLicense = License.fromXContent(trialLicenseParser); - pre20Licenses.add(TrialLicense.create(License.builder().fromPre20LicenseSpec(pre20TrialLicense))); - } - } else { - // signed license - pre20Licenses.add(License.fromXContent(parser)); - } - } - } - } else if (fieldName.equals(Fields.LICENSE)) { - token = parser.nextToken(); - if (token == XContentParser.Token.START_OBJECT) { - license = License.fromXContent(parser); - } else if (token == XContentParser.Token.VALUE_NULL) { - license = LICENSE_TOMBSTONE; - } - } - } - } - } - // when we see old license metadata, - // we try to choose the license that has the latest issue date that is not expired - if (!pre20Licenses.isEmpty()) { - // take the best unexpired license - CollectionUtil.timSort(pre20Licenses, License.LATEST_ISSUE_DATE_FIRST); - long now = System.currentTimeMillis(); - for (License oldLicense : pre20Licenses) { - if (oldLicense.expiryDate() > now) { - license = oldLicense; - break; - } - } - // take the best expired license - if (license == LICENSE_TOMBSTONE && !pre20Licenses.isEmpty()) { - license = pre20Licenses.get(0); - } - } - return new LicensesMetaData(license); - } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - if (license == LICENSE_TOMBSTONE) { - builder.nullField(Fields.LICENSE); - } else { - builder.startObject(Fields.LICENSE); - license.toInnerXContent(builder, params); - builder.endObject(); - } - return builder; - } - - @Override - public void writeTo(StreamOutput streamOutput) throws IOException { - if (streamOutput.getVersion().before(Version.V_2_0_0)) { - if (license == LICENSE_TOMBSTONE) { - streamOutput.writeVInt(0); // no signed license - streamOutput.writeVInt(0); // no trial license - } else if (!License.isAutoGeneratedLicense(license.signature())) { - streamOutput.writeVInt(1); // one signed license - license.writeTo(streamOutput); - streamOutput.writeVInt(0); // no trial license - } else { - streamOutput.writeVInt(0); // no signed license - streamOutput.writeVInt(1); // one trial license - XContentBuilder contentBuilder = XContentFactory.contentBuilder(XContentType.JSON); - license.toXContent(contentBuilder, - new ToXContent.MapParams(Collections.singletonMap(License.LICENSE_SPEC_VIEW_MODE, "true"))); - streamOutput.writeString(Base64.getEncoder().encodeToString(encrypt(BytesReference.toBytes(contentBuilder.bytes())))); - } - } else { - if (license == LICENSE_TOMBSTONE) { - streamOutput.writeBoolean(false); // no license - } else { - streamOutput.writeBoolean(true); // has a license - license.writeTo(streamOutput); - } - } - } - - @Override - public LicensesMetaData readFrom(StreamInput streamInput) throws IOException { - License license = LICENSE_TOMBSTONE; - if (streamInput.getVersion().before(Version.V_2_0_0)) { - int size = streamInput.readVInt(); - List licenses = new ArrayList<>(); - for (int i = 0; i < size; i++) { - licenses.add(License.readLicense(streamInput)); - } - int numTrialLicenses = streamInput.readVInt(); - for (int i = 0; i < numTrialLicenses; i++) { - byte[] data = decrypt(Base64.getDecoder().decode(streamInput.readString())); - try (XContentParser trialLicenseParser = XContentFactory.xContent(XContentType.JSON).createParser(data)) { - trialLicenseParser.nextToken(); - License pre20TrialLicense = License.fromXContent(trialLicenseParser); - licenses.add(TrialLicense.create(License.builder().fromPre20LicenseSpec(pre20TrialLicense))); - } - } - // when we see read licenses from old pre v2.0, - // we try to choose the license that has the latest issue date that is not expired - CollectionUtil.timSort(licenses, License.LATEST_ISSUE_DATE_FIRST); - long now = System.currentTimeMillis(); - for (License oldLicense : licenses) { - if (oldLicense.expiryDate() > now) { - license = oldLicense; - break; - } - } - // take the best expired license - if (license == LICENSE_TOMBSTONE && !licenses.isEmpty()) { - license = licenses.get(0); - } - } else { - if (streamInput.readBoolean()) { - license = License.readLicense(streamInput); - } - } - return new LicensesMetaData(license); - } - - private static final class Fields { - private static final String SIGNED_LICENCES = "signed_licenses"; - private static final String TRIAL_LICENSES = "trial_licenses"; - private static final String LICENSE = "license"; - } -} diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/AbstractLicenseServiceTestCase.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/AbstractLicenseServiceTestCase.java similarity index 97% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/AbstractLicenseServiceTestCase.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/AbstractLicenseServiceTestCase.java index 4b524c85c85..7f3e247db92 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/AbstractLicenseServiceTestCase.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/AbstractLicenseServiceTestCase.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import org.elasticsearch.Version; import org.elasticsearch.cluster.ClusterName; @@ -17,7 +17,6 @@ import org.elasticsearch.common.component.Lifecycle; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.LocalTransportAddress; import org.elasticsearch.env.Environment; -import org.elasticsearch.license.core.License; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.xpack.support.clock.ClockMock; diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/AbstractLicensesIntegrationTestCase.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/AbstractLicensesIntegrationTestCase.java similarity index 96% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/AbstractLicensesIntegrationTestCase.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/AbstractLicensesIntegrationTestCase.java index b725ea31189..976cd4ee9b7 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/AbstractLicensesIntegrationTestCase.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/AbstractLicensesIntegrationTestCase.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin; +package org.elasticsearch.license; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.ClusterState; @@ -11,8 +11,6 @@ import org.elasticsearch.cluster.ClusterStateUpdateTask; import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.core.LicensesMetaData; import org.elasticsearch.xpack.monitoring.Monitoring; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.xpack.security.Security; diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/ExpirationCallbackTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/ExpirationCallbackTests.java similarity index 98% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/ExpirationCallbackTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/ExpirationCallbackTests.java index 0e5bc9c46a5..921ca45082a 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/ExpirationCallbackTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/ExpirationCallbackTests.java @@ -3,10 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.license.core.License; import org.elasticsearch.test.ESTestCase; import static org.elasticsearch.common.unit.TimeValue.timeValueMillis; diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseClusterChangeTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseClusterChangeTests.java similarity index 97% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseClusterChangeTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseClusterChangeTests.java index 1b4e6aac870..fe85d691d0a 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseClusterChangeTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseClusterChangeTests.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import org.elasticsearch.Version; import org.elasticsearch.cluster.ClusterChangedEvent; @@ -15,7 +15,6 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNodes; import org.elasticsearch.common.transport.LocalTransportAddress; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.license.core.License; import org.junit.After; import org.junit.Before; import org.mockito.ArgumentCaptor; diff --git a/elasticsearch/license/base/src/test/java/org/elasticsearch/license/core/LicenseOperationModeTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseOperationModeTests.java similarity index 95% rename from elasticsearch/license/base/src/test/java/org/elasticsearch/license/core/LicenseOperationModeTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseOperationModeTests.java index 6947a515298..e803d8772f0 100644 --- a/elasticsearch/license/base/src/test/java/org/elasticsearch/license/core/LicenseOperationModeTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseOperationModeTests.java @@ -3,13 +3,13 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.core; +package org.elasticsearch.license; import org.elasticsearch.test.ESTestCase; import java.util.Locale; -import static org.elasticsearch.license.core.License.OperationMode; +import static org.elasticsearch.license.License.OperationMode; import static org.hamcrest.Matchers.equalTo; /** diff --git a/elasticsearch/license/base/src/test/java/org/elasticsearch/license/core/LicenseOperationModeUpdateTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseOperationModeUpdateTests.java similarity index 92% rename from elasticsearch/license/base/src/test/java/org/elasticsearch/license/core/LicenseOperationModeUpdateTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseOperationModeUpdateTests.java index 8bd379862cc..a6933128791 100644 --- a/elasticsearch/license/base/src/test/java/org/elasticsearch/license/core/LicenseOperationModeUpdateTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseOperationModeUpdateTests.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.core; +package org.elasticsearch.license; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.watcher.FileWatcher; @@ -12,7 +12,6 @@ import org.junit.Before; import java.nio.file.Path; -import static org.elasticsearch.license.core.OperationModeFileWatcherTests.writeMode; import static org.hamcrest.Matchers.equalTo; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; @@ -47,7 +46,7 @@ public class LicenseOperationModeUpdateTests extends ESTestCase { .build(); assertThat(license.operationMode(), equalTo(License.OperationMode.resolve(type))); - writeMode("gold", licenseModeFile); + OperationModeFileWatcherTests.writeMode("gold", licenseModeFile); license.setOperationModeFileWatcher(operationModeFileWatcher); verifyZeroInteractions(resourceWatcherService); assertThat(license.operationMode(), equalTo(License.OperationMode.resolve(type))); @@ -65,7 +64,7 @@ public class LicenseOperationModeUpdateTests extends ESTestCase { .build(); assertThat(license.operationMode(), equalTo(License.OperationMode.PLATINUM)); - writeMode("gold", licenseModeFile); + OperationModeFileWatcherTests.writeMode("gold", licenseModeFile); license.setOperationModeFileWatcher(operationModeFileWatcher); verify(resourceWatcherService, times(1)).add(any(FileWatcher.class), eq(ResourceWatcherService.Frequency.HIGH)); assertThat(license.operationMode(), equalTo(License.OperationMode.GOLD)); diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseRegistrationTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseRegistrationTests.java similarity index 92% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseRegistrationTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseRegistrationTests.java index 577d2a6df01..fc2b3f47edc 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseRegistrationTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseRegistrationTests.java @@ -3,16 +3,14 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ClusterStateUpdateTask; -import org.elasticsearch.common.unit.TimeValue; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; -import static org.hamcrest.Matchers.equalTo; import static org.mockito.Matchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseScheduleTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseScheduleTests.java similarity index 95% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseScheduleTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseScheduleTests.java index 37113016360..844b14dd676 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseScheduleTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseScheduleTests.java @@ -3,10 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.license.core.License; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.scheduler.SchedulerEngine; import org.junit.Before; diff --git a/elasticsearch/license/base/src/test/java/org/elasticsearch/license/core/LicenseSerializationTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseSerializationTests.java similarity index 99% rename from elasticsearch/license/base/src/test/java/org/elasticsearch/license/core/LicenseSerializationTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseSerializationTests.java index c79ae1df6bc..31d869d9c9b 100644 --- a/elasticsearch/license/base/src/test/java/org/elasticsearch/license/core/LicenseSerializationTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseSerializationTests.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.core; +package org.elasticsearch.license; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseServiceClusterTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseServiceClusterTests.java similarity index 93% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseServiceClusterTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseServiceClusterTests.java index ffd83337399..96a373603e7 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseServiceClusterTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseServiceClusterTests.java @@ -3,15 +3,12 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.env.Environment; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.AbstractLicensesIntegrationTestCase; -import org.elasticsearch.license.plugin.LicensingClient; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.xpack.MockNetty3Plugin; @@ -23,7 +20,7 @@ import java.nio.file.Path; import java.util.Arrays; import java.util.Collection; -import static org.elasticsearch.license.plugin.core.TestUtils.generateSignedLicense; +import static org.elasticsearch.license.TestUtils.generateSignedLicense; import static org.elasticsearch.test.ESIntegTestCase.Scope.TEST; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.nullValue; @@ -71,7 +68,7 @@ public class LicenseServiceClusterTests extends AbstractLicensesIntegrationTestC logger.info("--> put signed license"); LicensingClient licensingClient = new LicensingClient(client()); - License license = generateSignedLicense(TimeValue.timeValueMinutes(1)); + License license = TestUtils.generateSignedLicense(TimeValue.timeValueMinutes(1)); putLicense(license); assertThat(licensingClient.prepareGetLicense().get().license(), equalTo(license)); assertOperationMode(license.operationMode()); @@ -109,7 +106,7 @@ public class LicenseServiceClusterTests extends AbstractLicensesIntegrationTestC logger.info("--> put signed license"); LicensingClient licensingClient = new LicensingClient(client()); - License license = generateSignedLicense("cloud_internal", License.VERSION_CURRENT, System.currentTimeMillis(), + License license = TestUtils.generateSignedLicense("cloud_internal", License.VERSION_CURRENT, System.currentTimeMillis(), TimeValue.timeValueMinutes(1)); putLicense(license); assertThat(licensingClient.prepareGetLicense().get().license(), equalTo(license)); diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicenseTribeTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseTribeTests.java similarity index 71% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicenseTribeTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseTribeTests.java index 663c57b8166..812214d1cc6 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicenseTribeTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseTribeTests.java @@ -3,19 +3,12 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin; +package org.elasticsearch.license; import org.elasticsearch.client.Client; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.license.plugin.action.delete.DeleteLicenseAction; -import org.elasticsearch.license.plugin.action.delete.DeleteLicenseRequest; -import org.elasticsearch.license.plugin.action.get.GetLicenseAction; -import org.elasticsearch.license.plugin.action.get.GetLicenseRequest; -import org.elasticsearch.license.plugin.action.put.PutLicenseAction; -import org.elasticsearch.license.plugin.action.put.PutLicenseRequest; -import org.elasticsearch.xpack.TribeTransportTestCase; -import static org.elasticsearch.license.plugin.core.TestUtils.generateSignedLicense; +import static org.elasticsearch.license.TestUtils.generateSignedLicense; public class LicenseTribeTests extends TribeTransportTestCase { diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseUtilsTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseUtilsTests.java similarity index 97% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseUtilsTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseUtilsTests.java index 73c69b6660b..ab063c0949c 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseUtilsTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicenseUtilsTests.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.test.ESTestCase; diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesAcknowledgementTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicensesAcknowledgementTests.java similarity index 88% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesAcknowledgementTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicensesAcknowledgementTests.java index c5a6855b731..faf468eef07 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesAcknowledgementTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicensesAcknowledgementTests.java @@ -3,16 +3,13 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import org.elasticsearch.action.ActionListener; import org.elasticsearch.cluster.ClusterStateUpdateTask; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.action.put.PutLicenseRequest; -import org.elasticsearch.license.plugin.action.put.PutLicenseResponse; -import static org.elasticsearch.license.plugin.core.TestUtils.generateSignedLicense; +import static org.elasticsearch.license.TestUtils.generateSignedLicense; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; import static org.mockito.Matchers.any; @@ -27,7 +24,7 @@ public class LicensesAcknowledgementTests extends AbstractLicenseServiceTestCase setInitialState(TestUtils.generateSignedLicense("trial", TimeValue.timeValueHours(2)), licenseState); licenseService.start(); // try installing a signed license - License signedLicense = generateSignedLicense("basic", TimeValue.timeValueHours(10)); + License signedLicense = TestUtils.generateSignedLicense("basic", TimeValue.timeValueHours(10)); PutLicenseRequest putLicenseRequest = new PutLicenseRequest().license(signedLicense); // ensure acknowledgement message was part of the response licenseService.registerLicense(putLicenseRequest, new AssertingLicensesUpdateResponse(false, LicensesStatus.VALID, true)); diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesManagerServiceTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicensesManagerServiceTests.java similarity index 86% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesManagerServiceTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicensesManagerServiceTests.java index 260135b764a..83706610731 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesManagerServiceTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicensesManagerServiceTests.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import java.util.Collection; import java.util.Collections; @@ -15,8 +15,6 @@ import org.elasticsearch.cluster.ack.ClusterStateUpdateResponse; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.action.delete.DeleteLicenseRequest; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.test.ESSingleNodeTestCase; import org.elasticsearch.xpack.XPackPlugin; @@ -25,7 +23,7 @@ import org.elasticsearch.xpack.monitoring.Monitoring; import org.elasticsearch.xpack.security.Security; import org.elasticsearch.xpack.watcher.Watcher; -import static org.elasticsearch.license.plugin.core.TestUtils.generateSignedLicense; +import static org.elasticsearch.license.TestUtils.generateSignedLicense; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; @@ -56,13 +54,13 @@ public class LicensesManagerServiceTests extends ESSingleNodeTestCase { public void testStoreAndGetLicenses() throws Exception { LicenseService licenseService = getInstanceFromNode(LicenseService.class); ClusterService clusterService = getInstanceFromNode(ClusterService.class); - License goldLicense = generateSignedLicense("gold", TimeValue.timeValueHours(1)); + License goldLicense = TestUtils.generateSignedLicense("gold", TimeValue.timeValueHours(1)); TestUtils.registerAndAckSignedLicenses(licenseService, goldLicense, LicensesStatus.VALID); - License silverLicense = generateSignedLicense("silver", TimeValue.timeValueHours(2)); + License silverLicense = TestUtils.generateSignedLicense("silver", TimeValue.timeValueHours(2)); TestUtils.registerAndAckSignedLicenses(licenseService, silverLicense, LicensesStatus.VALID); - License platinumLicense = generateSignedLicense("platinum", TimeValue.timeValueHours(1)); + License platinumLicense = TestUtils.generateSignedLicense("platinum", TimeValue.timeValueHours(1)); TestUtils.registerAndAckSignedLicenses(licenseService, platinumLicense, LicensesStatus.VALID); - License basicLicense = generateSignedLicense("basic", TimeValue.timeValueHours(3)); + License basicLicense = TestUtils.generateSignedLicense("basic", TimeValue.timeValueHours(3)); TestUtils.registerAndAckSignedLicenses(licenseService, basicLicense, LicensesStatus.VALID); LicensesMetaData licensesMetaData = clusterService.state().metaData().custom(LicensesMetaData.TYPE); assertThat(licensesMetaData.getLicense(), equalTo(basicLicense)); @@ -73,19 +71,19 @@ public class LicensesManagerServiceTests extends ESSingleNodeTestCase { public void testEffectiveLicenses() throws Exception { final LicenseService licenseService = getInstanceFromNode(LicenseService.class); final ClusterService clusterService = getInstanceFromNode(ClusterService.class); - License goldLicense = generateSignedLicense("gold", TimeValue.timeValueSeconds(5)); + License goldLicense = TestUtils.generateSignedLicense("gold", TimeValue.timeValueSeconds(5)); // put gold license TestUtils.registerAndAckSignedLicenses(licenseService, goldLicense, LicensesStatus.VALID); LicensesMetaData licensesMetaData = clusterService.state().metaData().custom(LicensesMetaData.TYPE); assertThat(licenseService.getLicense(licensesMetaData), equalTo(goldLicense)); - License platinumLicense = generateSignedLicense("platinum", TimeValue.timeValueSeconds(3)); + License platinumLicense = TestUtils.generateSignedLicense("platinum", TimeValue.timeValueSeconds(3)); // put platinum license TestUtils.registerAndAckSignedLicenses(licenseService, platinumLicense, LicensesStatus.VALID); licensesMetaData = clusterService.state().metaData().custom(LicensesMetaData.TYPE); assertThat(licenseService.getLicense(licensesMetaData), equalTo(platinumLicense)); - License basicLicense = generateSignedLicense("basic", TimeValue.timeValueSeconds(3)); + License basicLicense = TestUtils.generateSignedLicense("basic", TimeValue.timeValueSeconds(3)); // put basic license TestUtils.registerAndAckSignedLicenses(licenseService, basicLicense, LicensesStatus.VALID); licensesMetaData = clusterService.state().metaData().custom(LicensesMetaData.TYPE); @@ -95,7 +93,7 @@ public class LicensesManagerServiceTests extends ESSingleNodeTestCase { public void testInvalidLicenseStorage() throws Exception { LicenseService licenseService = getInstanceFromNode(LicenseService.class); ClusterService clusterService = getInstanceFromNode(ClusterService.class); - License signedLicense = generateSignedLicense(TimeValue.timeValueMinutes(2)); + License signedLicense = TestUtils.generateSignedLicense(TimeValue.timeValueMinutes(2)); // modify content of signed license License tamperedLicense = License.builder() @@ -116,7 +114,7 @@ public class LicensesManagerServiceTests extends ESSingleNodeTestCase { ClusterService clusterService = getInstanceFromNode(ClusterService.class); // generate signed licenses - License license = generateSignedLicense(TimeValue.timeValueHours(1)); + License license = TestUtils.generateSignedLicense(TimeValue.timeValueHours(1)); TestUtils.registerAndAckSignedLicenses(licenseService, license, LicensesStatus.VALID); LicensesMetaData licensesMetaData = clusterService.state().metaData().custom(LicensesMetaData.TYPE); assertThat(licensesMetaData.getLicense(), not(LicensesMetaData.LICENSE_TOMBSTONE)); diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicensesMetaDataSerializationTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicensesMetaDataSerializationTests.java new file mode 100644 index 00000000000..18cbe641463 --- /dev/null +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicensesMetaDataSerializationTests.java @@ -0,0 +1,105 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.license; + +import org.elasticsearch.cluster.metadata.MetaData; +import org.elasticsearch.cluster.metadata.RepositoriesMetaData; +import org.elasticsearch.cluster.metadata.RepositoryMetaData; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.ToXContent.Params; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.test.ESTestCase; + +import java.util.Collections; +import java.util.UUID; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; + +public class LicensesMetaDataSerializationTests extends ESTestCase { + public void testXContentSerializationOneSignedLicense() throws Exception { + License license = TestUtils.generateSignedLicense(TimeValue.timeValueHours(2)); + LicensesMetaData licensesMetaData = new LicensesMetaData(license); + XContentBuilder builder = XContentFactory.jsonBuilder(); + builder.startObject("licenses"); + licensesMetaData.toXContent(builder, ToXContent.EMPTY_PARAMS); + builder.endObject(); + LicensesMetaData licensesMetaDataFromXContent = getLicensesMetaDataFromXContent(builder.bytes()); + assertThat(licensesMetaDataFromXContent.getLicense(), equalTo(license)); + } + + public void testLicenseMetadataParsingDoesNotSwallowOtherMetaData() throws Exception { + new Licensing(Settings.EMPTY); // makes sure LicensePlugin is registered in Custom MetaData + License license = TestUtils.generateSignedLicense(TimeValue.timeValueHours(2)); + LicensesMetaData licensesMetaData = new LicensesMetaData(license); + RepositoryMetaData repositoryMetaData = new RepositoryMetaData("repo", "fs", Settings.EMPTY); + RepositoriesMetaData repositoriesMetaData = new RepositoriesMetaData(repositoryMetaData); + final MetaData.Builder metaDataBuilder = MetaData.builder(); + if (randomBoolean()) { // random order of insertion + metaDataBuilder.putCustom(licensesMetaData.type(), licensesMetaData); + metaDataBuilder.putCustom(repositoriesMetaData.type(), repositoriesMetaData); + } else { + metaDataBuilder.putCustom(repositoriesMetaData.type(), repositoriesMetaData); + metaDataBuilder.putCustom(licensesMetaData.type(), licensesMetaData); + } + // serialize metadata + XContentBuilder builder = XContentFactory.jsonBuilder(); + Params params = new ToXContent.MapParams(Collections.singletonMap(MetaData.CONTEXT_MODE_PARAM, MetaData.CONTEXT_MODE_GATEWAY)); + builder.startObject(); + builder = metaDataBuilder.build().toXContent(builder, params); + builder.endObject(); + String serializedMetaData = builder.string(); + // deserialize metadata again + MetaData metaData = MetaData.Builder.fromXContent(XContentFactory.xContent(XContentType.JSON).createParser(serializedMetaData)); + // check that custom metadata still present + assertThat(metaData.custom(licensesMetaData.type()), notNullValue()); + assertThat(metaData.custom(repositoriesMetaData.type()), notNullValue()); + } + + public void testXContentSerializationOneTrial() throws Exception { + long issueDate = System.currentTimeMillis(); + License.Builder specBuilder = License.builder() + .uid(UUID.randomUUID().toString()) + .issuedTo("customer") + .maxNodes(5) + .issueDate(issueDate) + .expiryDate(issueDate + TimeValue.timeValueHours(2).getMillis()); + final License trialLicense = TrialLicense.create(specBuilder); + LicensesMetaData licensesMetaData = new LicensesMetaData(trialLicense); + XContentBuilder builder = XContentFactory.jsonBuilder(); + builder.startObject("licenses"); + licensesMetaData.toXContent(builder, ToXContent.EMPTY_PARAMS); + builder.endObject(); + LicensesMetaData licensesMetaDataFromXContent = getLicensesMetaDataFromXContent(builder.bytes()); + assertThat(licensesMetaDataFromXContent.getLicense(), equalTo(trialLicense)); + } + + public void testLicenseTombstoneFromXContext() throws Exception { + final XContentBuilder builder = XContentFactory.jsonBuilder(); + builder.startObject("licenses"); + builder.nullField("license"); + builder.endObject(); + LicensesMetaData metaDataFromXContent = getLicensesMetaDataFromXContent(builder.bytes()); + assertThat(metaDataFromXContent.getLicense(), equalTo(LicensesMetaData.LICENSE_TOMBSTONE)); + } + + private static LicensesMetaData getLicensesMetaDataFromXContent(BytesReference bytes) throws Exception { + final XContentParser parser = XContentFactory.xContent(XContentType.JSON).createParser(bytes); + parser.nextToken(); // consume null + parser.nextToken(); // consume "licenses" + LicensesMetaData licensesMetaDataFromXContent = LicensesMetaData.PROTO.fromXContent(parser); + parser.nextToken(); // consume endObject + assertThat(parser.nextToken(), nullValue()); + return licensesMetaDataFromXContent; + } +} diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicensesTransportTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicensesTransportTests.java similarity index 89% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicensesTransportTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicensesTransportTests.java index 0c83cfc45a4..00155d4bfd4 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicensesTransportTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/LicensesTransportTests.java @@ -3,23 +3,11 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin; +package org.elasticsearch.license; import org.elasticsearch.action.ActionFuture; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.action.delete.DeleteLicenseAction; -import org.elasticsearch.license.plugin.action.delete.DeleteLicenseRequestBuilder; -import org.elasticsearch.license.plugin.action.delete.DeleteLicenseResponse; -import org.elasticsearch.license.plugin.action.get.GetLicenseAction; -import org.elasticsearch.license.plugin.action.get.GetLicenseRequestBuilder; -import org.elasticsearch.license.plugin.action.get.GetLicenseResponse; -import org.elasticsearch.license.plugin.action.put.PutLicenseAction; -import org.elasticsearch.license.plugin.action.put.PutLicenseRequestBuilder; -import org.elasticsearch.license.plugin.action.put.PutLicenseResponse; -import org.elasticsearch.license.plugin.core.LicensesStatus; -import org.elasticsearch.license.plugin.core.TestUtils; import org.elasticsearch.xpack.monitoring.Monitoring; import org.elasticsearch.node.Node; import org.elasticsearch.plugins.Plugin; @@ -31,8 +19,8 @@ import org.elasticsearch.xpack.watcher.Watcher; import java.util.Collection; import java.util.Collections; -import static org.elasticsearch.license.plugin.core.TestUtils.generateExpiredLicense; -import static org.elasticsearch.license.plugin.core.TestUtils.generateSignedLicense; +import static org.elasticsearch.license.TestUtils.generateExpiredLicense; +import static org.elasticsearch.license.TestUtils.generateSignedLicense; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.not; diff --git a/elasticsearch/license/base/src/test/java/org/elasticsearch/license/core/OperationModeFileWatcherTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/OperationModeFileWatcherTests.java similarity index 99% rename from elasticsearch/license/base/src/test/java/org/elasticsearch/license/core/OperationModeFileWatcherTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/OperationModeFileWatcherTests.java index a51ea032c91..71868fd85df 100644 --- a/elasticsearch/license/base/src/test/java/org/elasticsearch/license/core/OperationModeFileWatcherTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/OperationModeFileWatcherTests.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.core; +package org.elasticsearch.license; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.test.ESTestCase; diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/PutLicenseResponseTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/PutLicenseResponseTests.java similarity index 96% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/PutLicenseResponseTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/PutLicenseResponseTests.java index 13d6d8b04fc..a9805f43d0d 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/PutLicenseResponseTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/PutLicenseResponseTests.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin; +package org.elasticsearch.license; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.StreamInput; @@ -11,8 +11,6 @@ import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentHelper; -import org.elasticsearch.license.plugin.action.put.PutLicenseResponse; -import org.elasticsearch.license.plugin.core.LicensesStatus; import org.elasticsearch.test.ESTestCase; import java.io.IOException; diff --git a/elasticsearch/license/base/src/test/java/org/elasticsearch/license/core/TestUtils.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/TestUtils.java similarity index 51% rename from elasticsearch/license/base/src/test/java/org/elasticsearch/license/core/TestUtils.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/TestUtils.java index d2b8e998e43..a871dfdc181 100644 --- a/elasticsearch/license/base/src/test/java/org/elasticsearch/license/core/TestUtils.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/TestUtils.java @@ -3,25 +3,43 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.core; +package org.elasticsearch.license; +import com.carrotsearch.randomizedtesting.RandomizedTest; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.common.io.PathUtils; import org.elasticsearch.common.joda.DateMathParser; import org.elasticsearch.common.joda.FormatDateTimeFormatter; import org.elasticsearch.common.joda.Joda; +import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.license.licensor.LicenseSigner; import org.hamcrest.MatcherAssert; import org.joda.time.format.DateTimeFormatter; +import org.junit.Assert; import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; import static com.carrotsearch.randomizedtesting.RandomizedTest.randomBoolean; import static com.carrotsearch.randomizedtesting.RandomizedTest.randomInt; -import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; +import static org.elasticsearch.test.ESTestCase.assertNotNull; +import static org.elasticsearch.test.ESTestCase.awaitBusy; +import static org.elasticsearch.test.ESTestCase.randomAsciiOfLength; import static org.elasticsearch.test.ESTestCase.randomFrom; +import static org.elasticsearch.test.ESTestCase.randomIntBetween; import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; public class TestUtils { @@ -63,12 +81,12 @@ public class TestUtils { subscriptionType = null; type = randomFrom("basic", "dev", "gold", "silver", "platinum"); } - int maxNodes = randomIntBetween(5, 100); + int maxNodes = RandomizedTest.randomIntBetween(5, 100); if (datesInMillis) { long issueDateInMillis = dateMath("now", now); long expiryDateInMillis = dateMath("now+10d/d", now); return new LicenseSpec(version, uid, feature, issueDateInMillis, expiryDateInMillis, type, subscriptionType, issuedTo, issuer, - maxNodes); + maxNodes); } else { String issueDate = dateMathString("now", now); String expiryDate = dateMathString("now+10d/d", now); @@ -81,13 +99,13 @@ public class TestUtils { licenses.startObject(); licenses.startArray("licenses"); licenses.startObject() - .field("uid", licenseSpec.uid) - .field("type", licenseSpec.type) - .field("subscription_type", licenseSpec.subscriptionType) - .field("issued_to", licenseSpec.issuedTo) - .field("issuer", licenseSpec.issuer) - .field("feature", licenseSpec.feature) - .field("max_nodes", licenseSpec.maxNodes); + .field("uid", licenseSpec.uid) + .field("type", licenseSpec.type) + .field("subscription_type", licenseSpec.subscriptionType) + .field("issued_to", licenseSpec.issuedTo) + .field("issuer", licenseSpec.issuer) + .field("feature", licenseSpec.feature) + .field("max_nodes", licenseSpec.maxNodes); if (licenseSpec.issueDate != null) { licenses.field("issue_date", licenseSpec.issueDate); @@ -108,13 +126,13 @@ public class TestUtils { public static License generateLicenses(LicenseSpec spec) { License.Builder builder = License.builder() - .uid(spec.uid) - .feature(spec.feature) - .type(spec.type) - .subscriptionType(spec.subscriptionType) - .issuedTo(spec.issuedTo) - .issuer(spec.issuer) - .maxNodes(spec.maxNodes); + .uid(spec.uid) + .feature(spec.feature) + .type(spec.type) + .subscriptionType(spec.subscriptionType) + .issuedTo(spec.issuedTo) + .issuer(spec.issuer) + .maxNodes(spec.maxNodes); if (spec.expiryDate != null) { builder.expiryDate(DateUtils.endOfTheDay(spec.expiryDate)); @@ -163,7 +181,7 @@ public class TestUtils { public LicenseSpec(String issueDate, String expiryDate) { this(License.VERSION_CURRENT, UUID.randomUUID().toString(), "feature", issueDate, expiryDate, "trial", "none", "customer", - "elasticsearch", 5); + "elasticsearch", 5); } public LicenseSpec(int version, String uid, String feature, long issueDateInMillis, long expiryDateInMillis, String type, @@ -198,4 +216,130 @@ public class TestUtils { this.maxNodes = maxNodes; } } + + public static Path getTestPriKeyPath() throws Exception { + return getResourcePath("/private.key"); + } + + public static Path getTestPubKeyPath() throws Exception { + return getResourcePath("/public.key"); + } + + public static String dumpLicense(License license) throws Exception { + XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON); + builder.startObject(); + builder.startObject("license"); + license.toInnerXContent(builder, ToXContent.EMPTY_PARAMS); + builder.endObject(); + builder.endObject(); + return builder.string(); + } + + public static License generateSignedLicense(TimeValue expiryDuration) throws Exception { + return generateSignedLicense(null, -1, expiryDuration); + } + + public static License generateSignedLicense(String type, TimeValue expiryDuration) throws Exception { + return generateSignedLicense(type, -1, expiryDuration); + } + + public static License generateSignedLicense(long issueDate, TimeValue expiryDuration) throws Exception { + return generateSignedLicense(null, issueDate, expiryDuration); + } + + public static License generateSignedLicense(String type, long issueDate, TimeValue expiryDuration) throws Exception { + return generateSignedLicense(type, randomIntBetween(License.VERSION_START, License.VERSION_CURRENT), issueDate, expiryDuration); + } + + public static License generateSignedLicense(String type, int version, long issueDate, TimeValue expiryDuration) throws Exception { + long issue = (issueDate != -1L) ? issueDate : System.currentTimeMillis() - TimeValue.timeValueHours(2).getMillis(); + final String licenseType; + if (version < License.VERSION_NO_FEATURE_TYPE) { + licenseType = randomFrom("subscription", "internal", "development"); + } else { + licenseType = (type != null) ? type : randomFrom("basic", "silver", "dev", "gold", "platinum"); + } + final License.Builder builder = License.builder() + .uid(UUID.randomUUID().toString()) + .version(version) + .expiryDate(System.currentTimeMillis() + expiryDuration.getMillis()) + .issueDate(issue) + .type(licenseType) + .issuedTo("customer") + .issuer("elasticsearch") + .maxNodes(5); + if (version == License.VERSION_START) { + builder.subscriptionType((type != null) ? type : randomFrom("dev", "gold", "platinum", "silver")); + builder.feature(randomAsciiOfLength(10)); + } + LicenseSigner signer = new LicenseSigner(getTestPriKeyPath(), getTestPubKeyPath()); + return signer.sign(builder.build()); + } + + public static License generateExpiredLicense(long expiryDate) throws Exception { + return generateExpiredLicense(randomFrom("basic", "silver", "dev", "gold", "platinum"), expiryDate); + } + + public static License generateExpiredLicense() throws Exception { + return generateExpiredLicense(randomFrom("basic", "silver", "dev", "gold", "platinum")); + } + + public static License generateExpiredLicense(String type) throws Exception { + return generateExpiredLicense(type, + System.currentTimeMillis() - TimeValue.timeValueHours(randomIntBetween(1, 10)).getMillis()); + } + + public static License generateExpiredLicense(String type, long expiryDate) throws Exception { + final License.Builder builder = License.builder() + .uid(UUID.randomUUID().toString()) + .version(License.VERSION_CURRENT) + .expiryDate(expiryDate) + .issueDate(expiryDate - TimeValue.timeValueMinutes(10).getMillis()) + .type(type) + .issuedTo("customer") + .issuer("elasticsearch") + .maxNodes(5); + LicenseSigner signer = new LicenseSigner(getTestPriKeyPath(), getTestPubKeyPath()); + return signer.sign(builder.build()); + } + + private static Path getResourcePath(String resource) throws Exception { + return PathUtils.get(TestUtils.class.getResource(resource).toURI()); + } + + public static void registerAndAckSignedLicenses(final LicenseService licenseService, License license, + final LicensesStatus expectedStatus) { + PutLicenseRequest putLicenseRequest = new PutLicenseRequest().license(license).acknowledge(true); + final CountDownLatch latch = new CountDownLatch(1); + final AtomicReference status = new AtomicReference<>(); + licenseService.registerLicense(putLicenseRequest, new ActionListener() { + @Override + public void onResponse(PutLicenseResponse licensesUpdateResponse) { + status.set(licensesUpdateResponse.status()); + latch.countDown(); + } + + @Override + public void onFailure(Exception e) { + latch.countDown(); + } + }); + try { + latch.await(); + } catch (InterruptedException e) { + Assert.fail(e.getMessage()); + } + assertThat(status.get(), equalTo(expectedStatus)); + } + + public static class AssertingLicenseState extends XPackLicenseState { + public final List modeUpdates = new ArrayList<>(); + public final List activeUpdates = new ArrayList<>(); + + @Override + void update(License.OperationMode mode, boolean active) { + modeUpdates.add(mode); + activeUpdates.add(active); + } + } } diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/TrialLicenseTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/TrialLicenseTests.java similarity index 95% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/TrialLicenseTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/TrialLicenseTests.java index 26c34df6483..9d68dc092a5 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/TrialLicenseTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/TrialLicenseTests.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin; +package org.elasticsearch.license; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.unit.TimeValue; @@ -11,8 +11,6 @@ import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.core.TrialLicense; import org.elasticsearch.test.ESTestCase; import java.io.IOException; @@ -21,7 +19,7 @@ import java.util.Base64; import java.util.Collections; import java.util.UUID; -import static org.elasticsearch.license.core.CryptUtils.encrypt; +import static org.elasticsearch.license.CryptUtils.encrypt; import static org.hamcrest.Matchers.equalTo; diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/xpack/TribeTransportTestCase.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/TribeTransportTestCase.java similarity index 99% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/xpack/TribeTransportTestCase.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/TribeTransportTestCase.java index f6bc9baa3fa..004e49370ce 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/xpack/TribeTransportTestCase.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/TribeTransportTestCase.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack; +package org.elasticsearch.license; import org.elasticsearch.action.Action; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; @@ -21,6 +21,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.discovery.DiscoveryModule; import org.elasticsearch.discovery.zen.ping.unicast.UnicastZenPing; +import org.elasticsearch.xpack.XPackPlugin; import org.elasticsearch.xpack.monitoring.Monitoring; import org.elasticsearch.node.Node; import org.elasticsearch.plugins.Plugin; diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesMetaDataSerializationTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesMetaDataSerializationTests.java deleted file mode 100644 index 4748ab9c065..00000000000 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesMetaDataSerializationTests.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.license.plugin.core; - -import org.elasticsearch.Version; -import org.elasticsearch.cluster.metadata.MetaData; -import org.elasticsearch.cluster.metadata.RepositoriesMetaData; -import org.elasticsearch.cluster.metadata.RepositoryMetaData; -import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.io.stream.BytesStreamOutput; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.common.xcontent.ToXContent; -import org.elasticsearch.common.xcontent.ToXContent.Params; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentFactory; -import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.Licensing; -import org.elasticsearch.test.ESTestCase; - -import java.util.Base64; -import java.util.Collections; -import java.util.UUID; - -import static org.elasticsearch.license.core.CryptUtils.encrypt; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; - -public class LicensesMetaDataSerializationTests extends ESTestCase { - public void testXContentSerializationOneSignedLicense() throws Exception { - License license = TestUtils.generateSignedLicense(TimeValue.timeValueHours(2)); - LicensesMetaData licensesMetaData = new LicensesMetaData(license); - XContentBuilder builder = XContentFactory.jsonBuilder(); - builder.startObject("licenses"); - licensesMetaData.toXContent(builder, ToXContent.EMPTY_PARAMS); - builder.endObject(); - LicensesMetaData licensesMetaDataFromXContent = getLicensesMetaDataFromXContent(builder.bytes()); - assertThat(licensesMetaDataFromXContent.getLicense(), equalTo(license)); - } - - public void testLicenseMetadataParsingDoesNotSwallowOtherMetaData() throws Exception { - new Licensing(Settings.EMPTY); // makes sure LicensePlugin is registered in Custom MetaData - License license = TestUtils.generateSignedLicense(TimeValue.timeValueHours(2)); - LicensesMetaData licensesMetaData = new LicensesMetaData(license); - RepositoryMetaData repositoryMetaData = new RepositoryMetaData("repo", "fs", Settings.EMPTY); - RepositoriesMetaData repositoriesMetaData = new RepositoriesMetaData(repositoryMetaData); - final MetaData.Builder metaDataBuilder = MetaData.builder(); - if (randomBoolean()) { // random order of insertion - metaDataBuilder.putCustom(licensesMetaData.type(), licensesMetaData); - metaDataBuilder.putCustom(repositoriesMetaData.type(), repositoriesMetaData); - } else { - metaDataBuilder.putCustom(repositoriesMetaData.type(), repositoriesMetaData); - metaDataBuilder.putCustom(licensesMetaData.type(), licensesMetaData); - } - // serialize metadata - XContentBuilder builder = XContentFactory.jsonBuilder(); - Params params = new ToXContent.MapParams(Collections.singletonMap(MetaData.CONTEXT_MODE_PARAM, MetaData.CONTEXT_MODE_GATEWAY)); - builder.startObject(); - builder = metaDataBuilder.build().toXContent(builder, params); - builder.endObject(); - String serializedMetaData = builder.string(); - // deserialize metadata again - MetaData metaData = MetaData.Builder.fromXContent(XContentFactory.xContent(XContentType.JSON).createParser(serializedMetaData)); - // check that custom metadata still present - assertThat(metaData.custom(licensesMetaData.type()), notNullValue()); - assertThat(metaData.custom(repositoriesMetaData.type()), notNullValue()); - } - - public void testXContentSerializationOneTrial() throws Exception { - long issueDate = System.currentTimeMillis(); - License.Builder specBuilder = License.builder() - .uid(UUID.randomUUID().toString()) - .issuedTo("customer") - .maxNodes(5) - .issueDate(issueDate) - .expiryDate(issueDate + TimeValue.timeValueHours(2).getMillis()); - final License trialLicense = TrialLicense.create(specBuilder); - LicensesMetaData licensesMetaData = new LicensesMetaData(trialLicense); - XContentBuilder builder = XContentFactory.jsonBuilder(); - builder.startObject("licenses"); - licensesMetaData.toXContent(builder, ToXContent.EMPTY_PARAMS); - builder.endObject(); - LicensesMetaData licensesMetaDataFromXContent = getLicensesMetaDataFromXContent(builder.bytes()); - assertThat(licensesMetaDataFromXContent.getLicense(), equalTo(trialLicense)); - } - - public void test1xLicensesMetaDataFromXContent() throws Exception { - License signedLicense = TestUtils.generateSignedLicense(TimeValue.timeValueHours(2)); - long issueDate = signedLicense.issueDate() - TimeValue.timeValueMillis(200).getMillis(); - License.Builder specBuilder = License.builder() - .uid(UUID.randomUUID().toString()) - .issuedTo("customer") - .maxNodes(5) - .issueDate(issueDate) - .expiryDate(issueDate + TimeValue.timeValueHours(2).getMillis()); - final License trialLicense = TrialLicense.create(specBuilder); - // trial license - XContentBuilder builder = XContentFactory.jsonBuilder(); - builder.startObject(); - builder.startObject("licenses"); - builder.startArray("trial_licenses"); - XContentBuilder contentBuilder = XContentFactory.contentBuilder(XContentType.JSON); - trialLicense.toXContent(contentBuilder, new ToXContent.MapParams(Collections.singletonMap(License.LICENSE_SPEC_VIEW_MODE, "true"))); - builder.value(Base64.getEncoder().encodeToString(encrypt(BytesReference.toBytes(contentBuilder.bytes())))); - builder.endArray(); - builder.startArray("signed_licenses"); - builder.endArray(); - builder.endObject(); - builder.endObject(); - LicensesMetaData licensesMetaDataFromXContent = getLicensesMetaDataFromXContent(builder.bytes()); - assertThat(licensesMetaDataFromXContent.getLicense(), equalTo(trialLicense)); - - // signed license - builder = XContentFactory.jsonBuilder(); - builder.startObject(); - builder.startObject("licenses"); - builder.startArray("trial_licenses"); - builder.endArray(); - builder.startArray("signed_licenses"); - signedLicense.toXContent(builder, ToXContent.EMPTY_PARAMS); - builder.endArray(); - builder.endObject(); - builder.endObject(); - licensesMetaDataFromXContent = getLicensesMetaDataFromXContent(builder.bytes()); - assertThat(licensesMetaDataFromXContent.getLicense(), equalTo(signedLicense)); - - // trial and signed license - builder = XContentFactory.jsonBuilder(); - builder.startObject(); - builder.startObject("licenses"); - builder.startArray("trial_licenses"); - contentBuilder = XContentFactory.contentBuilder(XContentType.JSON); - trialLicense.toXContent(contentBuilder, new ToXContent.MapParams(Collections.singletonMap(License.LICENSE_SPEC_VIEW_MODE, "true"))); - builder.value(Base64.getEncoder().encodeToString(encrypt(BytesReference.toBytes(contentBuilder.bytes())))); - builder.endArray(); - builder.startArray("signed_licenses"); - signedLicense.toXContent(builder, ToXContent.EMPTY_PARAMS); - builder.endArray(); - builder.endObject(); - builder.endObject(); - licensesMetaDataFromXContent = getLicensesMetaDataFromXContent(builder.bytes()); - assertThat(licensesMetaDataFromXContent.getLicense(), equalTo(signedLicense)); - - // license with later issue date is selected - long laterIssueDate = trialLicense.issueDate() + TimeValue.timeValueHours(2).getMillis(); - License signedLicenseIssuedLater = TestUtils.generateSignedLicense(laterIssueDate, TimeValue.timeValueHours(2)); - builder = XContentFactory.jsonBuilder(); - builder.startObject(); - builder.startObject("licenses"); - builder.startArray("trial_licenses"); - contentBuilder = XContentFactory.contentBuilder(XContentType.JSON); - trialLicense.toXContent(contentBuilder, new ToXContent.MapParams(Collections.singletonMap(License.LICENSE_SPEC_VIEW_MODE, "true"))); - builder.value(Base64.getEncoder().encodeToString(encrypt(BytesReference.toBytes(contentBuilder.bytes())))); - builder.endArray(); - builder.startArray("signed_licenses"); - signedLicense.toXContent(builder, ToXContent.EMPTY_PARAMS); - signedLicenseIssuedLater.toXContent(builder, ToXContent.EMPTY_PARAMS); - builder.endArray(); - builder.endObject(); - builder.endObject(); - licensesMetaDataFromXContent = getLicensesMetaDataFromXContent(builder.bytes()); - assertThat(licensesMetaDataFromXContent.getLicense(), equalTo(signedLicenseIssuedLater)); - - } - - public void test1xLicensesMetaDataFromStream() throws Exception { - long issueDate = System.currentTimeMillis(); - License.Builder specBuilder = License.builder() - .uid(UUID.randomUUID().toString()) - .issuedTo("customer") - .maxNodes(5) - .issueDate(issueDate) - .expiryDate(issueDate + TimeValue.timeValueHours(1).getMillis()); - final License trialLicense = TrialLicense.create(specBuilder); - // trial license - BytesStreamOutput output = new BytesStreamOutput(); - output.writeVInt(0); - output.writeVInt(1); - XContentBuilder contentBuilder = XContentFactory.contentBuilder(XContentType.JSON); - trialLicense.toXContent(contentBuilder, new ToXContent.MapParams(Collections.singletonMap(License.LICENSE_SPEC_VIEW_MODE, "true"))); - output.writeString(Base64.getEncoder().encodeToString(encrypt(BytesReference.toBytes(contentBuilder.bytes())))); - try (StreamInput input = output.bytes().streamInput()) { - input.setVersion(Version.V_2_0_0_beta1); - LicensesMetaData licensesMetaData = LicensesMetaData.PROTO.readFrom(input); - assertThat(licensesMetaData.getLicense(), equalTo(trialLicense)); - } - - // signed license - License signedLicense = TestUtils.generateSignedLicense(TimeValue.timeValueHours(2)); - output = new BytesStreamOutput(); - output.writeVInt(1); - signedLicense.writeTo(output); - output.writeVInt(0); - try (StreamInput input = output.bytes().streamInput()) { - input.setVersion(Version.V_2_0_0_beta1); - LicensesMetaData licensesMetaData = LicensesMetaData.PROTO.readFrom(input); - assertThat(licensesMetaData.getLicense(), equalTo(signedLicense)); - } - } - - public void testLicenseTombstoneFromXContext() throws Exception { - final XContentBuilder builder = XContentFactory.jsonBuilder(); - builder.startObject("licenses"); - builder.nullField("license"); - builder.endObject(); - LicensesMetaData metaDataFromXContent = getLicensesMetaDataFromXContent(builder.bytes()); - assertThat(metaDataFromXContent.getLicense(), equalTo(LicensesMetaData.LICENSE_TOMBSTONE)); - } - - private static LicensesMetaData getLicensesMetaDataFromXContent(BytesReference bytes) throws Exception { - final XContentParser parser = XContentFactory.xContent(XContentType.JSON).createParser(bytes); - parser.nextToken(); // consume null - parser.nextToken(); // consume "licenses" - LicensesMetaData licensesMetaDataFromXContent = LicensesMetaData.PROTO.fromXContent(parser); - parser.nextToken(); // consume endObject - assertThat(parser.nextToken(), nullValue()); - return licensesMetaDataFromXContent; - } -} diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/TestUtils.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/TestUtils.java deleted file mode 100644 index 2a1f6350adf..00000000000 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/TestUtils.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.license.plugin.core; - -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.common.collect.Tuple; -import org.elasticsearch.common.io.PathUtils; -import org.elasticsearch.common.joda.DateMathParser; -import org.elasticsearch.common.joda.FormatDateTimeFormatter; -import org.elasticsearch.common.joda.Joda; -import org.elasticsearch.common.logging.ESLogger; -import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.common.xcontent.ToXContent; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentFactory; -import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.licensor.LicenseSigner; -import org.elasticsearch.license.plugin.action.put.PutLicenseRequest; -import org.elasticsearch.license.plugin.action.put.PutLicenseResponse; -import org.junit.Assert; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -import static org.elasticsearch.test.ESTestCase.assertNotNull; -import static org.elasticsearch.test.ESTestCase.awaitBusy; -import static org.elasticsearch.test.ESTestCase.randomAsciiOfLength; -import static org.elasticsearch.test.ESTestCase.randomFrom; -import static org.elasticsearch.test.ESTestCase.randomIntBetween; -import static org.hamcrest.core.IsEqual.equalTo; -import static org.junit.Assert.assertThat; - -public class TestUtils { - - private static final FormatDateTimeFormatter formatDateTimeFormatter = Joda.forPattern("yyyy-MM-dd"); - private static final DateMathParser dateMathParser = new DateMathParser(formatDateTimeFormatter); - - public static long dateMath(String time, final long now) { - return dateMathParser.parse(time, new Callable() { - @Override - public Long call() throws Exception { - return now; - } - }); - } - public static Path getTestPriKeyPath() throws Exception { - return getResourcePath("/private.key"); - } - - public static Path getTestPubKeyPath() throws Exception { - return getResourcePath("/public.key"); - } - - public static String dumpLicense(License license) throws Exception { - XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON); - builder.startObject(); - builder.startObject("license"); - license.toInnerXContent(builder, ToXContent.EMPTY_PARAMS); - builder.endObject(); - builder.endObject(); - return builder.string(); - } - - public static License generateSignedLicense(TimeValue expiryDuration) throws Exception { - return generateSignedLicense(null, -1, expiryDuration); - } - - public static License generateSignedLicense(String type, TimeValue expiryDuration) throws Exception { - return generateSignedLicense(type, -1, expiryDuration); - } - - public static License generateSignedLicense(long issueDate, TimeValue expiryDuration) throws Exception { - return generateSignedLicense(null, issueDate, expiryDuration); - } - - public static License generateSignedLicense(String type, long issueDate, TimeValue expiryDuration) throws Exception { - return generateSignedLicense(type, randomIntBetween(License.VERSION_START, License.VERSION_CURRENT), issueDate, expiryDuration); - } - - public static License generateSignedLicense(String type, int version, long issueDate, TimeValue expiryDuration) throws Exception { - long issue = (issueDate != -1L) ? issueDate : System.currentTimeMillis() - TimeValue.timeValueHours(2).getMillis(); - final String licenseType; - if (version < License.VERSION_NO_FEATURE_TYPE) { - licenseType = randomFrom("subscription", "internal", "development"); - } else { - licenseType = (type != null) ? type : randomFrom("basic", "silver", "dev", "gold", "platinum"); - } - final License.Builder builder = License.builder() - .uid(UUID.randomUUID().toString()) - .version(version) - .expiryDate(System.currentTimeMillis() + expiryDuration.getMillis()) - .issueDate(issue) - .type(licenseType) - .issuedTo("customer") - .issuer("elasticsearch") - .maxNodes(5); - if (version == License.VERSION_START) { - builder.subscriptionType((type != null) ? type : randomFrom("dev", "gold", "platinum", "silver")); - builder.feature(randomAsciiOfLength(10)); - } - LicenseSigner signer = new LicenseSigner(getTestPriKeyPath(), getTestPubKeyPath()); - return signer.sign(builder.build()); - } - - public static License generateExpiredLicense(long expiryDate) throws Exception { - return generateExpiredLicense(randomFrom("basic", "silver", "dev", "gold", "platinum"), expiryDate); - } - - public static License generateExpiredLicense() throws Exception { - return generateExpiredLicense(randomFrom("basic", "silver", "dev", "gold", "platinum")); - } - - public static License generateExpiredLicense(String type) throws Exception { - return generateExpiredLicense(type, - System.currentTimeMillis() - TimeValue.timeValueHours(randomIntBetween(1, 10)).getMillis()); - } - - public static License generateExpiredLicense(String type, long expiryDate) throws Exception { - final License.Builder builder = License.builder() - .uid(UUID.randomUUID().toString()) - .version(License.VERSION_CURRENT) - .expiryDate(expiryDate) - .issueDate(expiryDate - TimeValue.timeValueMinutes(10).getMillis()) - .type(type) - .issuedTo("customer") - .issuer("elasticsearch") - .maxNodes(5); - LicenseSigner signer = new LicenseSigner(getTestPriKeyPath(), getTestPubKeyPath()); - return signer.sign(builder.build()); - } - - private static Path getResourcePath(String resource) throws Exception { - return PathUtils.get(TestUtils.class.getResource(resource).toURI()); - } - - public static void registerAndAckSignedLicenses(final LicenseService licenseService, License license, - final LicensesStatus expectedStatus) { - PutLicenseRequest putLicenseRequest = new PutLicenseRequest().license(license).acknowledge(true); - final CountDownLatch latch = new CountDownLatch(1); - final AtomicReference status = new AtomicReference<>(); - licenseService.registerLicense(putLicenseRequest, new ActionListener() { - @Override - public void onResponse(PutLicenseResponse licensesUpdateResponse) { - status.set(licensesUpdateResponse.status()); - latch.countDown(); - } - - @Override - public void onFailure(Exception e) { - latch.countDown(); - } - }); - try { - latch.await(); - } catch (InterruptedException e) { - Assert.fail(e.getMessage()); - } - assertThat(status.get(), equalTo(expectedStatus)); - } - - public static class AssertingLicenseState extends XPackLicenseState { - public final List modeUpdates = new ArrayList<>(); - public final List activeUpdates = new ArrayList<>(); - - @Override - void update(License.OperationMode mode, boolean active) { - modeUpdates.add(mode); - activeUpdates.add(active); - } - } -} diff --git a/elasticsearch/license/licensor/src/test/resources/public.key b/elasticsearch/x-pack/license-plugin/src/test/resources/public.key similarity index 100% rename from elasticsearch/license/licensor/src/test/resources/public.key rename to elasticsearch/x-pack/license-plugin/src/test/resources/public.key diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/Monitoring.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/Monitoring.java index bb359f5453c..6581e331c14 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/Monitoring.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/Monitoring.java @@ -7,28 +7,46 @@ package org.elasticsearch.xpack.monitoring; import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.common.component.LifecycleComponent; +import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Module; -import org.elasticsearch.common.network.NetworkModule; +import org.elasticsearch.common.inject.util.Providers; +import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.env.Environment; +import org.elasticsearch.license.LicenseService; +import org.elasticsearch.license.XPackLicenseState; +import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.xpack.XPackPlugin; import org.elasticsearch.xpack.monitoring.action.MonitoringBulkAction; import org.elasticsearch.xpack.monitoring.action.TransportMonitoringBulkAction; import org.elasticsearch.xpack.monitoring.agent.AgentService; -import org.elasticsearch.xpack.monitoring.agent.collector.CollectorModule; -import org.elasticsearch.xpack.monitoring.agent.exporter.ExporterModule; +import org.elasticsearch.xpack.monitoring.agent.collector.Collector; +import org.elasticsearch.xpack.monitoring.agent.collector.cluster.ClusterStateCollector; +import org.elasticsearch.xpack.monitoring.agent.collector.cluster.ClusterStatsCollector; +import org.elasticsearch.xpack.monitoring.agent.collector.indices.IndexRecoveryCollector; +import org.elasticsearch.xpack.monitoring.agent.collector.indices.IndexStatsCollector; +import org.elasticsearch.xpack.monitoring.agent.collector.indices.IndicesStatsCollector; +import org.elasticsearch.xpack.monitoring.agent.collector.node.NodeStatsCollector; +import org.elasticsearch.xpack.monitoring.agent.collector.shards.ShardsCollector; +import org.elasticsearch.xpack.monitoring.agent.exporter.Exporter; +import org.elasticsearch.xpack.monitoring.agent.exporter.Exporters; +import org.elasticsearch.xpack.monitoring.agent.exporter.http.HttpExporter; +import org.elasticsearch.xpack.monitoring.agent.exporter.local.LocalExporter; import org.elasticsearch.xpack.monitoring.cleaner.CleanerService; -import org.elasticsearch.xpack.monitoring.client.MonitoringClientModule; import org.elasticsearch.xpack.monitoring.rest.action.RestMonitoringBulkAction; import org.elasticsearch.plugins.ActionPlugin; import org.elasticsearch.rest.RestHandler; -import org.elasticsearch.xpack.XPackPlugin; +import org.elasticsearch.xpack.security.InternalClient; 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.List; +import java.util.Map; +import java.util.Set; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; @@ -44,12 +62,16 @@ public class Monitoring implements ActionPlugin { public static final String NAME = "monitoring"; private final Settings settings; + private final Environment env; + private final XPackLicenseState licenseState; private final boolean enabled; private final boolean transportClientMode; private final boolean tribeNode; - public Monitoring(Settings settings) { + public Monitoring(Settings settings, Environment env, XPackLicenseState licenseState) { this.settings = settings; + this.env = env; + this.licenseState = licenseState; this.enabled = enabled(settings); this.transportClientMode = XPackPlugin.transportClientMode(settings); this.tribeNode = XPackPlugin.isTribeNode(settings); @@ -65,20 +87,41 @@ public class Monitoring implements ActionPlugin { public Collection nodeModules() { List modules = new ArrayList<>(); - modules.add(new MonitoringModule(enabled, transportClientMode)); - modules.add(new ExporterModule(settings)); - if (enabled && transportClientMode == false && tribeNode == false) { - modules.add(new CollectorModule()); - modules.add(new MonitoringClientModule()); - } + modules.add(b -> { + XPackPlugin.bindFeatureSet(b, MonitoringFeatureSet.class); + if (transportClientMode || enabled == false || tribeNode) { + b.bind(Exporters.class).toProvider(Providers.of(null)); + } + }); return modules; } - public Collection> nodeServices() { - if (enabled == false || transportClientMode || tribeNode) { + public Collection createComponents(InternalClient client, ThreadPool threadPool, ClusterService clusterService, + LicenseService licenseService) { + if (enabled == false || tribeNode) { return Collections.emptyList(); } - return Arrays.>asList(AgentService.class, CleanerService.class); + + final ClusterSettings clusterSettings = clusterService.getClusterSettings(); + final MonitoringSettings monitoringSettings = new MonitoringSettings(settings, clusterSettings); + final CleanerService cleanerService = new CleanerService(settings, clusterSettings, threadPool, licenseState); + + Map exporterFactories = new HashMap<>(); + exporterFactories.put(HttpExporter.TYPE, config -> new HttpExporter(config, env)); + exporterFactories.put(LocalExporter.TYPE, config -> new LocalExporter(config, client, clusterService, cleanerService)); + final Exporters exporters = new Exporters(settings, exporterFactories, clusterService); + + Set collectors = new HashSet<>(); + collectors.add(new IndicesStatsCollector(settings, clusterService, monitoringSettings, licenseState, client)); + collectors.add(new IndexStatsCollector(settings, clusterService, monitoringSettings, licenseState, client)); + collectors.add(new ClusterStatsCollector(settings, clusterService, monitoringSettings, licenseState, client, licenseService)); + collectors.add(new ClusterStateCollector(settings, clusterService, monitoringSettings, licenseState, client)); + collectors.add(new ShardsCollector(settings, clusterService, monitoringSettings, licenseState)); + collectors.add(new NodeStatsCollector(settings, clusterService, monitoringSettings, licenseState, client)); + collectors.add(new IndexRecoveryCollector(settings, clusterService, monitoringSettings, licenseState, client)); + final AgentService agentService = new AgentService(settings, clusterSettings, collectors, exporters); + + return Arrays.asList(agentService, monitoringSettings, exporters, cleanerService); } @Override diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringFeatureSet.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringFeatureSet.java index e70dcd67713..6000b7883b6 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringFeatureSet.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringFeatureSet.java @@ -12,7 +12,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.XPackFeatureSet; import org.elasticsearch.xpack.monitoring.agent.exporter.Exporter; import org.elasticsearch.xpack.monitoring.agent.exporter.Exporters; @@ -71,7 +71,7 @@ public class MonitoringFeatureSet implements XPackFeatureSet { Map usage = new HashMap<>(); for (Exporter exporter : exporters) { if (exporter.config().enabled()) { - String type = exporter.type(); + String type = exporter.config().type(); int count = (Integer) usage.getOrDefault(type, 0); usage.put(type, count + 1); } diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringModule.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringModule.java deleted file mode 100644 index 6c7908b82c3..00000000000 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringModule.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.monitoring; - -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.inject.util.Providers; -import org.elasticsearch.xpack.XPackPlugin; -import org.elasticsearch.xpack.monitoring.agent.AgentService; -import org.elasticsearch.xpack.monitoring.cleaner.CleanerService; - -public class MonitoringModule extends AbstractModule { - - private final boolean enabled; - private final boolean transportClientMode; - - public MonitoringModule(boolean enabled, boolean transportClientMode) { - this.enabled = enabled; - this.transportClientMode = transportClientMode; - } - - @Override - protected void configure() { - XPackPlugin.bindFeatureSet(binder(), MonitoringFeatureSet.class); - - if (enabled && transportClientMode == false) { - bind(MonitoringSettings.class).asEagerSingleton(); - bind(AgentService.class).asEagerSingleton(); - bind(CleanerService.class).asEagerSingleton(); - } - } -} diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringSettings.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringSettings.java index dc5f039b430..479ba479fe4 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringSettings.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringSettings.java @@ -34,7 +34,6 @@ public class MonitoringSettings extends AbstractComponent { * The minimum amount of time allowed for the history duration. */ public static final TimeValue HISTORY_DURATION_MINIMUM = TimeValue.timeValueHours(24); - public static final TimeValue MAX_LICENSE_GRACE_PERIOD = TimeValue.timeValueHours(7 * 24); /** * Determines whether monitoring is enabled/disabled @@ -123,7 +122,7 @@ public class MonitoringSettings extends AbstractComponent { * Settings/Options per configured exporter */ public static final Setting EXPORTERS_SETTINGS = - groupSetting(collectionKey("exporters."), Property.Dynamic, Property.NodeScope); + groupSetting(key("exporters."), Property.Dynamic, Property.NodeScope); public static List> getSettings() { return Arrays.asList(INDICES, @@ -141,7 +140,7 @@ public class MonitoringSettings extends AbstractComponent { } public static List getSettingsFilter() { - return Arrays.asList("xpack.monitoring.collection.exporters.*.auth.*", "xpack.monitoring.collection.exporters.*.ssl.*"); + return Arrays.asList(key("exporters.*.auth.*"), key("exporters.*.ssl.*")); } @@ -153,7 +152,6 @@ public class MonitoringSettings extends AbstractComponent { private volatile boolean recoveryActiveOnly; private volatile String[] indices; - @Inject public MonitoringSettings(Settings settings, ClusterSettings clusterSettings) { super(settings); diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/AgentService.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/AgentService.java index 37cfd5617fa..bf10f959767 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/AgentService.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/AgentService.java @@ -51,7 +51,6 @@ public class AgentService extends AbstractLifecycleComponent { private final String[] settingsCollectors; private final Exporters exporters; - @Inject public AgentService(Settings settings, ClusterSettings clusterSettings, Set collectors, Exporters exporters) { super(settings); this.samplingIntervalMillis = MonitoringSettings.INTERVAL.get(settings).millis(); diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/AbstractCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/AbstractCollector.java index fccfc22e57f..5042718dce0 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/AbstractCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/AbstractCollector.java @@ -12,7 +12,7 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoredSystem; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; @@ -27,7 +27,6 @@ public abstract class AbstractCollector extends AbstractLifecycleComponent imple protected final MonitoringSettings monitoringSettings; protected final XPackLicenseState licenseState; - @Inject public AbstractCollector(Settings settings, String name, ClusterService clusterService, MonitoringSettings monitoringSettings, XPackLicenseState licenseState) { super(settings); diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/CollectorModule.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/CollectorModule.java deleted file mode 100644 index baa7a13bdad..00000000000 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/CollectorModule.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.monitoring.agent.collector; - -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.inject.multibindings.Multibinder; -import org.elasticsearch.xpack.monitoring.agent.collector.cluster.ClusterStateCollector; -import org.elasticsearch.xpack.monitoring.agent.collector.cluster.ClusterStatsCollector; -import org.elasticsearch.xpack.monitoring.agent.collector.indices.IndexRecoveryCollector; -import org.elasticsearch.xpack.monitoring.agent.collector.indices.IndexStatsCollector; -import org.elasticsearch.xpack.monitoring.agent.collector.indices.IndicesStatsCollector; -import org.elasticsearch.xpack.monitoring.agent.collector.node.NodeStatsCollector; -import org.elasticsearch.xpack.monitoring.agent.collector.shards.ShardsCollector; - -import java.util.HashSet; -import java.util.Set; - -public class CollectorModule extends AbstractModule { - - private final Set> collectors = new HashSet<>(); - - public CollectorModule() { - // Registers default collectors - registerCollector(IndicesStatsCollector.class); - registerCollector(IndexStatsCollector.class); - registerCollector(ClusterStatsCollector.class); - registerCollector(ClusterStateCollector.class); - registerCollector(ShardsCollector.class); - registerCollector(NodeStatsCollector.class); - registerCollector(IndexRecoveryCollector.class); - } - - @Override - protected void configure() { - Multibinder binder = Multibinder.newSetBinder(binder(), Collector.class); - for (Class collector : collectors) { - bind(collector).asEagerSingleton(); - binder.addBinding().to(collector); - } - } - - public void registerCollector(Class collector) { - collectors.add(collector); - } -} \ No newline at end of file diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterInfoMonitoringDoc.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterInfoMonitoringDoc.java index cd1c9d8aabc..b111a9d96e1 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterInfoMonitoringDoc.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterInfoMonitoringDoc.java @@ -6,7 +6,7 @@ package org.elasticsearch.xpack.monitoring.agent.collector.cluster; import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse; -import org.elasticsearch.license.core.License; +import org.elasticsearch.license.License; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; public class ClusterInfoMonitoringDoc extends MonitoringDoc { diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollector.java index 938a728c6ca..fe6f92cd1d7 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollector.java @@ -5,25 +5,24 @@ */ package org.elasticsearch.xpack.monitoring.agent.collector.cluster; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNodes; import org.elasticsearch.cluster.service.ClusterService; -import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; import org.elasticsearch.xpack.security.InternalClient; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - /** * Collector for cluster state. *

@@ -36,7 +35,6 @@ public class ClusterStateCollector extends AbstractCollector { private final Client client; - @Inject public ClusterStateCollector(Settings settings, ClusterService clusterService, MonitoringSettings monitoringSettings, XPackLicenseState licenseState, InternalClient client) { super(settings, NAME, clusterService, monitoringSettings, licenseState); diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollector.java index 4eee2aa63a0..f57c6544e0b 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollector.java @@ -5,27 +5,26 @@ */ package org.elasticsearch.xpack.monitoring.agent.collector.cluster; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.Version; import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.service.ClusterService; -import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.LicenseService; -import org.elasticsearch.license.plugin.core.LicenseUtils; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.LicenseService; +import org.elasticsearch.license.LicenseUtils; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; import org.elasticsearch.xpack.security.InternalClient; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - /** * Collector for cluster stats. *

@@ -43,7 +42,6 @@ public class ClusterStatsCollector extends AbstractCollector { private final LicenseService licenseService; private final Client client; - @Inject public ClusterStatsCollector(Settings settings, ClusterService clusterService, MonitoringSettings monitoringSettings, XPackLicenseState licenseState, InternalClient client, LicenseService licenseService) { diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollector.java index 14b866b17b0..487f1fd60f5 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollector.java @@ -5,27 +5,26 @@ */ package org.elasticsearch.xpack.monitoring.agent.collector.indices; -import org.elasticsearch.action.admin.indices.recovery.RecoveryResponse; -import org.elasticsearch.action.support.IndicesOptions; -import org.elasticsearch.client.Client; -import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; -import org.elasticsearch.cluster.service.ClusterService; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.index.IndexNotFoundException; -import org.elasticsearch.license.plugin.core.XPackLicenseState; -import org.elasticsearch.xpack.monitoring.MonitoringSettings; -import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; -import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; -import org.elasticsearch.xpack.security.InternalClient; -import org.elasticsearch.xpack.security.Security; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; +import org.elasticsearch.action.admin.indices.recovery.RecoveryResponse; +import org.elasticsearch.action.support.IndicesOptions; +import org.elasticsearch.client.Client; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.index.IndexNotFoundException; +import org.elasticsearch.license.XPackLicenseState; +import org.elasticsearch.xpack.monitoring.MonitoringSettings; +import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; +import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; +import org.elasticsearch.xpack.security.InternalClient; +import org.elasticsearch.xpack.security.Security; + /** * Collector for the Recovery API. *

@@ -38,7 +37,6 @@ public class IndexRecoveryCollector extends AbstractCollector { private final Client client; - @Inject public IndexRecoveryCollector(Settings settings, ClusterService clusterService, MonitoringSettings monitoringSettings, XPackLicenseState licenseState, InternalClient client) { super(settings, NAME, clusterService, monitoringSettings, licenseState); diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollector.java index b2c2821ff59..5cce9df091c 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollector.java @@ -5,6 +5,12 @@ */ package org.elasticsearch.xpack.monitoring.agent.collector.indices; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + import org.elasticsearch.action.admin.indices.stats.IndexStats; import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse; import org.elasticsearch.action.support.IndicesOptions; @@ -12,22 +18,15 @@ import org.elasticsearch.client.Client; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.service.ClusterService; -import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexNotFoundException; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; import org.elasticsearch.xpack.security.InternalClient; import org.elasticsearch.xpack.security.Security; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - /** * Collector for indices statistics. *

@@ -40,7 +39,6 @@ public class IndexStatsCollector extends AbstractCollector { private final Client client; - @Inject public IndexStatsCollector(Settings settings, ClusterService clusterService, MonitoringSettings monitoringSettings, XPackLicenseState licenseState, InternalClient client) { super(settings, NAME, clusterService, monitoringSettings, licenseState); diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollector.java index 446517166ef..b5bf088188c 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollector.java @@ -5,25 +5,24 @@ */ package org.elasticsearch.xpack.monitoring.agent.collector.indices; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.service.ClusterService; -import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexNotFoundException; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; import org.elasticsearch.xpack.security.InternalClient; import org.elasticsearch.xpack.security.Security; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; - /** * Collector for indices statistics. *

@@ -35,7 +34,6 @@ public class IndicesStatsCollector extends AbstractCollector { private final Client client; - @Inject public IndicesStatsCollector(Settings settings, ClusterService clusterService, MonitoringSettings monitoringSettings, XPackLicenseState licenseState, InternalClient client) { super(settings, NAME, clusterService, monitoringSettings, licenseState); diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollector.java index 5b855284c41..ce4506c1569 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollector.java @@ -5,6 +5,10 @@ */ package org.elasticsearch.xpack.monitoring.agent.collector.node; +import java.util.Collection; +import java.util.Collections; +import java.util.function.Consumer; + import org.elasticsearch.action.admin.cluster.node.stats.NodeStats; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsRequest; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse; @@ -12,20 +16,14 @@ import org.elasticsearch.action.admin.indices.stats.CommonStatsFlags; import org.elasticsearch.bootstrap.BootstrapInfo; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider; import org.elasticsearch.cluster.service.ClusterService; -import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.env.NodeEnvironment; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; import org.elasticsearch.xpack.security.InternalClient; -import java.util.Collection; -import java.util.Collections; - /** * Collector for nodes statistics. *

@@ -37,29 +35,11 @@ public class NodeStatsCollector extends AbstractCollector { public static final String NAME = "node-stats-collector"; private final Client client; - private final NodeEnvironment nodeEnvironment; - private final DiskThresholdDecider diskThresholdDecider; - - @Inject public NodeStatsCollector(Settings settings, ClusterService clusterService, MonitoringSettings monitoringSettings, - XPackLicenseState licenseState, InternalClient client, - NodeEnvironment nodeEnvironment, DiskThresholdDecider diskThresholdDecider) { + XPackLicenseState licenseState, InternalClient client) { super(settings, NAME, clusterService, monitoringSettings, licenseState); this.client = client; - this.nodeEnvironment = nodeEnvironment; - this.diskThresholdDecider = diskThresholdDecider; - } - - @Override - protected boolean shouldCollect() { - // In some cases, the collector starts to collect nodes stats but the - // NodeEnvironment is not fully initialized (NodePath is null) and can fail. - // This why we need to check for nodeEnvironment.hasNodeFile() here, but only - // for nodes that can hold data. Client nodes can collect nodes stats because - // elasticsearch correctly handles the nodes stats for client nodes. - return super.shouldCollect() - && (DiscoveryNode.nodeRequiresLocalStorage(settings) == false || nodeEnvironment.hasNodeFile()); } @Override @@ -80,12 +60,6 @@ public class NodeStatsCollector extends AbstractCollector { } NodeStats nodeStats = response.getNodes().get(0); - - // Here we are calling directly the DiskThresholdDecider to retrieve the high watermark value - // It would be nicer to use a settings API like documented in #6732 - Double diskThresholdWatermarkHigh = (diskThresholdDecider != null) ? 100.0 - diskThresholdDecider.getFreeDiskThresholdHigh() : -1; - boolean diskThresholdDeciderEnabled = (diskThresholdDecider != null) && diskThresholdDecider.isEnabled(); - DiscoveryNode sourceNode = localNode(); NodeStatsMonitoringDoc nodeStatsDoc = new NodeStatsMonitoringDoc(monitoringId(), monitoringVersion()); @@ -96,8 +70,6 @@ public class NodeStatsCollector extends AbstractCollector { nodeStatsDoc.setNodeMaster(isLocalNodeMaster()); nodeStatsDoc.setNodeStats(nodeStats); nodeStatsDoc.setMlockall(BootstrapInfo.isMemoryLocked()); - nodeStatsDoc.setDiskThresholdWaterMarkHigh(diskThresholdWatermarkHigh); - nodeStatsDoc.setDiskThresholdDeciderEnabled(diskThresholdDeciderEnabled); return Collections.singletonList(nodeStatsDoc); } diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsMonitoringDoc.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsMonitoringDoc.java index edc2c440d03..65520cbcdc2 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsMonitoringDoc.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsMonitoringDoc.java @@ -13,10 +13,7 @@ public class NodeStatsMonitoringDoc extends MonitoringDoc { private String nodeId; private boolean nodeMaster; private NodeStats nodeStats; - private boolean mlockall; - private Double diskThresholdWaterMarkHigh; - private boolean diskThresholdDeciderEnabled; public NodeStatsMonitoringDoc(String monitoringId, String monitoringVersion) { super(monitoringId, monitoringVersion); @@ -38,14 +35,6 @@ public class NodeStatsMonitoringDoc extends MonitoringDoc { this.mlockall = mlockall; } - public void setDiskThresholdWaterMarkHigh(Double diskThresholdWaterMarkHigh) { - this.diskThresholdWaterMarkHigh = diskThresholdWaterMarkHigh; - } - - public void setDiskThresholdDeciderEnabled(boolean diskThresholdDeciderEnabled) { - this.diskThresholdDeciderEnabled = diskThresholdDeciderEnabled; - } - public String getNodeId() { return nodeId; } @@ -61,13 +50,5 @@ public class NodeStatsMonitoringDoc extends MonitoringDoc { public boolean isMlockall() { return mlockall; } - - public Double getDiskThresholdWaterMarkHigh() { - return diskThresholdWaterMarkHigh; - } - - public boolean isDiskThresholdDeciderEnabled() { - return diskThresholdDeciderEnabled; - } } diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollector.java index c712d029267..d630b8235d9 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollector.java @@ -5,25 +5,24 @@ */ package org.elasticsearch.xpack.monitoring.agent.collector.shards; -import org.elasticsearch.cluster.ClusterState; -import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; -import org.elasticsearch.cluster.routing.RoutingTable; -import org.elasticsearch.cluster.routing.ShardRouting; -import org.elasticsearch.cluster.service.ClusterService; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.regex.Regex; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.XPackLicenseState; -import org.elasticsearch.xpack.monitoring.MonitoringSettings; -import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; -import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.routing.RoutingTable; +import org.elasticsearch.cluster.routing.ShardRouting; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.regex.Regex; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.XPackLicenseState; +import org.elasticsearch.xpack.monitoring.MonitoringSettings; +import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; +import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; + /** * Collector for shards. *

@@ -34,7 +33,6 @@ public class ShardsCollector extends AbstractCollector { public static final String NAME = "shards-collector"; - @Inject public ShardsCollector(Settings settings, ClusterService clusterService, MonitoringSettings monitoringSettings, XPackLicenseState licenseState) { super(settings, NAME, clusterService, monitoringSettings, licenseState); diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/Exporter.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/Exporter.java index f13a7173f4e..72fade797a2 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/Exporter.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/Exporter.java @@ -19,7 +19,6 @@ public abstract class Exporter implements AutoCloseable { public static final String INDEX_NAME_TIME_FORMAT_SETTING = "index.name.time_format"; public static final String BULK_TIMEOUT_SETTING = "bulk.timeout"; - protected final String type; protected final Config config; protected final ESLogger logger; @@ -27,17 +26,12 @@ public abstract class Exporter implements AutoCloseable { private AtomicBoolean closed = new AtomicBoolean(false); - public Exporter(String type, Config config) { - this.type = type; + public Exporter(Config config) { this.config = config; this.logger = config.logger(getClass()); this.bulkTimeout = config.settings().getAsTime(BULK_TIMEOUT_SETTING, null); } - public String type() { - return type; - } - public String name() { return config.name; } @@ -50,6 +44,11 @@ public abstract class Exporter implements AutoCloseable { return false; } + /** Returns true if only one instance of this exporter should be allowed. */ + public boolean isSingleton() { + return false; + } + /** * Opens up a new export bulk. May return {@code null} indicating this exporter is not ready * yet to export the docs @@ -76,12 +75,14 @@ public abstract class Exporter implements AutoCloseable { public static class Config { private final String name; + private final String type; private final boolean enabled; private final Settings globalSettings; private final Settings settings; - public Config(String name, Settings globalSettings, Settings settings) { + public Config(String name, String type, Settings globalSettings, Settings settings) { this.name = name; + this.type = type; this.globalSettings = globalSettings; this.settings = settings; this.enabled = settings.getAsBoolean("enabled", true); @@ -91,6 +92,10 @@ public abstract class Exporter implements AutoCloseable { return name; } + public String type() { + return type; + } + public boolean enabled() { return enabled; } @@ -104,24 +109,10 @@ public abstract class Exporter implements AutoCloseable { } } - public abstract static class Factory { + /** A factory for constructing {@link Exporter} instances.*/ + public interface Factory { - private final String type; - private final boolean singleton; - - public Factory(String type, boolean singleton) { - this.type = type; - this.singleton = singleton; - } - - public String type() { - return type; - } - - public boolean singleton() { - return singleton; - } - - public abstract E create(Config config); + /** Create an exporter with the given configuration. */ + Exporter create(Config config); } } diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/ExporterModule.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/ExporterModule.java deleted file mode 100644 index 8370f8d66f0..00000000000 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/ExporterModule.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.monitoring.agent.exporter; - -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.inject.multibindings.MapBinder; -import org.elasticsearch.common.inject.util.Providers; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.xpack.XPackPlugin; -import org.elasticsearch.xpack.monitoring.Monitoring; -import org.elasticsearch.xpack.monitoring.agent.exporter.http.HttpExporter; -import org.elasticsearch.xpack.monitoring.agent.exporter.local.LocalExporter; - -import java.util.HashMap; -import java.util.Map; - -public class ExporterModule extends AbstractModule { - - private final Settings settings; - private final Map>> exporterFactories = new HashMap<>(); - - public ExporterModule(Settings settings) { - this.settings = settings; - registerExporter(HttpExporter.TYPE, HttpExporter.Factory.class); - registerExporter(LocalExporter.TYPE, LocalExporter.Factory.class); - } - - @Override - protected void configure() { - if (Monitoring.enabled(settings) && XPackPlugin.transportClientMode(settings) == false - && XPackPlugin.isTribeNode(settings) == false) { - bind(Exporters.class).asEagerSingleton(); - MapBinder factoryBinder = MapBinder.newMapBinder(binder(), String.class, Exporter.Factory.class); - for (Map.Entry>> entry : exporterFactories.entrySet()) { - bind(entry.getValue()).asEagerSingleton(); - factoryBinder.addBinding(entry.getKey()).to(entry.getValue()); - } - } else { - bind(Exporters.class).toProvider(Providers.of(null)); - } - } - - public void registerExporter(String type, Class> factory) { - exporterFactories.put(type, factory); - } -} diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/Exporters.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/Exporters.java index ab04f41897a..e75b916458f 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/Exporters.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/Exporters.java @@ -8,9 +8,7 @@ package org.elasticsearch.xpack.monitoring.agent.exporter; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.component.Lifecycle; -import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.logging.ESLogger; -import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.node.Node; @@ -39,16 +37,15 @@ public class Exporters extends AbstractLifecycleComponent implements Iterable> exporters; - @Inject public Exporters(Settings settings, Map factories, - ClusterService clusterService, - ClusterSettings clusterSettings) { + ClusterService clusterService) { super(settings); this.factories = factories; this.clusterService = clusterService; this.exporters = new AtomicReference<>(emptyMap()); - clusterSettings.addSettingsUpdateConsumer(MonitoringSettings.EXPORTERS_SETTINGS, this::setExportersSetting); + clusterService.getClusterSettings().addSettingsUpdateConsumer(MonitoringSettings.EXPORTERS_SETTINGS, + this::setExportersSetting); } private void setExportersSetting(Settings exportersSetting) { @@ -135,7 +132,7 @@ public class Exporters extends AbstractLifecycleComponent implements Iterable { - - private final Environment env; - - @Inject - public Factory(Environment env) { - super(TYPE, false); - this.env = env; - } - - @Override - public HttpExporter create(Config config) { - return new HttpExporter(config, env); - } - } } diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/local/LocalBulk.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/local/LocalBulk.java index 0666e541e0a..0f6106acf9a 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/local/LocalBulk.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/local/LocalBulk.java @@ -17,6 +17,7 @@ import org.elasticsearch.xpack.monitoring.agent.exporter.ExportException; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; import org.elasticsearch.xpack.monitoring.agent.resolver.MonitoringIndexNameResolver; import org.elasticsearch.xpack.monitoring.agent.resolver.ResolversRegistry; +import org.elasticsearch.xpack.security.InternalClient; import java.util.Arrays; import java.util.Collection; @@ -28,13 +29,13 @@ import java.util.Collection; public class LocalBulk extends ExportBulk { private final ESLogger logger; - private final ClientProxy client; + private final InternalClient client; private final ResolversRegistry resolvers; private BulkRequestBuilder requestBuilder; - public LocalBulk(String name, ESLogger logger, ClientProxy client, ResolversRegistry resolvers) { + public LocalBulk(String name, ESLogger logger, InternalClient client, ResolversRegistry resolvers) { super(name); this.logger = logger; this.client = client; diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/local/LocalExporter.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/local/LocalExporter.java index efc545c3887..df1f4f57814 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/local/LocalExporter.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/exporter/local/LocalExporter.java @@ -51,16 +51,16 @@ public class LocalExporter extends Exporter implements ClusterStateListener, Cle public static final String TYPE = "local"; - private final ClientProxy client; + private final InternalClient client; private final ClusterService clusterService; private final ResolversRegistry resolvers; private final CleanerService cleanerService; private final AtomicReference state = new AtomicReference<>(State.INITIALIZED); - public LocalExporter(Exporter.Config config, ClientProxy client, + public LocalExporter(Exporter.Config config, InternalClient client, ClusterService clusterService, CleanerService cleanerService) { - super(TYPE, config); + super(config); this.client = client; this.clusterService = clusterService; this.cleanerService = cleanerService; @@ -302,26 +302,6 @@ public class LocalExporter extends Exporter implements ClusterStateListener, Cle }); } - public static class Factory extends Exporter.Factory { - - private final ClientProxy client; - private final ClusterService clusterService; - private final CleanerService cleanerService; - - @Inject - public Factory(InternalClient client, ClusterService clusterService, CleanerService cleanerService) { - super(TYPE, true); - this.client = new ClientProxy(client); - this.clusterService = clusterService; - this.cleanerService = cleanerService; - } - - @Override - public LocalExporter create(Config config) { - return new LocalExporter(config, client, clusterService, cleanerService); - } - } - enum State { INITIALIZED, RUNNING, diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterInfoResolver.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterInfoResolver.java index d6c5e8cad3e..17ae28f1324 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterInfoResolver.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterInfoResolver.java @@ -10,7 +10,7 @@ import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.hash.MessageDigests; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.license.core.License; +import org.elasticsearch.license.License; import org.elasticsearch.xpack.monitoring.agent.collector.cluster.ClusterInfoMonitoringDoc; import org.elasticsearch.xpack.monitoring.agent.resolver.MonitoringIndexNameResolver; diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/NodeStatsResolver.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/NodeStatsResolver.java index 948ca7a9ff9..901ecee3292 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/NodeStatsResolver.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/NodeStatsResolver.java @@ -28,8 +28,6 @@ public class NodeStatsResolver extends MonitoringIndexNameResolver.Timestamped> clusterSettings = new HashSet<>(); + clusterSettings.addAll(ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); + clusterSettings.add(MonitoringSettings.EXPORTERS_SETTINGS); clusterService = new ClusterService(Settings.builder().put("cluster.name", TransportMonitoringBulkActionTests.class.getName()).build(), - new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), threadPool); + new ClusterSettings(Settings.EMPTY, clusterSettings), threadPool); clusterService.setLocalNode(new DiscoveryNode("node", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT)); clusterService.setNodeConnectionsService(new NodeConnectionsService(Settings.EMPTY, null, null) { @@ -257,8 +263,7 @@ public class TransportMonitoringBulkActionTests extends ESTestCase { private final Collection exported = ConcurrentCollections.newConcurrentSet(); public CapturingExporters() { - super(Settings.EMPTY, Collections.emptyMap(), clusterService, - new ClusterSettings(Settings.EMPTY, Collections.singleton(MonitoringSettings.EXPORTERS_SETTINGS))); + super(Settings.EMPTY, Collections.emptyMap(), clusterService); } @Override @@ -279,8 +284,7 @@ public class TransportMonitoringBulkActionTests extends ESTestCase { private final Consumer> consumer; public ConsumingExporters(Consumer> consumer) { - super(Settings.EMPTY, Collections.emptyMap(), clusterService, - new ClusterSettings(Settings.EMPTY, Collections.singleton(MonitoringSettings.EXPORTERS_SETTINGS))); + super(Settings.EMPTY, Collections.emptyMap(), clusterService); this.consumer = consumer; } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollectorTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollectorTests.java index 0823b3ba3c3..8eead22ed08 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollectorTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollectorTests.java @@ -10,7 +10,7 @@ import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoredSystem; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollectorTestCase; diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollectorTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollectorTests.java index 370fa9f642a..e026d90b7ba 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollectorTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollectorTests.java @@ -11,8 +11,8 @@ import org.apache.lucene.util.LuceneTestCase.BadApple; import org.elasticsearch.Version; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.LicenseService; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.LicenseService; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoredSystem; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollectorTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollectorTests.java index fdd37852e3f..e1c59c10222 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollectorTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollectorTests.java @@ -13,7 +13,7 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.indices.recovery.RecoveryState; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.test.hamcrest.ElasticsearchAssertions; import org.elasticsearch.xpack.monitoring.MonitoredSystem; diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollectorTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollectorTests.java index 3d7cd3bda92..816f4ff8148 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollectorTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollectorTests.java @@ -11,7 +11,7 @@ import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexNotFoundException; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.xpack.monitoring.MonitoredSystem; import org.elasticsearch.xpack.monitoring.MonitoringSettings; @@ -20,7 +20,6 @@ import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; import java.util.Collection; import java.util.Iterator; -import java.util.List; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; import static org.hamcrest.Matchers.equalTo; diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollectorTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollectorTests.java index 8efc0ff1b11..6f2e42ebb7d 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollectorTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollectorTests.java @@ -13,7 +13,7 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexNotFoundException; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.xpack.monitoring.MonitoredSystem; import org.elasticsearch.xpack.monitoring.MonitoringSettings; @@ -22,7 +22,6 @@ import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; import org.hamcrest.Matchers; import java.util.Collection; -import java.util.List; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; import static org.hamcrest.Matchers.equalTo; diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollectorTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollectorTests.java index 8d503b2b7be..5f81101e224 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollectorTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollectorTests.java @@ -11,7 +11,7 @@ import org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.NodeEnvironment; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.xpack.monitoring.MonitoredSystem; import org.elasticsearch.xpack.monitoring.MonitoringSettings; @@ -56,8 +56,6 @@ public class NodeStatsCollectorTests extends AbstractCollectorTestCase { equalTo(internalCluster().getInstance(ClusterService.class, node).localNode().getId())); assertThat(nodeStatsMonitoringDoc.isNodeMaster(), equalTo(node.equals(internalCluster().getMasterName()))); assertThat(nodeStatsMonitoringDoc.isMlockall(), equalTo(BootstrapInfo.isMemoryLocked())); - assertNotNull(nodeStatsMonitoringDoc.isDiskThresholdDeciderEnabled()); - assertNotNull(nodeStatsMonitoringDoc.getDiskThresholdWaterMarkHigh()); assertNotNull(nodeStatsMonitoringDoc.getNodeStats()); } @@ -68,8 +66,6 @@ public class NodeStatsCollectorTests extends AbstractCollectorTestCase { internalCluster().getInstance(ClusterService.class, nodeId), internalCluster().getInstance(MonitoringSettings.class, nodeId), internalCluster().getInstance(XPackLicenseState.class, nodeId), - internalCluster().getInstance(InternalClient.class, nodeId), - internalCluster().getInstance(NodeEnvironment.class, nodeId), - internalCluster().getInstance(DiskThresholdDecider.class, nodeId)); + internalCluster().getInstance(InternalClient.class, nodeId)); } } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollectorTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollectorTests.java index 17aa341cffc..513b0639d17 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollectorTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollectorTests.java @@ -10,7 +10,7 @@ import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.routing.ShardRouting; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoredSystem; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollectorTestCase; diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/AbstractExporterTemplateTestCase.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/AbstractExporterTemplateTestCase.java index 70c657b260f..c760a63f13c 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/AbstractExporterTemplateTestCase.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/AbstractExporterTemplateTestCase.java @@ -6,14 +6,18 @@ package org.elasticsearch.xpack.monitoring.agent.exporter; import org.elasticsearch.Version; +import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.LicenseService; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.xpack.monitoring.MonitoredSystem; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.Collector; import org.elasticsearch.xpack.monitoring.agent.collector.cluster.ClusterStatsCollector; import org.elasticsearch.xpack.monitoring.test.MonitoringIntegTestCase; +import org.elasticsearch.xpack.security.InternalClient; import java.io.IOException; import java.util.Map; @@ -32,7 +36,7 @@ public abstract class AbstractExporterTemplateTestCase extends MonitoringIntegTe .put(MonitoringSettings.INTERVAL.getKey(), "-1"); for (Map.Entry setting : exporterSettings().getAsMap().entrySet()) { - settings.put("xpack.monitoring.collection.exporters._exporter." + setting.getKey(), setting.getValue()); + settings.put("xpack.monitoring.exporters._exporter." + setting.getKey(), setting.getValue()); } return settings.build(); } @@ -114,8 +118,14 @@ public abstract class AbstractExporterTemplateTestCase extends MonitoringIntegTe } protected void doExporting() throws Exception { - Collector collector = internalCluster().getInstance(ClusterStatsCollector.class); - assertNotNull(collector); + // TODO: these should be unit tests, not using guice + ClusterService clusterService = internalCluster().getInstance(ClusterService.class); + XPackLicenseState licenseState = internalCluster().getInstance(XPackLicenseState.class); + LicenseService licenseService = internalCluster().getInstance(LicenseService.class); + InternalClient client = internalCluster().getInstance(InternalClient.class); + Collector collector = new ClusterStatsCollector(clusterService.getSettings(), clusterService, + new MonitoringSettings(clusterService.getSettings(), clusterService.getClusterSettings()), + licenseState, client, licenseService); Exporters exporters = internalCluster().getInstance(Exporters.class); assertNotNull(exporters); diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/ExportersTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/ExportersTests.java index 38a18b6a8e6..643ec1d2193 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/ExportersTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/ExportersTests.java @@ -6,7 +6,6 @@ package org.elasticsearch.xpack.monitoring.agent.exporter; import org.elasticsearch.Version; -import org.elasticsearch.client.Client; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.node.DiscoveryNodes; @@ -16,11 +15,11 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.common.util.concurrent.AbstractRunnable; import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.xpack.common.init.proxy.ClientProxy; import org.elasticsearch.xpack.monitoring.MonitoredSystem; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.exporter.local.LocalExporter; import org.elasticsearch.xpack.monitoring.cleaner.CleanerService; +import org.elasticsearch.xpack.security.InternalClient; import org.junit.Before; import java.util.ArrayList; @@ -45,7 +44,6 @@ import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; @@ -64,21 +62,21 @@ public class ExportersTests extends ESTestCase { public void init() throws Exception { factories = new HashMap<>(); - Client client = mock(Client.class); - when(client.settings()).thenReturn(Settings.EMPTY); + InternalClient client = mock(InternalClient.class); clusterService = mock(ClusterService.class); + clusterSettings = new ClusterSettings(Settings.EMPTY, new HashSet<>(Arrays.asList(MonitoringSettings.COLLECTORS, + MonitoringSettings.INTERVAL, MonitoringSettings.EXPORTERS_SETTINGS))); + when(clusterService.getClusterSettings()).thenReturn(clusterSettings); // we always need to have the local exporter as it serves as the default one - factories.put(LocalExporter.TYPE, new LocalExporter.Factory(ClientProxy.fromClient(client), clusterService, + factories.put(LocalExporter.TYPE, config -> new LocalExporter(config, client, clusterService, mock(CleanerService.class))); - clusterSettings = new ClusterSettings(Settings.EMPTY, new HashSet<>(Arrays.asList(MonitoringSettings.COLLECTORS, - MonitoringSettings.INTERVAL, MonitoringSettings.EXPORTERS_SETTINGS))); - exporters = new Exporters(Settings.EMPTY, factories, clusterService, clusterSettings); + + exporters = new Exporters(Settings.EMPTY, factories, clusterService); } public void testInitExportersDefault() throws Exception { - Exporter.Factory factory = new TestFactory("_type", true); - factories.put("_type", factory); + factories.put("_type", TestExporter::new); Map internalExporters = exporters.initExporters(Settings.builder().build()); assertThat(internalExporters, notNullValue()); @@ -88,8 +86,7 @@ public class ExportersTests extends ESTestCase { } public void testInitExportersSingle() throws Exception { - Exporter.Factory factory = new TestFactory("_type", true); - factories.put("_type", factory); + factories.put("_type", TestExporter::new); Map internalExporters = exporters.initExporters(Settings.builder() .put("_name.type", "_type") .build()); @@ -97,13 +94,12 @@ public class ExportersTests extends ESTestCase { assertThat(internalExporters, notNullValue()); assertThat(internalExporters.size(), is(1)); assertThat(internalExporters, hasKey("_name")); - assertThat(internalExporters.get("_name"), instanceOf(TestFactory.TestExporter.class)); - assertThat(internalExporters.get("_name").type, is("_type")); + assertThat(internalExporters.get("_name"), instanceOf(TestExporter.class)); + assertThat(internalExporters.get("_name").config().type(), is("_type")); } public void testInitExportersSingleDisabled() throws Exception { - Exporter.Factory factory = new TestFactory("_type", true); - factories.put("_type", factory); + factories.put("_type", TestExporter::new); Map internalExporters = exporters.initExporters(Settings.builder() .put("_name.type", "_type") .put("_name.enabled", false) @@ -138,8 +134,7 @@ public class ExportersTests extends ESTestCase { } public void testInitExportersMultipleSameType() throws Exception { - Exporter.Factory factory = new TestFactory("_type", false); - factories.put("_type", factory); + factories.put("_type", TestExporter::new); Map internalExporters = exporters.initExporters(Settings.builder() .put("_name0.type", "_type") .put("_name1.type", "_type") @@ -148,40 +143,37 @@ public class ExportersTests extends ESTestCase { assertThat(internalExporters, notNullValue()); assertThat(internalExporters.size(), is(2)); assertThat(internalExporters, hasKey("_name0")); - assertThat(internalExporters.get("_name0"), instanceOf(TestFactory.TestExporter.class)); - assertThat(internalExporters.get("_name0").type, is("_type")); + assertThat(internalExporters.get("_name0"), instanceOf(TestExporter.class)); + assertThat(internalExporters.get("_name0").config().type(), is("_type")); assertThat(internalExporters, hasKey("_name1")); - assertThat(internalExporters.get("_name1"), instanceOf(TestFactory.TestExporter.class)); - assertThat(internalExporters.get("_name1").type, is("_type")); + assertThat(internalExporters.get("_name1"), instanceOf(TestExporter.class)); + assertThat(internalExporters.get("_name1").config().type(), is("_type")); } public void testInitExportersMultipleSameTypeSingletons() throws Exception { - Exporter.Factory factory = new TestFactory("_type", true); - factories.put("_type", factory); - try { + factories.put("_type", TestSingletonExporter::new); + SettingsException e = expectThrows(SettingsException.class, () -> exporters.initExporters(Settings.builder() .put("_name0.type", "_type") .put("_name1.type", "_type") - .build()); - fail("Expected SettingsException"); - } catch (SettingsException e) { - assertThat(e.getMessage(), containsString("multiple [_type] exporters are configured. there can only be one")); - } + .build()) + ); + assertThat(e.getMessage(), containsString("multiple [_type] exporters are configured. there can only be one")); } public void testSettingsUpdate() throws Exception { - Exporter.Factory factory = spy(new TestFactory("_type", false)); - factories.put("_type", factory); + factories.put("_type", TestExporter::new); final AtomicReference settingsHolder = new AtomicReference<>(); Settings nodeSettings = Settings.builder() - .put("xpack.monitoring.collection.exporters._name0.type", "_type") - .put("xpack.monitoring.collection.exporters._name1.type", "_type") + .put("xpack.monitoring.exporters._name0.type", "_type") + .put("xpack.monitoring.exporters._name1.type", "_type") .build(); clusterSettings = new ClusterSettings(nodeSettings, new HashSet<>(Arrays.asList(MonitoringSettings.EXPORTERS_SETTINGS))); + when(clusterService.getClusterSettings()).thenReturn(clusterSettings); - exporters = new Exporters(nodeSettings, factories, clusterService, clusterSettings) { + exporters = new Exporters(nodeSettings, factories, clusterService) { @Override Map initExporters(Settings settings) { settingsHolder.set(settings); @@ -197,8 +189,8 @@ public class ExportersTests extends ESTestCase { assertThat(settings, hasEntry("_name1.type", "_type")); Settings update = Settings.builder() - .put("xpack.monitoring.collection.exporters._name0.foo", "bar") - .put("xpack.monitoring.collection.exporters._name1.foo", "bar") + .put("xpack.monitoring.exporters._name0.foo", "bar") + .put("xpack.monitoring.exporters._name1.foo", "bar") .build(); clusterSettings.applySettings(update); assertThat(settingsHolder.get(), notNullValue()); @@ -211,14 +203,14 @@ public class ExportersTests extends ESTestCase { } public void testOpenBulkOnMaster() throws Exception { - Exporter.Factory factory = new MockFactory("mock", false); - Exporter.Factory masterOnlyFactory = new MockFactory("mock_master_only", true); + Exporter.Factory factory = new MockFactory(false); + Exporter.Factory masterOnlyFactory = new MockFactory(true); factories.put("mock", factory); factories.put("mock_master_only", masterOnlyFactory); Exporters exporters = new Exporters(Settings.builder() - .put("xpack.monitoring.collection.exporters._name0.type", "mock") - .put("xpack.monitoring.collection.exporters._name1.type", "mock_master_only") - .build(), factories, clusterService, clusterSettings); + .put("xpack.monitoring.exporters._name0.type", "mock") + .put("xpack.monitoring.exporters._name1.type", "mock_master_only") + .build(), factories, clusterService); exporters.start(); DiscoveryNodes nodes = mock(DiscoveryNodes.class); @@ -236,14 +228,14 @@ public class ExportersTests extends ESTestCase { } public void testExportNotOnMaster() throws Exception { - Exporter.Factory factory = new MockFactory("mock", false); - Exporter.Factory masterOnlyFactory = new MockFactory("mock_master_only", true); + Exporter.Factory factory = new MockFactory(false); + Exporter.Factory masterOnlyFactory = new MockFactory(true); factories.put("mock", factory); factories.put("mock_master_only", masterOnlyFactory); Exporters exporters = new Exporters(Settings.builder() - .put("xpack.monitoring.collection.exporters._name0.type", "mock") - .put("xpack.monitoring.collection.exporters._name1.type", "mock_master_only") - .build(), factories, clusterService, clusterSettings); + .put("xpack.monitoring.exporters._name0.type", "mock") + .put("xpack.monitoring.exporters._name1.type", "mock_master_only") + .build(), factories, clusterService); exporters.start(); DiscoveryNodes nodes = mock(DiscoveryNodes.class); @@ -257,6 +249,7 @@ public class ExportersTests extends ESTestCase { verify(exporters.getExporter("_name0"), times(1)).masterOnly(); verify(exporters.getExporter("_name0"), times(1)).openBulk(); verify(exporters.getExporter("_name1"), times(1)).masterOnly(); + verify(exporters.getExporter("_name1"), times(1)).isSingleton(); verifyNoMoreInteractions(exporters.getExporter("_name1")); } @@ -270,13 +263,12 @@ public class ExportersTests extends ESTestCase { logger.info("--> creating {} exporters", nbExporters); Settings.Builder settings = Settings.builder(); for (int i = 0; i < nbExporters; i++) { - settings.put("xpack.monitoring.collection.exporters._name" + String.valueOf(i) + ".type", "record"); + settings.put("xpack.monitoring.exporters._name" + String.valueOf(i) + ".type", "record"); } - Exporter.Factory factory = new CountingExportFactory("record", false); - factories.put("record", factory); + factories.put("record", CountingExporter::new); - Exporters exporters = new Exporters(settings.build(), factories, clusterService, clusterSettings); + Exporters exporters = new Exporters(settings.build(), factories, clusterService); exporters.start(); final Thread[] threads = new Thread[3 + randomInt(7)]; @@ -327,51 +319,50 @@ public class ExportersTests extends ESTestCase { assertThat(exceptions, empty()); for (Exporter exporter : exporters) { - assertThat(exporter, instanceOf(CountingExportFactory.CountingExporter.class)); - assertThat(((CountingExportFactory.CountingExporter) exporter).getExportedCount(), equalTo(total)); + assertThat(exporter, instanceOf(CountingExporter.class)); + assertThat(((CountingExporter) exporter).getExportedCount(), equalTo(total)); } exporters.close(); } - static class TestFactory extends Exporter.Factory { - public TestFactory(String type, boolean singleton) { - super(type, singleton); + static class TestExporter extends Exporter { + public TestExporter(Config config) { + super(config); } @Override - public TestExporter create(Exporter.Config config) { - return new TestExporter(type(), config); + public ExportBulk openBulk() { + return mock(ExportBulk.class); } - static class TestExporter extends Exporter { - public TestExporter(String type, Config config) { - super(type, config); - } - - @Override - public ExportBulk openBulk() { - return mock(ExportBulk.class); - } - - @Override - public void doClose() { - } + @Override + public void doClose() { } } - static class MockFactory extends Exporter.Factory { + static class TestSingletonExporter extends TestExporter { + TestSingletonExporter(Config config) { + super(config); + } + + @Override + public boolean isSingleton() { + return true; + } + } + + + static class MockFactory implements Exporter.Factory { private final boolean masterOnly; - public MockFactory(String type, boolean masterOnly) { - super(type, false); + public MockFactory(boolean masterOnly) { this.masterOnly = masterOnly; } @Override public Exporter create(Exporter.Config config) { Exporter exporter = mock(Exporter.class); - when(exporter.type()).thenReturn(type()); when(exporter.name()).thenReturn(config.name()); when(exporter.masterOnly()).thenReturn(masterOnly); when(exporter.openBulk()).thenReturn(mock(ExportBulk.class)); @@ -379,73 +370,58 @@ public class ExportersTests extends ESTestCase { } } - /** - * A factory of exporters that count the number of exported documents. - */ - static class CountingExportFactory extends Exporter.Factory { + static class CountingExporter extends Exporter { - public CountingExportFactory(String type, boolean singleton) { - super(type, singleton); + private static final AtomicInteger count = new AtomicInteger(0); + private List bulks = new CopyOnWriteArrayList<>(); + + public CountingExporter(Config config) { + super(config); } @Override - public CountingExporter create(Exporter.Config config) { - return new CountingExporter(type(), config); + public ExportBulk openBulk() { + CountingBulk bulk = new CountingBulk(config.type() + "#" + count.getAndIncrement()); + bulks.add(bulk); + return bulk; } - static class CountingExporter extends Exporter { - - private static final AtomicInteger count = new AtomicInteger(0); - private List bulks = new CopyOnWriteArrayList<>(); - - public CountingExporter(String type, Config config) { - super(type, config); - } - - @Override - public ExportBulk openBulk() { - CountingBulk bulk = new CountingBulk(type + "#" + count.getAndIncrement()); - bulks.add(bulk); - return bulk; - } - - @Override - public void doClose() { - } - - public int getExportedCount() { - int exported = 0; - for (CountingBulk bulk : bulks) { - exported += bulk.getCount(); - } - return exported; - } + @Override + public void doClose() { } - static class CountingBulk extends ExportBulk { - - private final AtomicInteger count = new AtomicInteger(); - - public CountingBulk(String name) { - super(name); + public int getExportedCount() { + int exported = 0; + for (CountingBulk bulk : bulks) { + exported += bulk.getCount(); } + return exported; + } + } - @Override - protected void doAdd(Collection docs) throws ExportException { - count.addAndGet(docs.size()); - } + static class CountingBulk extends ExportBulk { - @Override - protected void doFlush() { - } + private final AtomicInteger count = new AtomicInteger(); - @Override - protected void doClose() throws ExportException { - } + public CountingBulk(String name) { + super(name); + } - int getCount() { - return count.get(); - } + @Override + protected void doAdd(Collection docs) throws ExportException { + count.addAndGet(docs.size()); + } + + @Override + protected void doFlush() { + } + + @Override + protected void doClose() throws ExportException { + } + + int getCount() { + return count.get(); } } } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/http/HttpExporterTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/http/HttpExporterTests.java index 9d5fd29023e..04162b1b2da 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/http/HttpExporterTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/http/HttpExporterTests.java @@ -95,10 +95,10 @@ public class HttpExporterTests extends MonitoringIntegTestCase { Settings.Builder builder = Settings.builder() .put(MonitoringSettings.INTERVAL.getKey(), "-1") - .put("xpack.monitoring.collection.exporters._http.type", "http") - .put("xpack.monitoring.collection.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort()) - .put("xpack.monitoring.collection.exporters._http.connection.keep_alive", false) - .put("xpack.monitoring.collection.exporters._http.update_mappings", false); + .put("xpack.monitoring.exporters._http.type", "http") + .put("xpack.monitoring.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort()) + .put("xpack.monitoring.exporters._http.connection.keep_alive", false) + .put("xpack.monitoring.exporters._http.update_mappings", false); internalCluster().startNode(builder); @@ -133,23 +133,23 @@ public class HttpExporterTests extends MonitoringIntegTestCase { // disable exporting to be able to use non valid hosts Settings.Builder builder = Settings.builder() .put(MonitoringSettings.INTERVAL.getKey(), "-1") - .put("xpack.monitoring.collection.exporters._http.type", "http") - .put("xpack.monitoring.collection.exporters._http.host", "test0"); + .put("xpack.monitoring.exporters._http.type", "http") + .put("xpack.monitoring.exporters._http.host", "test0"); String nodeName = internalCluster().startNode(builder); assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(Settings.builder() - .putArray("xpack.monitoring.collection.exporters._http.host", "test1"))); + .putArray("xpack.monitoring.exporters._http.host", "test1"))); assertThat(getExporter(nodeName).hosts, Matchers.arrayContaining("test1")); // wipes the non array settings assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(Settings.builder() - .putArray("xpack.monitoring.collection.exporters._http.host", "test2") - .put("xpack.monitoring.collection.exporters._http.host", ""))); + .putArray("xpack.monitoring.exporters._http.host", "test2") + .put("xpack.monitoring.exporters._http.host", ""))); assertThat(getExporter(nodeName).hosts, Matchers.arrayContaining("test2")); assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(Settings.builder() - .putArray("xpack.monitoring.collection.exporters._http.host", "test3"))); + .putArray("xpack.monitoring.exporters._http.host", "test3"))); assertThat(getExporter(nodeName).hosts, Matchers.arrayContaining("test3")); } @@ -157,10 +157,10 @@ public class HttpExporterTests extends MonitoringIntegTestCase { Settings.Builder builder = Settings.builder() .put(MonitoringSettings.INTERVAL.getKey(), "-1") - .put("xpack.monitoring.collection.exporters._http.type", "http") - .put("xpack.monitoring.collection.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort()) - .put("xpack.monitoring.collection.exporters._http.connection.keep_alive", false) - .put("xpack.monitoring.collection.exporters._http.update_mappings", false); + .put("xpack.monitoring.exporters._http.type", "http") + .put("xpack.monitoring.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort()) + .put("xpack.monitoring.exporters._http.connection.keep_alive", false) + .put("xpack.monitoring.exporters._http.update_mappings", false); logger.info("--> starting node"); @@ -221,7 +221,7 @@ public class HttpExporterTests extends MonitoringIntegTestCase { assertNotNull("Unable to start the second mock web server", secondWebServer); assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings( - Settings.builder().putArray("xpack.monitoring.collection.exporters._http.host", + Settings.builder().putArray("xpack.monitoring.exporters._http.host", secondWebServer.getHostName() + ":" + secondWebServer.getPort())).get()); // a new exporter is created on update, so we need to re-fetch it @@ -274,9 +274,9 @@ public class HttpExporterTests extends MonitoringIntegTestCase { public void testUnsupportedClusterVersion() throws Exception { Settings.Builder builder = Settings.builder() .put(MonitoringSettings.INTERVAL.getKey(), "-1") - .put("xpack.monitoring.collection.exporters._http.type", "http") - .put("xpack.monitoring.collection.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort()) - .put("xpack.monitoring.collection.exporters._http.connection.keep_alive", false); + .put("xpack.monitoring.exporters._http.type", "http") + .put("xpack.monitoring.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort()) + .put("xpack.monitoring.exporters._http.connection.keep_alive", false); logger.info("--> starting node"); @@ -302,10 +302,10 @@ public class HttpExporterTests extends MonitoringIntegTestCase { public void testDynamicIndexFormatChange() throws Exception { Settings.Builder builder = Settings.builder() .put(MonitoringSettings.INTERVAL.getKey(), "-1") - .put("xpack.monitoring.collection.exporters._http.type", "http") - .put("xpack.monitoring.collection.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort()) - .put("xpack.monitoring.collection.exporters._http.connection.keep_alive", false) - .put("xpack.monitoring.collection.exporters._http.update_mappings", false); + .put("xpack.monitoring.exporters._http.type", "http") + .put("xpack.monitoring.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort()) + .put("xpack.monitoring.exporters._http.connection.keep_alive", false) + .put("xpack.monitoring.exporters._http.update_mappings", false); String agentNode = internalCluster().startNode(builder); @@ -356,7 +356,7 @@ public class HttpExporterTests extends MonitoringIntegTestCase { String newTimeFormat = randomFrom("YY", "YYYY", "YYYY.MM", "YYYY-MM", "MM.YYYY", "MM"); logger.info("--> updating index time format setting to {}", newTimeFormat); assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(Settings.builder() - .put("xpack.monitoring.collection.exporters._http.index.name.time_format", newTimeFormat))); + .put("xpack.monitoring.exporters._http.index.name.time_format", newTimeFormat))); logger.info("--> exporting a second event"); @@ -402,9 +402,9 @@ public class HttpExporterTests extends MonitoringIntegTestCase { Settings.Builder builder = Settings.builder() .put(MonitoringSettings.INTERVAL.getKey(), "-1") - .put("xpack.monitoring.collection.exporters._http.type", "http") - .put("xpack.monitoring.collection.exporters._http.host", host) - .put("xpack.monitoring.collection.exporters._http.connection.keep_alive", false); + .put("xpack.monitoring.exporters._http.type", "http") + .put("xpack.monitoring.exporters._http.host", host) + .put("xpack.monitoring.exporters._http.connection.keep_alive", false); String agentNode = internalCluster().startNode(builder); HttpExporter exporter = getExporter(agentNode); diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/local/LocalExporterTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/local/LocalExporterTests.java index a3e67d97930..a18eb23fc30 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/local/LocalExporterTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/exporter/local/LocalExporterTests.java @@ -65,8 +65,8 @@ public class LocalExporterTests extends MonitoringIntegTestCase { public void testSimpleExport() throws Exception { internalCluster().startNode(Settings.builder() - .put("xpack.monitoring.collection.exporters._local.type", LocalExporter.TYPE) - .put("xpack.monitoring.collection.exporters._local.enabled", true) + .put("xpack.monitoring.exporters._local.type", LocalExporter.TYPE) + .put("xpack.monitoring.exporters._local.enabled", true) .build()); securedEnsureGreen(); @@ -96,7 +96,7 @@ public class LocalExporterTests extends MonitoringIntegTestCase { public void testTemplateCreation() throws Exception { internalCluster().startNode(Settings.builder() - .put("xpack.monitoring.collection.exporters._local.type", LocalExporter.TYPE) + .put("xpack.monitoring.exporters._local.type", LocalExporter.TYPE) .build()); securedEnsureGreen(); @@ -111,8 +111,8 @@ public class LocalExporterTests extends MonitoringIntegTestCase { String timeFormat = randomFrom("YY", "YYYY", "YYYY.MM", "YYYY-MM", "MM.YYYY", "MM"); internalCluster().startNode(Settings.builder() - .put("xpack.monitoring.collection.exporters._local.type", LocalExporter.TYPE) - .put("xpack.monitoring.collection.exporters._local." + LocalExporter.INDEX_NAME_TIME_FORMAT_SETTING, timeFormat) + .put("xpack.monitoring.exporters._local.type", LocalExporter.TYPE) + .put("xpack.monitoring.exporters._local." + LocalExporter.INDEX_NAME_TIME_FORMAT_SETTING, timeFormat) .build()); securedEnsureGreen(); @@ -130,7 +130,7 @@ public class LocalExporterTests extends MonitoringIntegTestCase { logger.debug("--> updates the timestamp"); timeFormat = randomFrom("dd", "dd.MM.YYYY", "dd.MM"); - updateClusterSettings(Settings.builder().put("xpack.monitoring.collection.exporters._local.index.name.time_format", timeFormat)); + updateClusterSettings(Settings.builder().put("xpack.monitoring.exporters._local.index.name.time_format", timeFormat)); exporter = getLocalExporter("_local"); // we need to get it again.. as it was rebuilt indexName = ".monitoring-es-" + MonitoringTemplateUtils.TEMPLATE_VERSION + "-" + DateTimeFormat.forPattern(timeFormat).withZoneUTC().print(doc.getTimestamp()); @@ -144,8 +144,8 @@ public class LocalExporterTests extends MonitoringIntegTestCase { public void testLocalExporterFlush() throws Exception { internalCluster().startNode(Settings.builder() - .put("xpack.monitoring.collection.exporters._local.type", LocalExporter.TYPE) - .put("xpack.monitoring.collection.exporters._local.enabled", true) + .put("xpack.monitoring.exporters._local.type", LocalExporter.TYPE) + .put("xpack.monitoring.exporters._local.enabled", true) .build()); securedEnsureGreen(); diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterInfoResolverTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterInfoResolverTests.java index b3554abd45f..0ccc83edc3e 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterInfoResolverTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterInfoResolverTests.java @@ -13,7 +13,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.LocalTransportAddress; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.license.core.License; +import org.elasticsearch.license.License; import org.elasticsearch.xpack.monitoring.agent.collector.cluster.ClusterInfoMonitoringDoc; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringTemplateUtils; import org.elasticsearch.xpack.monitoring.agent.resolver.MonitoringIndexNameResolverTestCase; diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterInfoTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterInfoTests.java index 4da93724385..d5caa3c8ea6 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterInfoTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterInfoTests.java @@ -10,7 +10,7 @@ import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.query.QueryBuilders; -import org.elasticsearch.license.core.License; +import org.elasticsearch.license.License; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.cluster.ClusterStatsCollector; diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterStateTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterStateTests.java index cb9d317eaa8..461e20ab87a 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterStateTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterStateTests.java @@ -44,7 +44,7 @@ public class ClusterStateTests extends MonitoringIntegTestCase { .put(super.nodeSettings(nodeOrdinal)) .put(MonitoringSettings.INTERVAL.getKey(), "-1") .put(MonitoringSettings.COLLECTORS.getKey(), ClusterStateCollector.NAME) - .put("xpack.monitoring.collection.exporters.default_local.type", "local") + .put("xpack.monitoring.exporters.default_local.type", "local") .put("node.attr.custom", randomInt) .build(); } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterStatsTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterStatsTests.java index a2a591a7cf9..4ab49064185 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterStatsTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/cluster/ClusterStatsTests.java @@ -32,7 +32,7 @@ public class ClusterStatsTests extends MonitoringIntegTestCase { .put(super.nodeSettings(nodeOrdinal)) .put(MonitoringSettings.INTERVAL.getKey(), "-1") .put(MonitoringSettings.COLLECTORS.getKey(), ClusterStatsCollector.NAME) - .put("xpack.monitoring.collection.exporters.default_local.type", "local") + .put("xpack.monitoring.exporters.default_local.type", "local") .build(); } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/indices/IndexRecoveryTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/indices/IndexRecoveryTests.java index b4656ba24ef..8035dfa6215 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/indices/IndexRecoveryTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/indices/IndexRecoveryTests.java @@ -38,7 +38,7 @@ public class IndexRecoveryTests extends MonitoringIntegTestCase { .put(MonitoringSettings.INTERVAL.getKey(), "-1") .put(MonitoringSettings.INDICES.getKey(), INDEX_PREFIX + "*") .put(MonitoringSettings.COLLECTORS.getKey(), IndexRecoveryCollector.NAME) - .put("xpack.monitoring.collection.exporters.default_local.type", "local") + .put("xpack.monitoring.exporters.default_local.type", "local") .build(); } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/indices/IndexStatsTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/indices/IndexStatsTests.java index d8441c6dbe3..dbc282c98cc 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/indices/IndexStatsTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/indices/IndexStatsTests.java @@ -30,7 +30,7 @@ public class IndexStatsTests extends MonitoringIntegTestCase { .put(super.nodeSettings(nodeOrdinal)) .put(MonitoringSettings.INTERVAL.getKey(), "-1") .put(MonitoringSettings.COLLECTORS.getKey(), IndexStatsCollector.NAME) - .put("xpack.monitoring.collection.exporters.default_local.type", "local") + .put("xpack.monitoring.exporters.default_local.type", "local") .build(); } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/indices/IndicesStatsTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/indices/IndicesStatsTests.java index d2f7ce45ea2..b7d4459cd7a 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/indices/IndicesStatsTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/indices/IndicesStatsTests.java @@ -30,7 +30,7 @@ public class IndicesStatsTests extends MonitoringIntegTestCase { .put(super.nodeSettings(nodeOrdinal)) .put(MonitoringSettings.INTERVAL.getKey(), "-1") .put(MonitoringSettings.COLLECTORS.getKey(), IndicesStatsCollector.NAME) - .put("xpack.monitoring.collection.exporters.default_local.type", "local") + .put("xpack.monitoring.exporters.default_local.type", "local") .build(); } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/MultiNodesStatsTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/MultiNodesStatsTests.java index f452d6cb9f4..5697af10b51 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/MultiNodesStatsTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/MultiNodesStatsTests.java @@ -35,7 +35,7 @@ public class MultiNodesStatsTests extends MonitoringIntegTestCase { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) .put(MonitoringSettings.INTERVAL.getKey(), "-1") - .put("xpack.monitoring.collection.exporters.default_local.type", "local") + .put("xpack.monitoring.exporters.default_local.type", "local") .build(); } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/NodeStatsResolverTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/NodeStatsResolverTests.java index 36dd87a4cd8..6626328078f 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/NodeStatsResolverTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/NodeStatsResolverTests.java @@ -63,8 +63,6 @@ public class NodeStatsResolverTests extends MonitoringIndexNameResolverTestCase< doc.setSourceNode(new DiscoveryNode("id", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT)); doc.setNodeMaster(randomBoolean()); doc.setNodeId(UUID.randomUUID().toString()); - doc.setDiskThresholdDeciderEnabled(randomBoolean()); - doc.setDiskThresholdWaterMarkHigh(randomDouble()); doc.setMlockall(randomBoolean()); doc.setNodeStats(randomNodeStats()); return doc; diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/NodeStatsTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/NodeStatsTests.java index d071f67dc51..c4976c85ae0 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/NodeStatsTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/node/NodeStatsTests.java @@ -33,7 +33,7 @@ public class NodeStatsTests extends MonitoringIntegTestCase { .put(super.nodeSettings(nodeOrdinal)) .put(MonitoringSettings.INTERVAL.getKey(), "-1") .put(MonitoringSettings.COLLECTORS.getKey(), NodeStatsCollector.NAME) - .put("xpack.monitoring.collection.exporters.default_local.type", LocalExporter.TYPE) + .put("xpack.monitoring.exporters.default_local.type", LocalExporter.TYPE) .build(); } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/shards/ShardsTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/shards/ShardsTests.java index 27a456d0b0d..235fed062db 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/shards/ShardsTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/resolver/shards/ShardsTests.java @@ -46,7 +46,7 @@ public class ShardsTests extends MonitoringIntegTestCase { .put(MonitoringSettings.INTERVAL.getKey(), "-1") .put(MonitoringSettings.COLLECTORS.getKey(), ShardsCollector.NAME) .put(MonitoringSettings.INDICES.getKey(), INDEX_PREFIX + "*") - .put("xpack.monitoring.collection.exporters.default_local.type", "local") + .put("xpack.monitoring.exporters.default_local.type", "local") .build(); } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/cleaner/CleanerServiceTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/cleaner/CleanerServiceTests.java index e9b0f4f62c8..44dd709d0bf 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/cleaner/CleanerServiceTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/cleaner/CleanerServiceTests.java @@ -8,7 +8,7 @@ package org.elasticsearch.xpack.monitoring.cleaner; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.threadpool.TestThreadPool; import org.elasticsearch.threadpool.ThreadPool; diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/cleaner/local/LocalIndicesCleanerTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/cleaner/local/LocalIndicesCleanerTests.java index 7a5df1ab5db..d09605812be 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/cleaner/local/LocalIndicesCleanerTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/cleaner/local/LocalIndicesCleanerTests.java @@ -33,7 +33,7 @@ public class LocalIndicesCleanerTests extends AbstractIndicesCleanerTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put("xpack.monitoring.collection.exporters._local.type", LocalExporter.TYPE) + .put("xpack.monitoring.exporters._local.type", LocalExporter.TYPE) .build(); } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/security/MonitoringSettingsFilterTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/security/MonitoringSettingsFilterTests.java index c2a4a1bba6d..9f19aa81adb 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/security/MonitoringSettingsFilterTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/security/MonitoringSettingsFilterTests.java @@ -35,13 +35,13 @@ public class MonitoringSettingsFilterTests extends MonitoringIntegTestCase { .put(super.nodeSettings(nodeOrdinal)) .put(NetworkModule.HTTP_ENABLED.getKey(), true) .put(MonitoringSettings.INTERVAL.getKey(), "-1") - .put("xpack.monitoring.collection.exporters._http.type", "http") - .put("xpack.monitoring.collection.exporters._http.enabled", false) - .put("xpack.monitoring.collection.exporters._http.auth.username", "_user") - .put("xpack.monitoring.collection.exporters._http.auth.password", "_passwd") - .put("xpack.monitoring.collection.exporters._http.ssl.truststore.path", "/path/to/truststore") - .put("xpack.monitoring.collection.exporters._http.ssl.truststore.password", "_passwd") - .put("xpack.monitoring.collection.exporters._http.ssl.hostname_verification", true) + .put("xpack.monitoring.exporters._http.type", "http") + .put("xpack.monitoring.exporters._http.enabled", false) + .put("xpack.monitoring.exporters._http.auth.username", "_user") + .put("xpack.monitoring.exporters._http.auth.password", "_passwd") + .put("xpack.monitoring.exporters._http.ssl.truststore.path", "/path/to/truststore") + .put("xpack.monitoring.exporters._http.ssl.truststore.password", "_passwd") + .put("xpack.monitoring.exporters._http.ssl.hostname_verification", true) .build(); } @@ -69,13 +69,13 @@ public class MonitoringSettingsFilterTests extends MonitoringIntegTestCase { for (Object node : nodes.values()) { @SuppressWarnings("unchecked") Map settings = (Map) ((Map) node).get("settings"); - assertThat(extractValue("xpack.monitoring.collection.exporters._http.type", settings), equalTo("http")); - assertThat(extractValue("xpack.monitoring.collection.exporters._http.enabled", settings), equalTo("false")); - assertNullSetting(settings, "xpack.monitoring.collection.exporters._http.auth.username"); - assertNullSetting(settings, "xpack.monitoring.collection.exporters._http.auth.password"); - assertNullSetting(settings, "xpack.monitoring.collection.exporters._http.ssl.truststore.path"); - assertNullSetting(settings, "xpack.monitoring.collection.exporters._http.ssl.truststore.password"); - assertNullSetting(settings, "xpack.monitoring.collection.exporters._http.ssl.hostname_verification"); + assertThat(extractValue("xpack.monitoring.exporters._http.type", settings), equalTo("http")); + assertThat(extractValue("xpack.monitoring.exporters._http.enabled", settings), equalTo("false")); + assertNullSetting(settings, "xpack.monitoring.exporters._http.auth.username"); + assertNullSetting(settings, "xpack.monitoring.exporters._http.auth.password"); + assertNullSetting(settings, "xpack.monitoring.exporters._http.ssl.truststore.path"); + assertNullSetting(settings, "xpack.monitoring.exporters._http.ssl.truststore.password"); + assertNullSetting(settings, "xpack.monitoring.exporters._http.ssl.hostname_verification"); } } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/Security.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/Security.java index e9ef647a048..06a75ab43fa 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/Security.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/Security.java @@ -25,7 +25,6 @@ import org.elasticsearch.action.support.ActionFilter; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.Booleans; import org.elasticsearch.common.Strings; -import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.inject.util.Providers; import org.elasticsearch.common.logging.ESLogger; @@ -40,7 +39,7 @@ import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.env.Environment; import org.elasticsearch.index.IndexModule; import org.elasticsearch.ingest.Processor; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.plugins.ActionPlugin; import org.elasticsearch.plugins.IngestPlugin; import org.elasticsearch.rest.RestHandler; @@ -112,6 +111,7 @@ import org.elasticsearch.xpack.security.rest.action.user.RestGetUsersAction; import org.elasticsearch.xpack.security.rest.action.user.RestPutUserAction; import org.elasticsearch.xpack.security.ssl.ClientSSLService; import org.elasticsearch.xpack.security.ssl.SSLConfiguration; +import org.elasticsearch.xpack.security.ssl.SSLConfigurationReloader; import org.elasticsearch.xpack.security.ssl.ServerSSLService; import org.elasticsearch.xpack.security.support.OptionalSettings; import org.elasticsearch.xpack.security.transport.SecurityClientTransportService; @@ -186,8 +186,7 @@ public class Security implements ActionPlugin, IngestPlugin { modules.add(b -> { // for transport client we still must inject these ssl classes with guice b.bind(ServerSSLService.class).toProvider(Providers.of(null)); - b.bind(ClientSSLService.class).toInstance( - new ClientSSLService(settings, null, new SSLConfiguration.Global(settings), null)); + b.bind(ClientSSLService.class).toInstance(new ClientSSLService(settings, null, new SSLConfiguration.Global(settings))); }); return modules; @@ -233,8 +232,12 @@ public class Security implements ActionPlugin, IngestPlugin { components.add(securityContext); final SSLConfiguration.Global globalSslConfig = new SSLConfiguration.Global(settings); - final ClientSSLService clientSSLService = new ClientSSLService(settings, env, globalSslConfig, resourceWatcherService); - final ServerSSLService serverSSLService = new ServerSSLService(settings, env, globalSslConfig, resourceWatcherService); + final ClientSSLService clientSSLService = new ClientSSLService(settings, env, globalSslConfig); + final ServerSSLService serverSSLService = new ServerSSLService(settings, env, globalSslConfig); + // just create the reloader as it will register itself as a listener to the ssl service and nothing else depends on it + // IMPORTANT: if the reloader construction is moved to later, then it needs to be updated to ensure any SSLContexts that have been + // loaded by the services are also monitored by the reloader! + new SSLConfigurationReloader(settings, env, serverSSLService, clientSSLService, resourceWatcherService); components.add(clientSSLService); components.add(serverSSLService); @@ -330,7 +333,10 @@ public class Security implements ActionPlugin, IngestPlugin { public Settings additionalSettings() { if (enabled == false) { - return Settings.EMPTY; + return Settings.builder() + .put(NetworkModule.HTTP_TYPE_KEY, "netty3") + .put(NetworkModule.TRANSPORT_TYPE_KEY, "netty3") + .build(); } return additionalSettings(settings); diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/SecurityFeatureSet.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/SecurityFeatureSet.java index 14fb4070264..4c58cf22f4e 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/SecurityFeatureSet.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/SecurityFeatureSet.java @@ -10,14 +10,11 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.security.audit.AuditTrailService; -import org.elasticsearch.xpack.security.authc.Realm; import org.elasticsearch.xpack.security.authc.Realms; -import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm; import org.elasticsearch.xpack.XPackFeatureSet; import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore; import org.elasticsearch.xpack.security.authz.store.RolesStore; @@ -25,20 +22,20 @@ import org.elasticsearch.xpack.security.crypto.CryptoService; import org.elasticsearch.xpack.security.transport.filter.IPFilter; import org.elasticsearch.xpack.security.transport.netty3.SecurityNetty3HttpServerTransport; import org.elasticsearch.xpack.security.transport.netty3.SecurityNetty3Transport; +import org.elasticsearch.xpack.security.user.AnonymousUser; import java.io.IOException; -import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.stream.Collectors; /** * */ public class SecurityFeatureSet implements XPackFeatureSet { + private static final Map DISABLED_FEATURE_MAP = Collections.singletonMap("enabled", false); + private final Settings settings; private final boolean enabled; private final XPackLicenseState licenseState; @@ -91,28 +88,22 @@ public class SecurityFeatureSet implements XPackFeatureSet { @Override public XPackFeatureSet.Usage usage() { - List> enabledRealms = buildEnabledRealms(realms); + Map realmsUsage = buildRealmsUsage(realms); Map rolesStoreUsage = rolesStoreUsage(rolesStore); Map sslUsage = sslUsage(settings); Map auditUsage = auditUsage(auditTrailService); Map ipFilterUsage = ipFilterUsage(ipFilter); - boolean hasSystemKey = systemKeyUsage(cryptoService); - return new Usage(available(), enabled(), enabledRealms, rolesStoreUsage, sslUsage, auditUsage, ipFilterUsage, hasSystemKey); + Map systemKeyUsage = systemKeyUsage(cryptoService); + Map anonymousUsage = Collections.singletonMap("enabled", AnonymousUser.enabled()); + return new Usage(available(), enabled(), realmsUsage, rolesStoreUsage, sslUsage, auditUsage, ipFilterUsage, systemKeyUsage, + anonymousUsage); } - static List> buildEnabledRealms(Realms realms) { + static Map buildRealmsUsage(Realms realms) { if (realms == null) { - return Collections.emptyList(); + return Collections.emptyMap(); } - List> enabledRealms = new ArrayList<>(); - for (Realm realm : realms) { - if (realm instanceof ReservedRealm) { - continue; // we don't need usage of this one - } - Map stats = realm.usageStats(); - enabledRealms.add(stats); - } - return enabledRealms; + return realms.usageStats(); } static Map rolesStoreUsage(@Nullable RolesStore rolesStore) { @@ -131,82 +122,88 @@ public class SecurityFeatureSet implements XPackFeatureSet { static Map auditUsage(@Nullable AuditTrailService auditTrailService) { if (auditTrailService == null) { - return Collections.emptyMap(); + return DISABLED_FEATURE_MAP; } return auditTrailService.usageStats(); } static Map ipFilterUsage(@Nullable IPFilter ipFilter) { if (ipFilter == null) { - return Collections.emptyMap(); + return IPFilter.DISABLED_USAGE_STATS; } return ipFilter.usageStats(); } - static boolean systemKeyUsage(CryptoService cryptoService) { + static Map systemKeyUsage(CryptoService cryptoService) { // we can piggy back on the encryption enabled method as it is only enabled if there is a system key - return cryptoService != null && cryptoService.isEncryptionEnabled(); + return Collections.singletonMap("enabled", cryptoService != null && cryptoService.isEncryptionEnabled()); } static class Usage extends XPackFeatureSet.Usage { - private static final String ENABLED_REALMS_XFIELD = "enabled_realms"; + private static final String REALMS_XFIELD = "realms"; private static final String ROLES_XFIELD = "roles"; private static final String SSL_XFIELD = "ssl"; private static final String AUDIT_XFIELD = "audit"; private static final String IP_FILTER_XFIELD = "ipfilter"; private static final String SYSTEM_KEY_XFIELD = "system_key"; + private static final String ANONYMOUS_XFIELD = "anonymous"; - private List> enabledRealms; + private Map realmsUsage; private Map rolesStoreUsage; private Map sslUsage; private Map auditUsage; private Map ipFilterUsage; - private boolean hasSystemKey; + private Map systemKeyUsage; + private Map anonymousUsage; public Usage(StreamInput in) throws IOException { super(in); - enabledRealms = in.readList(StreamInput::readMap); + realmsUsage = in.readMap(); rolesStoreUsage = in.readMap(); sslUsage = in.readMap(); auditUsage = in.readMap(); ipFilterUsage = in.readMap(); - hasSystemKey = in.readBoolean(); + systemKeyUsage = in.readMap(); + anonymousUsage = in.readMap(); } - public Usage(boolean available, boolean enabled, List> enabledRealms, Map rolesStoreUsage, + public Usage(boolean available, boolean enabled, Map realmsUsage, Map rolesStoreUsage, Map sslUsage, Map auditUsage, Map ipFilterUsage, - boolean hasSystemKey) { + Map systemKeyUsage, Map anonymousUsage) { super(Security.NAME, available, enabled); - this.enabledRealms = enabledRealms; + this.realmsUsage = realmsUsage; this.rolesStoreUsage = rolesStoreUsage; this.sslUsage = sslUsage; this.auditUsage = auditUsage; this.ipFilterUsage = ipFilterUsage; - this.hasSystemKey = hasSystemKey; + this.systemKeyUsage = systemKeyUsage; + this.anonymousUsage = anonymousUsage; } @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); - out.writeList(enabledRealms.stream().map((m) -> (Writeable) o -> o.writeMap(m)).collect(Collectors.toList())); + out.writeMap(realmsUsage); out.writeMap(rolesStoreUsage); out.writeMap(sslUsage); out.writeMap(auditUsage); out.writeMap(ipFilterUsage); - out.writeBoolean(hasSystemKey); + out.writeMap(systemKeyUsage); + out.writeMap(anonymousUsage); } @Override protected void innerXContent(XContentBuilder builder, Params params) throws IOException { super.innerXContent(builder, params); if (enabled) { - builder.field(ENABLED_REALMS_XFIELD, enabledRealms); + builder.field(REALMS_XFIELD, realmsUsage); builder.field(ROLES_XFIELD, rolesStoreUsage); builder.field(SSL_XFIELD, sslUsage); builder.field(AUDIT_XFIELD, auditUsage); builder.field(IP_FILTER_XFIELD, ipFilterUsage); - builder.field(SYSTEM_KEY_XFIELD, hasSystemKey); + builder.field(SYSTEM_KEY_XFIELD, systemKeyUsage); + builder.field(ANONYMOUS_XFIELD, anonymousUsage); } } } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilter.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilter.java index 0d87c1c3260..a75f3ecd208 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilter.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilter.java @@ -18,7 +18,7 @@ import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; -import org.elasticsearch.license.plugin.core.LicenseUtils; +import org.elasticsearch.license.LicenseUtils; import org.elasticsearch.xpack.security.Security; import org.elasticsearch.xpack.security.SecurityContext; import org.elasticsearch.xpack.security.action.SecurityActionMapper; @@ -33,7 +33,7 @@ import org.elasticsearch.xpack.security.audit.AuditTrail; import org.elasticsearch.xpack.security.authz.AuthorizationUtils; import org.elasticsearch.xpack.security.authz.privilege.HealthAndStatsPrivilege; import org.elasticsearch.xpack.security.crypto.CryptoService; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditTrailService.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditTrailService.java index e78d48ade51..6d414c91c8d 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditTrailService.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditTrailService.java @@ -13,7 +13,7 @@ import java.util.Map; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.transport.TransportMessage; import org.elasticsearch.xpack.security.Security; @@ -26,6 +26,8 @@ import org.elasticsearch.xpack.security.user.User; */ public class AuditTrailService extends AbstractComponent implements AuditTrail { + public static final Map DISABLED_USAGE_STATS = Collections.singletonMap("enabled", false); + private final XPackLicenseState licenseState; final List auditTrails; diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realm.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realm.java index 078ff26c76e..c6596033be5 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realm.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realm.java @@ -89,7 +89,6 @@ public abstract class Realm implements Comparable { public Map usageStats() { Map stats = new HashMap<>(); - stats.put("type", type); stats.put("name", name()); stats.put("order", order()); return stats; diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realms.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realms.java index d54e370a9ae..adcb11d059f 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realms.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realms.java @@ -8,20 +8,23 @@ package org.elasticsearch.xpack.security.authc; import java.util.ArrayList; import java.util.Arrays; 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.Map.Entry; import java.util.Set; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; -import org.elasticsearch.license.plugin.core.XPackLicenseState; -import org.elasticsearch.license.plugin.core.XPackLicenseState.AllowedRealmType; +import org.elasticsearch.license.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState.AllowedRealmType; import org.elasticsearch.xpack.security.authc.activedirectory.ActiveDirectoryRealm; import org.elasticsearch.xpack.security.authc.esnative.NativeRealm; import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm; @@ -178,6 +181,48 @@ public class Realms extends AbstractLifecycleComponent implements Iterable usageStats() { + Map realmMap = new HashMap<>(); + for (Realm realm : this) { + if (ReservedRealm.TYPE.equals(realm.type())) { + continue; + } + realmMap.compute(realm.type(), (key, value) -> { + if (value == null) { + Object realmTypeUsage = convertToMapOfLists(realm.usageStats()); + return realmTypeUsage; + } + assert value instanceof Map; + combineMaps((Map) value, realm.usageStats()); + return value; + }); + } + + final AllowedRealmType allowedRealmType = licenseState.allowedRealmType(); + // iterate over the factories so we can add enabled & available info + for (String type : factories.keySet()) { + assert ReservedRealm.TYPE.equals(type) == false; + realmMap.compute(type, (key, value) -> { + if (value == null) { + return MapBuilder.newMapBuilder() + .put("enabled", false) + .put("available", isRealmTypeAvailable(allowedRealmType, type)) + .map(); + } + + assert value instanceof Map; + Map realmTypeUsage = (Map) value; + realmTypeUsage.put("enabled", true); + // the realms iterator returned this type so it must be enabled + assert isRealmTypeAvailable(allowedRealmType, type); + realmTypeUsage.put("available", true); + return value; + }); + } + + return realmMap; + } + /** * returns the settings for the {@link FileRealm}. Typically, this realms may or may * not be configured. If it is not configured, it will work OOTB using default settings. If it is @@ -218,4 +263,41 @@ public class Realms extends AbstractLifecycleComponent implements Iterable> settingsModule) { settingsModule.add(REALMS_GROUPS_SETTINGS); } + + private static void combineMaps(Map mapA, Map mapB) { + for (Entry entry : mapB.entrySet()) { + mapA.compute(entry.getKey(), (key, value) -> { + if (value == null) { + return new ArrayList<>(Collections.singletonList(entry.getValue())); + } + + assert value instanceof List; + ((List) value).add(entry.getValue()); + return value; + }); + } + } + + private static Map convertToMapOfLists(Map map) { + Map converted = new HashMap<>(map.size()); + for (Entry entry : map.entrySet()) { + converted.put(entry.getKey(), new ArrayList<>(Collections.singletonList(entry.getValue()))); + } + return converted; + } + + private static boolean isRealmTypeAvailable(AllowedRealmType enabledRealmType, String type) { + switch (enabledRealmType) { + case ALL: + return true; + case NONE: + return false; + case NATIVE: + return FileRealm.TYPE.equals(type) || NativeRealm.TYPE.equals(type); + case DEFAULT: + return INTERNAL_REALM_TYPES.contains(type); + default: + throw new IllegalStateException("unknown enabled realm type [" + enabledRealmType + "]"); + } + } } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/ESNativeRealmMigrateTool.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/ESNativeRealmMigrateTool.java index d100396bf47..517791211c7 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/ESNativeRealmMigrateTool.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/ESNativeRealmMigrateTool.java @@ -6,44 +6,31 @@ package org.elasticsearch.xpack.security.authc.esnative; import com.google.common.base.Charsets; -import com.google.common.base.Joiner; import javax.net.ssl.HttpsURLConnection; import joptsimple.OptionParser; import joptsimple.OptionSet; import joptsimple.OptionSpec; import org.elasticsearch.ElasticsearchException; -import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.cli.MultiCommand; import org.elasticsearch.cli.SettingCommand; import org.elasticsearch.cli.Terminal; -import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Strings; -import org.elasticsearch.common.SuppressForbidden; -import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.env.Environment; -import org.elasticsearch.node.internal.InternalSettingsPreparer; -import org.elasticsearch.xpack.security.action.role.PutRoleRequest; -import org.elasticsearch.xpack.security.action.user.PutUserRequest; import org.elasticsearch.xpack.security.authc.Realms; import org.elasticsearch.xpack.security.authc.file.FileUserPasswdStore; import org.elasticsearch.xpack.security.authc.file.FileUserRolesStore; -import org.elasticsearch.xpack.security.authc.support.Hasher; import org.elasticsearch.xpack.security.authc.support.SecuredString; import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken; import org.elasticsearch.xpack.security.authz.RoleDescriptor; -import org.elasticsearch.xpack.security.authz.permission.Permission; import org.elasticsearch.xpack.security.authz.store.FileRolesStore; import org.elasticsearch.xpack.security.ssl.ClientSSLService; import org.elasticsearch.xpack.security.ssl.SSLConfiguration; -import org.elasticsearch.xpack.security.support.NoOpLogger; -import org.elasticsearch.xpack.security.support.Validation; import java.io.BufferedReader; import java.io.IOException; @@ -52,16 +39,13 @@ import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; -import java.nio.file.Files; import java.nio.file.Path; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.regex.Pattern; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.xpack.security.Security.setting; @@ -151,7 +135,7 @@ public class ESNativeRealmMigrateTool extends MultiCommand { if ("https".equalsIgnoreCase(uri.getScheme())) { Settings sslSettings = settings.getByPrefix(setting("http.ssl.")); SSLConfiguration.Global globalConfig = new SSLConfiguration.Global(settings); - final ClientSSLService sslService = new ClientSSLService(sslSettings, env, globalConfig, null); + final ClientSSLService sslService = new ClientSSLService(sslSettings, env, globalConfig); final HttpsURLConnection httpsConn = (HttpsURLConnection) url.openConnection(); AccessController.doPrivileged(new PrivilegedAction() { @Override diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/NativeUsersStore.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/NativeUsersStore.java index 1134d0d10a8..c591ccf1e9f 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/NativeUsersStore.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/NativeUsersStore.java @@ -13,6 +13,7 @@ import com.carrotsearch.hppc.cursors.ObjectCursor; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.LatchedActionListener; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.delete.DeleteResponse; @@ -325,7 +326,7 @@ public class NativeUsersStore extends AbstractComponent implements ClusterStateL .execute(new ActionListener() { @Override public void onResponse(UpdateResponse updateResponse) { - assert updateResponse.isCreated() == false; + assert updateResponse.getResult() == DocWriteResponse.Result.UPDATED; clearRealmCache(request.username(), listener, null); } @@ -401,7 +402,7 @@ public class NativeUsersStore extends AbstractComponent implements ClusterStateL .execute(new ActionListener() { @Override public void onResponse(UpdateResponse updateResponse) { - assert updateResponse.isCreated() == false; + assert updateResponse.getResult() == DocWriteResponse.Result.UPDATED; clearRealmCache(putUserRequest.username(), listener, false); } @@ -442,12 +443,13 @@ public class NativeUsersStore extends AbstractComponent implements ClusterStateL @Override public void onResponse(IndexResponse indexResponse) { // if the document was just created, then we don't need to clear cache - if (indexResponse.isCreated()) { - listener.onResponse(indexResponse.isCreated()); + boolean created = indexResponse.getResult() == DocWriteResponse.Result.CREATED; + if (created) { + listener.onResponse(true); return; } - clearRealmCache(putUserRequest.username(), listener, indexResponse.isCreated()); + clearRealmCache(putUserRequest.username(), listener, created); } @Override @@ -471,7 +473,8 @@ public class NativeUsersStore extends AbstractComponent implements ClusterStateL client.delete(request, new ActionListener() { @Override public void onResponse(DeleteResponse deleteResponse) { - clearRealmCache(deleteUserRequest.username(), listener, deleteResponse.isFound()); + clearRealmCache(deleteUserRequest.username(), listener, + deleteResponse.getResult() == DocWriteResponse.Result.DELETED); } @Override diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileRealm.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileRealm.java index bd17724107c..43f0ed0d563 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileRealm.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileRealm.java @@ -61,7 +61,7 @@ public class FileRealm extends CachingUsernamePasswordRealm { public Map usageStats() { Map stats = super.usageStats(); // here we can determine the size based on the in mem user store - stats.put("size", UserbaseSize.resolve(userPasswdStore.usersCount())); + stats.put("size", userPasswdStore.usersCount()); return stats; } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileUserPasswdStore.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileUserPasswdStore.java index 8190ac0e692..8adb8107c2a 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileUserPasswdStore.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileUserPasswdStore.java @@ -185,7 +185,7 @@ public class FileUserPasswdStore { } } - private class FileListener extends FileChangesListener { + private class FileListener implements FileChangesListener { @Override public void onFileCreated(Path file) { onFileChanged(file); diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileUserRolesStore.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileUserRolesStore.java index aa03091112b..4f951992e76 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileUserRolesStore.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/file/FileUserRolesStore.java @@ -217,7 +217,7 @@ public class FileUserRolesStore { } } - private class FileListener extends FileChangesListener { + private class FileListener implements FileChangesListener { @Override public void onFileCreated(Path file) { onFileChanged(file); diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/CachingUsernamePasswordRealm.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/CachingUsernamePasswordRealm.java index 54e5b59b1d6..b127e0725af 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/CachingUsernamePasswordRealm.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/CachingUsernamePasswordRealm.java @@ -171,7 +171,7 @@ public abstract class CachingUsernamePasswordRealm extends UsernamePasswordRealm @Override public Map usageStats() { Map stats = super.usageStats(); - stats.put("size", UserbaseSize.resolve(cache.count()).toString()); + stats.put("size", cache.count()); return stats; } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/DnRoleMapper.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/DnRoleMapper.java index cb15f785ab4..9da361aaff1 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/DnRoleMapper.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/DnRoleMapper.java @@ -184,7 +184,7 @@ public class DnRoleMapper { } } - private class FileListener extends FileChangesListener { + private class FileListener implements FileChangesListener { @Override public void onFileCreated(Path file) { onFileChanged(file); diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UsernamePasswordRealm.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UsernamePasswordRealm.java index 1bac5a68aab..080d5aca001 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UsernamePasswordRealm.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UsernamePasswordRealm.java @@ -6,13 +6,10 @@ package org.elasticsearch.xpack.security.authc.support; import org.elasticsearch.common.util.concurrent.ThreadContext; -import org.elasticsearch.rest.RestController; import org.elasticsearch.xpack.security.authc.AuthenticationToken; import org.elasticsearch.xpack.security.authc.Realm; import org.elasticsearch.xpack.security.authc.RealmConfig; -import java.util.Locale; - /** * */ @@ -31,33 +28,4 @@ public abstract class UsernamePasswordRealm extends Realm { return token instanceof UsernamePasswordToken; } - public enum UserbaseSize { - - TINY, - SMALL, - MEDIUM, - LARGE, - XLARGE; - - public static UserbaseSize resolve(int count) { - if (count < 10) { - return TINY; - } - if (count < 100) { - return SMALL; - } - if (count < 500) { - return MEDIUM; - } - if (count < 1000) { - return LARGE; - } - return XLARGE; - } - - @Override - public String toString() { - return this == XLARGE ? "x-large" : name().toLowerCase(Locale.ROOT); - } - } } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapper.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapper.java index 4e0c25db6cc..f827fae6b05 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapper.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapper.java @@ -45,7 +45,7 @@ import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.index.shard.IndexSearcherWrapper; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.index.shard.ShardUtils; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptContext; diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/store/FileRolesStore.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/store/FileRolesStore.java index edb3f02c517..cc9b2cc0323 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/store/FileRolesStore.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/store/FileRolesStore.java @@ -287,7 +287,7 @@ public class FileRolesStore extends AbstractLifecycleComponent implements RolesS return segments; } - private class FileListener extends FileChangesListener { + private class FileListener implements FileChangesListener { @Override public void onFileCreated(Path file) { diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/store/NativeRolesStore.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/store/NativeRolesStore.java index 6324b4d8e5a..f2e2b005c9f 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/store/NativeRolesStore.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/store/NativeRolesStore.java @@ -22,6 +22,7 @@ import java.util.function.Function; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.LatchedActionListener; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.delete.DeleteResponse; @@ -273,7 +274,7 @@ public class NativeRolesStore extends AbstractComponent implements RolesStore, C client.delete(request, new ActionListener() { @Override public void onResponse(DeleteResponse deleteResponse) { - clearRoleCache(deleteRoleRequest.name(), listener, deleteResponse.isFound()); + clearRoleCache(deleteRoleRequest.name(), listener, deleteResponse.getResult() == DocWriteResponse.Result.DELETED); } @Override @@ -303,11 +304,12 @@ public class NativeRolesStore extends AbstractComponent implements RolesStore, C .execute(new ActionListener() { @Override public void onResponse(IndexResponse indexResponse) { - if (indexResponse.isCreated()) { - listener.onResponse(indexResponse.isCreated()); + boolean created = indexResponse.getResult() == DocWriteResponse.Result.CREATED; + if (created) { + listener.onResponse(true); return; } - clearRoleCache(role.getName(), listener, indexResponse.isCreated()); + clearRoleCache(role.getName(), listener, created); } @Override diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/rest/SecurityRestFilter.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/rest/SecurityRestFilter.java index a3796b60f09..60d0ca39c72 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/rest/SecurityRestFilter.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/rest/SecurityRestFilter.java @@ -19,7 +19,7 @@ import org.elasticsearch.rest.RestFilterChain; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.xpack.security.authc.AuthenticationService; import org.elasticsearch.xpack.security.authc.pki.PkiRealm; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.security.transport.netty3.SecurityNetty3HttpServerTransport; import org.elasticsearch.threadpool.ThreadPool; import org.jboss.netty.handler.ssl.SslHandler; diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/AbstractSSLService.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/AbstractSSLService.java index 69f44f75b32..80595be17d5 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/AbstractSSLService.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/AbstractSSLService.java @@ -13,13 +13,10 @@ import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.env.Environment; import org.elasticsearch.xpack.security.ssl.SSLConfiguration.Custom; import org.elasticsearch.xpack.security.ssl.SSLConfiguration.Global; -import org.elasticsearch.xpack.security.ssl.TrustConfig.Reloadable.Listener; -import org.elasticsearch.watcher.ResourceWatcherService; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLSessionContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; @@ -28,9 +25,12 @@ import java.net.InetAddress; import java.net.Socket; import java.util.ArrayList; import java.util.Arrays; -import java.util.Enumeration; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; /** @@ -39,19 +39,18 @@ import java.util.concurrent.ConcurrentHashMap; */ public abstract class AbstractSSLService extends AbstractComponent { - private final ConcurrentHashMap sslContexts = new ConcurrentHashMap<>(); private final SSLContextCacheLoader cacheLoader = new SSLContextCacheLoader(); + private final ConcurrentHashMap sslContexts = new ConcurrentHashMap<>(); protected final SSLConfiguration globalSSLConfiguration; protected final Environment env; - protected final ResourceWatcherService resourceWatcherService; - public AbstractSSLService(Settings settings, Environment environment, Global globalSSLConfiguration, - ResourceWatcherService resourceWatcherService) { + private Listener listener = Listener.NOOP; + + AbstractSSLService(Settings settings, Environment environment, Global globalSSLConfiguration) { super(settings); this.env = environment; this.globalSSLConfiguration = globalSSLConfiguration; - this.resourceWatcherService = resourceWatcherService; } public String[] supportedProtocols() { @@ -167,6 +166,27 @@ public abstract class AbstractSSLService extends AbstractComponent { return requestedCiphersList.toArray(new String[requestedCiphersList.size()]); } + /** + * Sets the listener to the value provided. Must not be {@code null} + */ + void setListener(Listener listener) { + this.listener = Objects.requireNonNull(listener); + } + + /** + * Returns the existing {@link SSLContext} for the configuration or {@code null} + */ + SSLContext getSSLContext(SSLConfiguration sslConfiguration) { + return sslContexts.get(sslConfiguration); + } + + /** + * Accessor to the loaded ssl configuration objects at the current point in time. This is useful for testing + */ + Collection getLoadedSSLConfigurations() { + return Collections.unmodifiableSet(new HashSet<>(sslContexts.keySet())); + } + private class SSLContextCacheLoader { public SSLContext load(SSLConfiguration sslConfiguration) { @@ -175,15 +195,15 @@ public abstract class AbstractSSLService extends AbstractComponent { logger.debug("using ssl settings [{}]", sslConfiguration); } - ConfigRefreshListener configRefreshListener = new ConfigRefreshListener(sslConfiguration); - TrustManager[] trustManagers = sslConfiguration.trustConfig().trustManagers(env, resourceWatcherService, configRefreshListener); - KeyManager[] keyManagers = sslConfiguration.keyConfig().keyManagers(env, resourceWatcherService, configRefreshListener); + TrustManager[] trustManagers = sslConfiguration.trustConfig().trustManagers(env); + KeyManager[] keyManagers = sslConfiguration.keyConfig().keyManagers(env); SSLContext sslContext = createSslContext(keyManagers, trustManagers, sslConfiguration.protocol(), sslConfiguration.sessionCacheSize(), sslConfiguration.sessionCacheTimeout()); // check the supported ciphers and log them here supportedCiphers(sslContext.getSupportedSSLParameters().getCipherSuites(), sslConfiguration.ciphers().toArray(Strings.EMPTY_ARRAY), true); + listener.onSSLContextLoaded(sslConfiguration); return sslContext; } @@ -202,37 +222,6 @@ public abstract class AbstractSSLService extends AbstractComponent { } } - class ConfigRefreshListener implements Listener { - - private final SSLConfiguration sslConfiguration; - - ConfigRefreshListener(SSLConfiguration sslConfiguration) { - this.sslConfiguration = sslConfiguration; - } - - @Override - public void onReload() { - SSLContext context = sslContexts.get(sslConfiguration); - if (context != null) { - invalidateSessions(context.getClientSessionContext()); - invalidateSessions(context.getServerSessionContext()); - } - } - - void invalidateSessions(SSLSessionContext sslSessionContext) { - Enumeration sessionIds = sslSessionContext.getIds(); - while (sessionIds.hasMoreElements()) { - byte[] sessionId = sessionIds.nextElement(); - sslSessionContext.getSession(sessionId).invalidate(); - } - } - - @Override - public void onFailure(Exception e) { - logger.error("failed to load updated ssl context for [{}]", e, sslConfiguration); - } - } - /** * This socket factory set the protocols and ciphers on each SSLSocket after it is created */ @@ -305,4 +294,14 @@ public abstract class AbstractSSLService extends AbstractComponent { socket.setEnabledCipherSuites(ciphers); } } + + interface Listener { + /** + * Called after a new SSLContext has been created + * @param sslConfiguration the configuration used to create the SSLContext + */ + void onSSLContextLoaded(SSLConfiguration sslConfiguration); + + Listener NOOP = (s) -> {}; + } } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/CertUtils.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/CertUtils.java index 5d85c447f68..ab0817079d7 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/CertUtils.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/CertUtils.java @@ -30,6 +30,7 @@ import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; +import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Strings; import org.elasticsearch.common.SuppressForbidden; @@ -48,6 +49,7 @@ import javax.net.ssl.X509ExtendedKeyManager; import javax.net.ssl.X509ExtendedTrustManager; import javax.security.auth.x500.X500Principal; import java.io.ByteArrayInputStream; +import java.io.InputStream; import java.io.Reader; import java.math.BigInteger; import java.net.InetAddress; @@ -84,7 +86,7 @@ class CertUtils { return PathUtils.get(Strings.cleanPath(path)); } - static X509ExtendedKeyManager[] keyManagers(Certificate[] certificateChain, PrivateKey privateKey, char[] password) throws Exception { + static X509ExtendedKeyManager keyManagers(Certificate[] certificateChain, PrivateKey privateKey, char[] password) throws Exception { KeyStore keyStore = KeyStore.getInstance("jks"); keyStore.load(null, null); // password must be non-null for keystore... @@ -92,19 +94,19 @@ class CertUtils { return keyManagers(keyStore, password, KeyManagerFactory.getDefaultAlgorithm()); } - static X509ExtendedKeyManager[] keyManagers(KeyStore keyStore, char[] password, String algorithm) throws Exception { + static X509ExtendedKeyManager keyManagers(KeyStore keyStore, char[] password, String algorithm) throws Exception { KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm); kmf.init(keyStore, password); KeyManager[] keyManagers = kmf.getKeyManagers(); for (KeyManager keyManager : keyManagers) { if (keyManager instanceof X509ExtendedKeyManager) { - return new X509ExtendedKeyManager[] { (X509ExtendedKeyManager) keyManager }; + return (X509ExtendedKeyManager) keyManager; } } throw new IllegalStateException("failed to find a X509ExtendedKeyManager"); } - static X509ExtendedTrustManager[] trustManagers(Certificate[] certificates) throws Exception { + static X509ExtendedTrustManager trustManagers(Certificate[] certificates) throws Exception { KeyStore store = KeyStore.getInstance("jks"); store.load(null, null); int counter = 0; @@ -115,13 +117,26 @@ class CertUtils { return trustManagers(store, TrustManagerFactory.getDefaultAlgorithm()); } - static X509ExtendedTrustManager[] trustManagers(KeyStore keyStore, String algorithm) throws Exception { + static X509ExtendedTrustManager trustManagers(String trustStorePath, String trustStorePassword, String trustStoreAlgorithm, + Environment env) throws Exception { + try (InputStream in = Files.newInputStream(resolvePath(trustStorePath, env))) { + // TODO remove reliance on JKS since we can PKCS12 stores... + KeyStore trustStore = KeyStore.getInstance("jks"); + assert trustStorePassword != null; + trustStore.load(in, trustStorePassword.toCharArray()); + return CertUtils.trustManagers(trustStore, trustStoreAlgorithm); + } catch (Exception e) { + throw new ElasticsearchException("failed to initialize a TrustManagerFactory", e); + } + } + + static X509ExtendedTrustManager trustManagers(KeyStore keyStore, String algorithm) throws Exception { TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); tmf.init(keyStore); TrustManager[] trustManagers = tmf.getTrustManagers(); for (TrustManager trustManager : trustManagers) { if (trustManager instanceof X509ExtendedTrustManager) { - return new X509ExtendedTrustManager[] { (X509ExtendedTrustManager) trustManager }; + return (X509ExtendedTrustManager) trustManager ; } } throw new IllegalStateException("failed to find a X509ExtendedTrustManager"); diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/ClientSSLService.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/ClientSSLService.java index 79b03c4444c..8805703c1f1 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/ClientSSLService.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/ClientSSLService.java @@ -7,14 +7,12 @@ package org.elasticsearch.xpack.security.ssl; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; -import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.xpack.security.ssl.SSLConfiguration.Global; public class ClientSSLService extends AbstractSSLService { - public ClientSSLService(Settings settings, Environment env, Global globalSSLConfiguration, - ResourceWatcherService resourceWatcherService) { - super(settings, env, globalSSLConfiguration, resourceWatcherService); + public ClientSSLService(Settings settings, Environment env, Global globalSSLConfiguration) { + super(settings, env, globalSSLConfiguration); } @Override diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/KeyConfig.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/KeyConfig.java index d62b8aa772b..31c46bc312a 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/KeyConfig.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/KeyConfig.java @@ -5,19 +5,12 @@ */ package org.elasticsearch.xpack.security.ssl; -import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.Nullable; import org.elasticsearch.env.Environment; -import org.elasticsearch.xpack.security.ssl.TrustConfig.Reloadable.Listener; -import org.elasticsearch.watcher.FileWatcher; -import org.elasticsearch.watcher.ResourceWatcherService; -import org.elasticsearch.watcher.ResourceWatcherService.Frequency; -import javax.net.ssl.KeyManager; import javax.net.ssl.SSLEngine; import javax.net.ssl.X509ExtendedKeyManager; import javax.net.ssl.X509ExtendedTrustManager; -import java.io.IOException; import java.net.Socket; import java.nio.file.Path; import java.security.Principal; @@ -28,18 +21,20 @@ import java.util.List; abstract class KeyConfig extends TrustConfig { - KeyConfig(boolean includeSystem, boolean reloadEnabled) { - super(includeSystem, reloadEnabled); + private X509ExtendedKeyManager[] keyManagers = null; + + KeyConfig(boolean includeSystem) { + super(includeSystem); } - static final KeyConfig NONE = new KeyConfig(false, false) { + static final KeyConfig NONE = new KeyConfig(false) { @Override - X509ExtendedKeyManager[] loadKeyManagers(@Nullable Environment environment) { + X509ExtendedKeyManager loadKeyManager(@Nullable Environment environment) { return null; } @Override - X509ExtendedTrustManager[] nonSystemTrustManagers(@Nullable Environment environment) { + X509ExtendedTrustManager nonSystemTrustManager(@Nullable Environment environment) { return null; } @@ -58,39 +53,48 @@ abstract class KeyConfig extends TrustConfig { } }; - final KeyManager[] keyManagers(@Nullable Environment environment, @Nullable ResourceWatcherService resourceWatcherService, - @Nullable Listener listener) { - X509ExtendedKeyManager[] keyManagers = loadKeyManagers(environment); - if (reloadEnabled && resourceWatcherService != null && listener != null) { - ReloadableX509KeyManager reloadableX509KeyManager = new ReloadableX509KeyManager(keyManagers[0], environment); - List filesToMonitor = filesToMonitor(environment); - if (filesToMonitor.isEmpty() == false) { - ChangeListener changeListener = new ChangeListener(filesToMonitor, reloadableX509KeyManager, listener); - try { - for (Path dir : directoriesToMonitor(filesToMonitor)) { - FileWatcher fileWatcher = new FileWatcher(dir); - fileWatcher.addListener(changeListener); - resourceWatcherService.add(fileWatcher, Frequency.HIGH); - } - return new X509ExtendedKeyManager[]{reloadableX509KeyManager}; - } catch (IOException e) { - throw new ElasticsearchException("failed to add file watcher", e); - } - } + final synchronized X509ExtendedKeyManager[] keyManagers(@Nullable Environment environment) { + if (keyManagers == null) { + X509ExtendedKeyManager keyManager = loadKeyManager(environment); + setKeyManagers(keyManager); } return keyManagers; } - abstract X509ExtendedKeyManager[] loadKeyManagers(@Nullable Environment environment); + @Override + synchronized void reload(@Nullable Environment environment) { + if (trustManagers == null) { + // trust managers were never initialized... do it lazily! + X509ExtendedKeyManager loadedKeyManager = loadKeyManager(environment); + setKeyManagers(loadedKeyManager); + return; + } - final class ReloadableX509KeyManager extends X509ExtendedKeyManager implements Reloadable { + X509ExtendedTrustManager loadedTrustManager = loadAndMergeIfNecessary(environment); + X509ExtendedKeyManager loadedKeyManager = loadKeyManager(environment); + setTrustManagers(loadedTrustManager); + setKeyManagers(loadedKeyManager); + } + + final synchronized void setKeyManagers(X509ExtendedKeyManager loadedKeyManager) { + if (loadedKeyManager == null) { + this.keyManagers = new X509ExtendedKeyManager[0]; + } else if (this.keyManagers == null || this.keyManagers.length == 0) { + this.keyManagers = new X509ExtendedKeyManager[] { new ReloadableX509KeyManager(loadedKeyManager) }; + } else { + assert this.keyManagers[0] instanceof ReloadableX509KeyManager; + ((ReloadableX509KeyManager)this.keyManagers[0]).setKeyManager(loadedKeyManager); + } + } + + abstract X509ExtendedKeyManager loadKeyManager(@Nullable Environment environment); + + final class ReloadableX509KeyManager extends X509ExtendedKeyManager { - private final Environment environment; private volatile X509ExtendedKeyManager keyManager; - ReloadableX509KeyManager(X509ExtendedKeyManager keyManager, @Nullable Environment environment) { + ReloadableX509KeyManager(X509ExtendedKeyManager keyManager) { this.keyManager = keyManager; - this.environment = environment; } @Override @@ -133,13 +137,13 @@ abstract class KeyConfig extends TrustConfig { return keyManager.chooseEngineServerAlias(s, principals, engine); } - public synchronized void reload() { - X509ExtendedKeyManager[] keyManagers = loadKeyManagers(environment); - this.keyManager = keyManagers[0]; - } - synchronized void setKeyManager(X509ExtendedKeyManager x509ExtendedKeyManager) { this.keyManager = x509ExtendedKeyManager; } + + // pkg-private accessor for testing + X509ExtendedKeyManager getKeyManager() { + return keyManager; + } } } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/PEMKeyConfig.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/PEMKeyConfig.java index 7a5f7c03c02..f0867e446cc 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/PEMKeyConfig.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/PEMKeyConfig.java @@ -28,23 +28,27 @@ class PEMKeyConfig extends KeyConfig { final String keyPassword; final List certPaths; - PEMKeyConfig(boolean includeSystem, boolean reloadEnabled, String keyPath, String keyPassword, List certPaths) { - super(includeSystem, reloadEnabled); + PEMKeyConfig(boolean includeSystem, String keyPath, String keyPassword, List certPaths) { + super(includeSystem); this.keyPath = keyPath; this.keyPassword = keyPassword; this.certPaths = certPaths; } @Override - X509ExtendedKeyManager[] loadKeyManagers(@Nullable Environment environment) { + X509ExtendedKeyManager loadKeyManager(@Nullable Environment environment) { + // password must be non-null for keystore... + char[] password = keyPassword == null ? new char[0] : keyPassword.toCharArray(); try { PrivateKey privateKey = readPrivateKey(CertUtils.resolvePath(keyPath, environment)); Certificate[] certificateChain = CertUtils.readCertificates(certPaths, environment); - // password must be non-null for keystore... - char[] password = keyPassword == null ? new char[0] : keyPassword.toCharArray(); return CertUtils.keyManagers(certificateChain, privateKey, password); } catch (Exception e) { throw new ElasticsearchException("failed to initialize a KeyManagerFactory", e); + } finally { + if (password != null) { + Arrays.fill(password, (char) 0); + } } } @@ -60,7 +64,7 @@ class PEMKeyConfig extends KeyConfig { } @Override - X509ExtendedTrustManager[] nonSystemTrustManagers(@Nullable Environment environment) { + X509ExtendedTrustManager nonSystemTrustManager(@Nullable Environment environment) { try { Certificate[] certificates = CertUtils.readCertificates(certPaths, environment); return CertUtils.trustManagers(certificates); diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/PEMTrustConfig.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/PEMTrustConfig.java index b9b1473a70e..5e5f42ba45c 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/PEMTrustConfig.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/PEMTrustConfig.java @@ -20,13 +20,13 @@ class PEMTrustConfig extends TrustConfig { final List caPaths; - PEMTrustConfig(boolean includeSystem, boolean reloadEnabled, List caPaths) { - super(includeSystem, reloadEnabled); + PEMTrustConfig(boolean includeSystem, List caPaths) { + super(includeSystem); this.caPaths = caPaths; } @Override - X509ExtendedTrustManager[] nonSystemTrustManagers(@Nullable Environment environment) { + X509ExtendedTrustManager nonSystemTrustManager(@Nullable Environment environment) { try { Certificate[] certificates = CertUtils.readCertificates(caPaths, environment); return CertUtils.trustManagers(certificates); diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/SSLConfiguration.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/SSLConfiguration.java index 84aa8a853eb..a61eceb3def 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/SSLConfiguration.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/SSLConfiguration.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.security.ssl; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.TrustManagerFactory; +import java.nio.file.Path; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -14,10 +16,12 @@ import java.util.Objects; import java.util.Optional; import java.util.function.Function; +import org.elasticsearch.common.Nullable; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.env.Environment; import static org.elasticsearch.xpack.security.Security.setting; import static org.elasticsearch.xpack.security.support.OptionalSettings.createInt; @@ -43,6 +47,42 @@ public abstract class SSLConfiguration { public abstract List supportedProtocols(); + /** + * Provides the list of paths to files that back this configuration + */ + public List filesToMonitor(@Nullable Environment environment) { + if (keyConfig() == trustConfig()) { + return keyConfig().filesToMonitor(environment); + } + List paths = new ArrayList<>(keyConfig().filesToMonitor(environment)); + paths.addAll(trustConfig().filesToMonitor(environment)); + return paths; + } + + /** + * Reloads the portion of this configuration that makes use of the modified file + */ + public void reload(Path file, @Nullable Environment environment) { + if (keyConfig() == trustConfig()) { + keyConfig().reload(environment); + return; + } + + for (Path path : keyConfig().filesToMonitor(environment)) { + if (file.equals(path)) { + keyConfig().reload(environment); + break; + } + } + + for (Path path : trustConfig().filesToMonitor(environment)) { + if (file.equals(path)) { + trustConfig().reload(environment); + break; + } + } + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -258,14 +298,14 @@ public abstract class SSLConfiguration { if (certPaths == null) { throw new IllegalArgumentException("you must specify the certificates to use with the key"); } - return new PEMKeyConfig(includeSystem, reloadEnabled, keyPath, keyPassword, certPaths); + return new PEMKeyConfig(includeSystem, keyPath, keyPassword, certPaths); } else { assert keyStorePath != null; String keyStorePassword = KEYSTORE_PASSWORD_SETTING.get(settings).orElse(null); String keyStoreAlgorithm = KEYSTORE_ALGORITHM_SETTING.get(settings); String keyStoreKeyPassword = KEYSTORE_KEY_PASSWORD_SETTING.get(settings).orElse(keyStorePassword); String trustStoreAlgorithm = TRUSTSTORE_ALGORITHM_SETTING.get(settings); - return new StoreKeyConfig(includeSystem, reloadEnabled, keyStorePath, keyStorePassword, keyStoreKeyPassword, + return new StoreKeyConfig(includeSystem, keyStorePath, keyStorePassword, keyStoreKeyPassword, keyStoreAlgorithm, trustStoreAlgorithm); } } @@ -274,19 +314,18 @@ public abstract class SSLConfiguration { String trustStorePath = TRUSTSTORE_PATH_SETTING.get(settings).orElse(null); List caPaths = getListOrNull(CA_PATHS_SETTING, settings); boolean includeSystem = INCLUDE_JDK_CERTS_SETTING.get(settings); - boolean reloadEnabled = RELOAD_ENABLED_SETTING.get(settings); if (trustStorePath != null && caPaths != null) { throw new IllegalArgumentException("you cannot specify a truststore and ca files"); } else if (caPaths != null) { - return new PEMTrustConfig(includeSystem, reloadEnabled, caPaths); + return new PEMTrustConfig(includeSystem, caPaths); } else if (trustStorePath != null) { String trustStorePassword = TRUSTSTORE_PASSWORD_SETTING.get(settings).orElse(null); String trustStoreAlgorithm = TRUSTSTORE_ALGORITHM_SETTING.get(settings); - return new StoreTrustConfig(includeSystem, reloadEnabled, trustStorePath, trustStorePassword, trustStoreAlgorithm); + return new StoreTrustConfig(includeSystem, trustStorePath, trustStorePassword, trustStoreAlgorithm); } else if (keyInfo != KeyConfig.NONE) { return keyInfo; } else { - return new StoreTrustConfig(includeSystem, reloadEnabled, null, null, null); + return new StoreTrustConfig(includeSystem, null, null, null); } } } @@ -413,14 +452,14 @@ public abstract class SSLConfiguration { if (certPaths == null) { throw new IllegalArgumentException("you must specify the certificates to use with the key"); } - return new PEMKeyConfig(includeSystem, reloadEnabled, keyPath, keyPassword, certPaths); + return new PEMKeyConfig(includeSystem, keyPath, keyPassword, certPaths); } else { assert keyStorePath != null; String keyStorePassword = KEYSTORE_PASSWORD_SETTING.get(settings).orElse(null); String keyStoreAlgorithm = KEYSTORE_ALGORITHM_SETTING.get(settings); String keyStoreKeyPassword = KEYSTORE_KEY_PASSWORD_SETTING.get(settings).orElse(keyStorePassword); String trustStoreAlgorithm = TRUSTSTORE_ALGORITHM_SETTING.get(settings); - return new StoreKeyConfig(includeSystem, reloadEnabled, keyStorePath, keyStorePassword, keyStoreKeyPassword, + return new StoreKeyConfig(includeSystem, keyStorePath, keyStorePassword, keyStoreKeyPassword, keyStoreAlgorithm, trustStoreAlgorithm); } } @@ -431,11 +470,11 @@ public abstract class SSLConfiguration { if (trustStorePath != null && caPaths != null) { throw new IllegalArgumentException("you cannot specify a truststore and ca files"); } else if (caPaths != null) { - return new PEMTrustConfig(INCLUDE_JDK_CERTS_SETTING.get(settings), RELOAD_ENABLED_SETTING.get(settings), caPaths); + return new PEMTrustConfig(INCLUDE_JDK_CERTS_SETTING.get(settings), caPaths); } else if (trustStorePath != null) { String trustStorePassword = TRUSTSTORE_PASSWORD_SETTING.get(settings).orElse(null); String trustStoreAlgorithm = TRUSTSTORE_ALGORITHM_SETTING.get(settings); - return new StoreTrustConfig(INCLUDE_JDK_CERTS_SETTING.get(settings), RELOAD_ENABLED_SETTING.get(settings), + return new StoreTrustConfig(INCLUDE_JDK_CERTS_SETTING.get(settings), trustStorePath, trustStorePassword, trustStoreAlgorithm); } else if (keyConfig == global.keyConfig()) { return global.trustConfig(); diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/SSLConfigurationReloader.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/SSLConfigurationReloader.java new file mode 100644 index 00000000000..49c6da03bfb --- /dev/null +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/SSLConfigurationReloader.java @@ -0,0 +1,150 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.security.ssl; + +import org.elasticsearch.common.component.AbstractComponent; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.env.Environment; +import org.elasticsearch.watcher.FileChangesListener; +import org.elasticsearch.watcher.FileWatcher; +import org.elasticsearch.watcher.ResourceWatcherService; +import org.elasticsearch.watcher.ResourceWatcherService.Frequency; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSessionContext; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * Ensures that the files backing an {@link SSLConfiguration} are monitored for changes and the underlying key/trust material is reloaded + * and the {@link SSLContext} has existing sessions invalidated to force the use of the new key/trust material + */ +public class SSLConfigurationReloader extends AbstractComponent implements AbstractSSLService.Listener { + + private final ConcurrentHashMap pathToChangeListenerMap = new ConcurrentHashMap<>(); + private final Environment environment; + private final ResourceWatcherService resourceWatcherService; + private final ServerSSLService serverSSLService; + private final ClientSSLService clientSSLService; + + public SSLConfigurationReloader(Settings settings, Environment env, ServerSSLService serverSSLService, + ClientSSLService clientSSLService, ResourceWatcherService resourceWatcher) { + super(settings); + this.environment = env; + this.resourceWatcherService = resourceWatcher; + this.serverSSLService = serverSSLService; + this.clientSSLService = clientSSLService; + serverSSLService.setListener(this); + clientSSLService.setListener(this); + } + + @Override + public void onSSLContextLoaded(SSLConfiguration sslConfiguration) { + startWatching(Collections.singleton(sslConfiguration)); + } + + /** + * Collects all of the directories that need to be monitored for the provided {@link SSLConfiguration} instances and ensures that + * they are being watched for changes + */ + private void startWatching(Collection sslConfigurations) { + for (SSLConfiguration sslConfiguration : sslConfigurations) { + for (Path directory : directoriesToMonitor(sslConfiguration.filesToMonitor(environment))) { + pathToChangeListenerMap.compute(directory, (path, listener) -> { + if (listener != null) { + listener.addSSLConfiguration(sslConfiguration); + return listener; + } + + ChangeListener changeListener = new ChangeListener(); + changeListener.addSSLConfiguration(sslConfiguration); + FileWatcher fileWatcher = new FileWatcher(path); + fileWatcher.addListener(changeListener); + try { + resourceWatcherService.add(fileWatcher, Frequency.HIGH); + return changeListener; + } catch (IOException e) { + logger.error("failed to start watching directory [{}] for ssl configuration [{}]", path, sslConfiguration); + } + return null; + }); + } + } + } + + /** + * Invalidates all of the sessions in the provided {@link SSLContext} + */ + private static void invalidateAllSessions(SSLContext context) { + if (context != null) { + invalidateSessions(context.getClientSessionContext()); + invalidateSessions(context.getServerSessionContext()); + } + } + + /** + * Invalidates the sessions in the provided {@link SSLSessionContext} + */ + private static void invalidateSessions(SSLSessionContext sslSessionContext) { + Enumeration sessionIds = sslSessionContext.getIds(); + while (sessionIds.hasMoreElements()) { + byte[] sessionId = sessionIds.nextElement(); + sslSessionContext.getSession(sessionId).invalidate(); + } + } + + /** + * Returns a unique set of directories that need to be monitored based on the provided file paths + */ + private static Set directoriesToMonitor(List filePaths) { + Set paths = new HashSet<>(); + for (Path path : filePaths) { + paths.add(path.getParent()); + } + return paths; + } + + private class ChangeListener implements FileChangesListener { + + private final CopyOnWriteArraySet sslConfigurations = new CopyOnWriteArraySet<>(); + + /** + * Adds the given ssl configuration to those that have files within the directory watched by this change listener + */ + private void addSSLConfiguration(SSLConfiguration sslConfiguration) { + sslConfigurations.add(sslConfiguration); + } + + @Override + public void onFileCreated(Path file) { + onFileChanged(file); + } + + @Override + public void onFileDeleted(Path file) { + onFileChanged(file); + } + + @Override + public void onFileChanged(Path file) { + for (SSLConfiguration sslConfiguration : sslConfigurations) { + if (sslConfiguration.filesToMonitor(environment).contains(file)) { + sslConfiguration.reload(file, environment); + invalidateAllSessions(serverSSLService.getSSLContext(sslConfiguration)); + invalidateAllSessions(clientSSLService.getSSLContext(sslConfiguration)); + } + } + } + } +} diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/ServerSSLService.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/ServerSSLService.java index 254f6870e4a..f8c0e78e2ba 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/ServerSSLService.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/ServerSSLService.java @@ -7,14 +7,12 @@ package org.elasticsearch.xpack.security.ssl; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; -import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.xpack.security.ssl.SSLConfiguration.Global; public class ServerSSLService extends AbstractSSLService { - public ServerSSLService(Settings settings, Environment environment, Global globalSSLConfiguration, - ResourceWatcherService resourceWatcherService) { - super(settings, environment, globalSSLConfiguration, resourceWatcherService); + public ServerSSLService(Settings settings, Environment environment, Global globalSSLConfiguration) { + super(settings, environment, globalSSLConfiguration); } @Override diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/StoreKeyConfig.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/StoreKeyConfig.java index 1e762dc6fed..24bf267b0d8 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/StoreKeyConfig.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/StoreKeyConfig.java @@ -26,9 +26,9 @@ class StoreKeyConfig extends KeyConfig { final String keyPassword; final String trustStoreAlgorithm; - StoreKeyConfig(boolean includeSystem, boolean reloadEnabled, String keyStorePath, String keyStorePassword, String keyPassword, + StoreKeyConfig(boolean includeSystem, String keyStorePath, String keyStorePassword, String keyPassword, String keyStoreAlgorithm, String trustStoreAlgorithm) { - super(includeSystem, reloadEnabled); + super(includeSystem); this.keyStorePath = keyStorePath; this.keyStorePassword = keyStorePassword; this.keyPassword = keyPassword; @@ -37,7 +37,7 @@ class StoreKeyConfig extends KeyConfig { } @Override - X509ExtendedKeyManager[] loadKeyManagers(@Nullable Environment environment) { + X509ExtendedKeyManager loadKeyManager(@Nullable Environment environment) { try (InputStream in = Files.newInputStream(CertUtils.resolvePath(keyStorePath, environment))) { // TODO remove reliance on JKS since we can PKCS12 stores... KeyStore ks = KeyStore.getInstance("jks"); @@ -50,14 +50,9 @@ class StoreKeyConfig extends KeyConfig { } @Override - X509ExtendedTrustManager[] nonSystemTrustManagers(@Nullable Environment environment) { - try (InputStream in = Files.newInputStream(CertUtils.resolvePath(keyStorePath, environment))) { - // TODO remove reliance on JKS since we can PKCS12 stores... - KeyStore ks = KeyStore.getInstance("jks"); - assert keyStorePassword != null; - ks.load(in, keyStorePassword.toCharArray()); - - return CertUtils.trustManagers(ks, trustStoreAlgorithm); + X509ExtendedTrustManager nonSystemTrustManager(@Nullable Environment environment) { + try { + return CertUtils.trustManagers(keyStorePath, keyStorePassword, trustStoreAlgorithm, environment); } catch (Exception e) { throw new ElasticsearchException("failed to initialize a TrustManagerFactory", e); } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/StoreTrustConfig.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/StoreTrustConfig.java index e9ac5bffc2b..db1a8ef40ea 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/StoreTrustConfig.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/StoreTrustConfig.java @@ -23,25 +23,20 @@ class StoreTrustConfig extends TrustConfig { final String trustStorePassword; final String trustStoreAlgorithm; - StoreTrustConfig(boolean includeSystem, boolean reloadEnabled, String trustStorePath, String trustStorePassword, - String trustStoreAlgorithm) { - super(includeSystem, reloadEnabled); + StoreTrustConfig(boolean includeSystem, String trustStorePath, String trustStorePassword, String trustStoreAlgorithm) { + super(includeSystem); this.trustStorePath = trustStorePath; this.trustStorePassword = trustStorePassword; this.trustStoreAlgorithm = trustStoreAlgorithm; } @Override - X509ExtendedTrustManager[] nonSystemTrustManagers(@Nullable Environment environment) { + X509ExtendedTrustManager nonSystemTrustManager(@Nullable Environment environment) { if (trustStorePath == null) { return null; } - try (InputStream in = Files.newInputStream(CertUtils.resolvePath(trustStorePath, environment))) { - // TODO remove reliance on JKS since we can PKCS12 stores... - KeyStore trustStore = KeyStore.getInstance("jks"); - assert trustStorePassword != null; - trustStore.load(in, trustStorePassword.toCharArray()); - return CertUtils.trustManagers(trustStore, trustStoreAlgorithm); + try { + return CertUtils.trustManagers(trustStorePath, trustStorePassword, trustStoreAlgorithm, environment); } catch (Exception e) { throw new ElasticsearchException("failed to initialize a TrustManagerFactory", e); } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/TrustConfig.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/TrustConfig.java index ec580993a32..1a3268b0027 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/TrustConfig.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/ssl/TrustConfig.java @@ -8,60 +8,53 @@ package org.elasticsearch.xpack.security.ssl; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.Nullable; import org.elasticsearch.env.Environment; -import org.elasticsearch.xpack.security.ssl.TrustConfig.Reloadable.Listener; -import org.elasticsearch.watcher.FileChangesListener; -import org.elasticsearch.watcher.FileWatcher; -import org.elasticsearch.watcher.ResourceWatcherService; -import org.elasticsearch.watcher.ResourceWatcherService.Frequency; import javax.net.ssl.SSLEngine; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509ExtendedTrustManager; -import javax.net.ssl.X509TrustManager; -import java.io.IOException; import java.net.Socket; -import java.nio.file.Files; import java.nio.file.Path; import java.security.KeyStore; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; -import java.util.HashSet; import java.util.List; -import java.util.Set; abstract class TrustConfig { protected final boolean includeSystem; - protected final boolean reloadEnabled; - TrustConfig(boolean includeSystem, boolean reloadEnabled) { + X509ExtendedTrustManager[] trustManagers = null; + + TrustConfig(boolean includeSystem) { this.includeSystem = includeSystem; - this.reloadEnabled = reloadEnabled; } - final TrustManager[] trustManagers(@Nullable Environment environment, @Nullable ResourceWatcherService resourceWatcherService, - @Nullable Listener listener) { - X509ExtendedTrustManager[] trustManagers = loadAndMergeIfNecessary(environment); - if (reloadEnabled && resourceWatcherService != null && listener != null) { - ReloadableTrustManager reloadableTrustManager = new ReloadableTrustManager(trustManagers[0], environment); - try { - List filesToMonitor = filesToMonitor(environment); - ChangeListener changeListener = new ChangeListener(filesToMonitor, reloadableTrustManager, listener); - for (Path path : directoriesToMonitor(filesToMonitor)) { - FileWatcher fileWatcher = new FileWatcher(path); - fileWatcher.addListener(changeListener); - resourceWatcherService.add(fileWatcher, Frequency.HIGH); - } - return new X509ExtendedTrustManager[] { reloadableTrustManager }; - } catch (IOException e) { - throw new ElasticsearchException("failed to add file watcher", e); - } + final synchronized X509ExtendedTrustManager[] trustManagers(@Nullable Environment environment) { + if (trustManagers == null) { + X509ExtendedTrustManager loadedTrustManager = loadAndMergeIfNecessary(environment); + setTrustManagers(loadedTrustManager); } return trustManagers; } - abstract X509ExtendedTrustManager[] nonSystemTrustManagers(@Nullable Environment environment); + synchronized void reload(@Nullable Environment environment) { + X509ExtendedTrustManager loadedTrustManager = loadAndMergeIfNecessary(environment); + setTrustManagers(loadedTrustManager); + } + + final synchronized void setTrustManagers(X509ExtendedTrustManager loadedTrustManager) { + if (loadedTrustManager == null) { + this.trustManagers = new X509ExtendedTrustManager[0]; + } else if (this.trustManagers == null || this.trustManagers.length == 0) { + this.trustManagers = new X509ExtendedTrustManager[] { new ReloadableTrustManager(loadedTrustManager) }; + } else { + assert this.trustManagers[0] instanceof ReloadableTrustManager; + ((ReloadableTrustManager)this.trustManagers[0]).setTrustManager(loadedTrustManager); + } + } + + abstract X509ExtendedTrustManager nonSystemTrustManager(@Nullable Environment environment); abstract void validate(); @@ -69,56 +62,47 @@ abstract class TrustConfig { public abstract String toString(); - private X509ExtendedTrustManager[] loadAndMergeIfNecessary(@Nullable Environment environment) { - X509ExtendedTrustManager[] nonSystemTrustManagers = nonSystemTrustManagers(environment); + final X509ExtendedTrustManager loadAndMergeIfNecessary(@Nullable Environment environment) { + X509ExtendedTrustManager trustManager = nonSystemTrustManager(environment); if (includeSystem) { - return mergeWithSystem(nonSystemTrustManagers); - } else if (nonSystemTrustManagers == null || nonSystemTrustManagers.length == 0) { - return new X509ExtendedTrustManager[0]; + trustManager = mergeWithSystem(trustManager); + } else if (trustManager == null) { + return null; } - return nonSystemTrustManagers; + return trustManager; } - private X509ExtendedTrustManager[] mergeWithSystem(X509ExtendedTrustManager[] nonSystemTrustManagers) { + private X509ExtendedTrustManager mergeWithSystem(X509ExtendedTrustManager nonSystemTrustManager) { try { TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init((KeyStore) null); TrustManager[] systemTrustManagers = tmf.getTrustManagers(); - X509ExtendedTrustManager system = findFirstX509TrustManager(systemTrustManagers); - if (nonSystemTrustManagers == null || nonSystemTrustManagers.length == 0) { - return new X509ExtendedTrustManager[] { system }; + X509ExtendedTrustManager system = findFirstX509ExtendedTrustManager(systemTrustManagers); + if (nonSystemTrustManager == null) { + return system; } - return new X509ExtendedTrustManager[] { new CombiningX509TrustManager(nonSystemTrustManagers[0], system) }; + return new CombiningX509TrustManager(nonSystemTrustManager, system); } catch (Exception e) { throw new ElasticsearchException("failed to initialize a trust managers", e); } } - private static X509ExtendedTrustManager findFirstX509TrustManager(TrustManager[] trustManagers) { + private static X509ExtendedTrustManager findFirstX509ExtendedTrustManager(TrustManager[] trustManagers) { X509ExtendedTrustManager x509TrustManager = null; for (TrustManager trustManager : trustManagers) { - if (trustManager instanceof X509TrustManager) { + if (trustManager instanceof X509ExtendedTrustManager) { // first one wins like in the JDK x509TrustManager = (X509ExtendedTrustManager) trustManager; break; } } if (x509TrustManager == null) { - throw new IllegalArgumentException("did not find a X509TrustManager"); + throw new IllegalArgumentException("did not find a X509ExtendedTrustManager"); } return x509TrustManager; } - static Set directoriesToMonitor(List filePaths) { - Set paths = new HashSet<>(); - for (Path path : filePaths) { - assert Files.isDirectory(path) == false; - paths.add(path.getParent()); - } - return paths; - } - private static class CombiningX509TrustManager extends X509ExtendedTrustManager { private final X509ExtendedTrustManager first; @@ -196,14 +180,12 @@ abstract class TrustConfig { } } - final class ReloadableTrustManager extends X509ExtendedTrustManager implements Reloadable { + final class ReloadableTrustManager extends X509ExtendedTrustManager { - private final Environment environment; private volatile X509ExtendedTrustManager trustManager; - ReloadableTrustManager(X509ExtendedTrustManager trustManager, @Nullable Environment environment) { + ReloadableTrustManager(X509ExtendedTrustManager trustManager) { this.trustManager = trustManager; - this.environment = environment; } @Override @@ -241,59 +223,12 @@ abstract class TrustConfig { return trustManager.getAcceptedIssuers(); } - public synchronized void reload() { - X509ExtendedTrustManager[] array = loadAndMergeIfNecessary(environment); - this.trustManager = array[0]; - } - synchronized void setTrustManager(X509ExtendedTrustManager trustManager) { this.trustManager = trustManager; } - } - interface Reloadable { - - void reload(); - - interface Listener { - - void onReload(); - - void onFailure(Exception e); - - } - } - - protected static class ChangeListener extends FileChangesListener { - - private final List paths; - private final Reloadable reloadable; - private final Listener listener; - - protected ChangeListener(List paths, Reloadable reloadable, Listener listener) { - this.paths = paths; - this.reloadable = reloadable; - this.listener = listener; - } - - @Override - public void onFileDeleted(Path file) { - onFileChanged(file); - } - - @Override - public void onFileChanged(Path file) { - for (Path path : paths) { - if (file.equals(path)) { - try { - reloadable.reload(); - listener.onReload(); - } catch (Exception e) { - listener.onFailure(e); - } - break; - } - } + X509ExtendedTrustManager getTrustManager() { + return trustManager; } } } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportService.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportService.java index ea1911b9d90..686770c2011 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportService.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportService.java @@ -14,7 +14,7 @@ import org.elasticsearch.xpack.security.authc.AuthenticationService; import org.elasticsearch.xpack.security.authz.AuthorizationService; import org.elasticsearch.xpack.security.authz.AuthorizationUtils; import org.elasticsearch.xpack.security.authz.accesscontrol.RequestContext; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.security.transport.netty3.SecurityNetty3Transport; import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/filter/IPFilter.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/filter/IPFilter.java index dc57434b81c..114ea5742bc 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/filter/IPFilter.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/filter/IPFilter.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.security.transport.filter; import org.apache.lucene.util.SetOnce; +import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; @@ -16,8 +17,7 @@ import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.TransportAddress; -import org.elasticsearch.xpack.security.audit.AuditTrail; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.transport.TransportSettings; import org.elasticsearch.xpack.security.audit.AuditTrailService; @@ -70,6 +70,10 @@ public class IPFilter { public static final Setting> HTTP_FILTER_DENY_SETTING = Setting.listSetting(setting("http.filter.deny"), HTTP_FILTER_DENY_FALLBACK, Function.identity(), Property.Dynamic, Property.NodeScope); + public static final Map DISABLED_USAGE_STATS = new MapBuilder() + .put("http", false) + .put("transport", false) + .immutableMap(); public static final SecurityIpFilterRule DEFAULT_PROFILE_ACCEPT_ALL = new SecurityIpFilterRule(true, "default:accept_all") { @Override @@ -133,8 +137,11 @@ public class IPFilter { public Map usageStats() { Map map = new HashMap<>(2); - map.put("http", Collections.singletonMap("enabled", isHttpFilterEnabled)); - map.put("transport", Collections.singletonMap("enabled", isIpFilterEnabled)); + final boolean httpFilterEnabled = isHttpFilterEnabled && (httpAllowFilter.isEmpty() == false || httpDenyFilter.isEmpty() == false); + final boolean transportFilterEnabled = isIpFilterEnabled && + (transportAllowFilter.isEmpty() == false || transportDenyFilter.isEmpty() == false); + map.put("http", httpFilterEnabled); + map.put("transport", transportFilterEnabled); return map; } diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/BulkUpdateTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/BulkUpdateTests.java index 201850afa2c..695db274857 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/BulkUpdateTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/BulkUpdateTests.java @@ -10,9 +10,9 @@ import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicHeader; import org.apache.http.util.EntityUtils; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.get.GetResponse; -import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.Response; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.settings.Settings; @@ -28,7 +28,6 @@ import java.util.Collections; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; public class BulkUpdateTests extends SecurityIntegTestCase { @@ -42,7 +41,8 @@ public class BulkUpdateTests extends SecurityIntegTestCase { } public void testThatBulkUpdateDoesNotLoseFields() { - assertThat(client().prepareIndex("index1", "type").setSource("{\"test\": \"test\"}").setId("1").get().isCreated(), is(true)); + assertEquals(DocWriteResponse.Result.CREATED, + client().prepareIndex("index1", "type").setSource("{\"test\": \"test\"}").setId("1").get().getResult()); GetResponse getResponse = internalCluster().transportClient().prepareGet("index1", "type", "1").setFields("test").get(); assertThat(getResponse.getField("test").getValue(), equalTo("test")); @@ -51,9 +51,8 @@ public class BulkUpdateTests extends SecurityIntegTestCase { } // update with a new field - boolean created = internalCluster().transportClient().prepareUpdate("index1", "type", "1").setDoc("{\"not test\": \"not test\"}") - .get().isCreated(); - assertThat(created, is(false)); + assertEquals(DocWriteResponse.Result.UPDATED, internalCluster().transportClient().prepareUpdate("index1", "type", "1") + .setDoc("{\"not test\": \"not test\"}").get().getResult()); getResponse = internalCluster().transportClient().prepareGet("index1", "type", "1").setFields("test", "not test").get(); assertThat(getResponse.getField("test").getValue(), equalTo("test")); assertThat(getResponse.getField("not test").getValue(), equalTo("not test")); @@ -65,7 +64,7 @@ public class BulkUpdateTests extends SecurityIntegTestCase { // do it in a bulk BulkResponse response = internalCluster().transportClient().prepareBulk().add(client().prepareUpdate("index1", "type", "1") .setDoc("{\"bulk updated\": \"bulk updated\"}")).get(); - assertThat(((UpdateResponse)response.getItems()[0].getResponse()).isCreated(), is(false)); + assertEquals(DocWriteResponse.Result.UPDATED, response.getItems()[0].getResponse().getResult()); getResponse = internalCluster().transportClient().prepareGet("index1", "type", "1"). setFields("test", "not test", "bulk updated").get(); assertThat(getResponse.getField("test").getValue(), equalTo("test")); diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/ClearRolesCacheTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/ClearRolesCacheTests.java index 1c3a9b5e6d5..87205804d63 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/ClearRolesCacheTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/ClearRolesCacheTests.java @@ -6,6 +6,7 @@ package org.elasticsearch.integration; import org.apache.http.message.BasicHeader; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.delete.DeleteResponse; import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.Client; @@ -119,7 +120,7 @@ public class ClearRolesCacheTests extends NativeRealmIntegTestCase { .setDoc("run_as", new String[] { role }) .setRefreshPolicy(refresh ? IMMEDIATE : NONE) .get(); - assertThat(response.isCreated(), is(false)); + assertEquals(DocWriteResponse.Result.UPDATED, response.getResult()); logger.debug("--> updated role [{}] with run_as", role); } @@ -161,7 +162,7 @@ public class ClearRolesCacheTests extends NativeRealmIntegTestCase { .prepareDelete(SecurityTemplateService.SECURITY_INDEX_NAME, NativeRolesStore.ROLE_DOC_TYPE, role) .setRefreshPolicy(refresh ? IMMEDIATE : NONE) .get(); - assertThat(response.isFound(), is(true)); + assertEquals(DocWriteResponse.Result.DELETED, response.getResult()); assertBusy(new Runnable() { @Override diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/DateMathExpressionIntegTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/DateMathExpressionIntegTests.java index 2f2003db155..06fcf206550 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/DateMathExpressionIntegTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/DateMathExpressionIntegTests.java @@ -5,6 +5,7 @@ */ package org.elasticsearch.integration; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse; import org.elasticsearch.action.get.GetResponse; @@ -69,7 +70,7 @@ public class DateMathExpressionIntegTests extends SecurityIntegTestCase { IndexResponse response = client.prepareIndex(expression, "type").setSource("foo", "bar") .setRefreshPolicy(refeshOnOperation ? IMMEDIATE : NONE).get(); - assertThat(response.isCreated(), is(true)); + assertEquals(DocWriteResponse.Result.CREATED, response.getResult()); assertThat(response.getIndex(), containsString(expectedIndexName)); if (refeshOnOperation == false) { @@ -89,7 +90,7 @@ public class DateMathExpressionIntegTests extends SecurityIntegTestCase { .setDoc("new", "field") .setRefreshPolicy(refeshOnOperation ? IMMEDIATE : NONE) .get(); - assertThat(updateResponse.isCreated(), is(false)); + assertEquals(DocWriteResponse.Result.UPDATED, updateResponse.getResult()); if (refeshOnOperation == false) { client.admin().indices().prepareRefresh(expression).get(); diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java index 0fd125570a1..d2edd52de7f 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java @@ -5,6 +5,7 @@ */ package org.elasticsearch.integration; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.action.admin.indices.get.GetIndexResponse; import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse; @@ -186,13 +187,13 @@ public class KibanaUserRoleIntegTests extends SecurityIntegTestCase { .setSource("foo", "bar") .setRefreshPolicy(IMMEDIATE) .get(); - assertThat(response.isCreated(), is(true)); + assertEquals(DocWriteResponse.Result.CREATED, response.getResult()); DeleteResponse deleteResponse = client() .filterWithHeader(singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_user", USERS_PASSWD))) .prepareDelete(index, "dashboard", response.getId()) .get(); - assertThat(deleteResponse.isFound(), is(true)); + assertEquals(DocWriteResponse.Result.DELETED, deleteResponse.getResult()); } // TODO: When we have an XPackIntegTestCase, this should test that we can send MonitoringBulkActions diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/MultipleIndicesPermissionsTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/MultipleIndicesPermissionsTests.java index a5425d3355f..5160581d6c2 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/MultipleIndicesPermissionsTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/MultipleIndicesPermissionsTests.java @@ -6,6 +6,7 @@ package org.elasticsearch.integration; import org.elasticsearch.ElasticsearchSecurityException; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchResponse; @@ -75,14 +76,14 @@ public class MultipleIndicesPermissionsTests extends SecurityIntegTestCase { .startObject() .field("name", "value") .endObject()); - assertThat(indexResponse.isCreated(), is(true)); + assertEquals(DocWriteResponse.Result.CREATED, indexResponse.getResult()); indexResponse = index("test1", "type", jsonBuilder() .startObject() .field("name", "value1") .endObject()); - assertThat(indexResponse.isCreated(), is(true)); + assertEquals(DocWriteResponse.Result.CREATED, indexResponse.getResult()); refresh(); @@ -150,13 +151,13 @@ public class MultipleIndicesPermissionsTests extends SecurityIntegTestCase { .startObject() .field("name", "value_a") .endObject()); - assertThat(indexResponse.isCreated(), is(true)); + assertEquals(DocWriteResponse.Result.CREATED, indexResponse.getResult()); indexResponse = index("b", "type", jsonBuilder() .startObject() .field("name", "value_b") .endObject()); - assertThat(indexResponse.isCreated(), is(true)); + assertEquals(DocWriteResponse.Result.CREATED, indexResponse.getResult()); refresh(); diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/SecurityCachePermissionIT.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/SecurityCachePermissionTests.java similarity index 53% rename from elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/SecurityCachePermissionIT.java rename to elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/SecurityCachePermissionTests.java index f84c4cc74ad..0b9511a5f1a 100644 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/SecurityCachePermissionIT.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/SecurityCachePermissionTests.java @@ -3,43 +3,26 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.messy.tests; +package org.elasticsearch.integration; import org.elasticsearch.ElasticsearchSecurityException; -import org.elasticsearch.Version; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.indices.TermsLookup; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.script.ScriptService; -import org.elasticsearch.script.mustache.MustachePlugin; -import org.elasticsearch.script.mustache.TemplateQueryBuilder; import org.elasticsearch.test.SecurityIntegTestCase; import org.elasticsearch.test.SecuritySettingsSource; import org.elasticsearch.xpack.security.authc.support.SecuredString; import org.junit.Before; -import org.junit.BeforeClass; - -import java.util.ArrayList; -import java.util.Collection; import static java.util.Collections.singletonMap; import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; -@SecurityIntegTestCase.AwaitsFix(bugUrl = "clean up test to not use mustache templates, otherwise needs many resources here") -public class SecurityCachePermissionIT extends SecurityIntegTestCase { - static final String READ_ONE_IDX_USER = "read_user"; - - @Override - protected Collection> nodePlugins() { - Collection> types = new ArrayList<>(); - types.addAll(super.nodePlugins()); - types.add(MustachePlugin.class); - return types; - } +public class SecurityCachePermissionTests extends SecurityIntegTestCase { + private final String READ_ONE_IDX_USER = "read_user"; + @Override public String configUsers() { return super.configUsers() @@ -61,11 +44,6 @@ public class SecurityCachePermissionIT extends SecurityIntegTestCase { + "read_one_idx:" + READ_ONE_IDX_USER + "\n"; } - @BeforeClass - public static void checkVersion() { - assumeTrue("These tests are only valid with elasticsearch 1.6.0+", Version.CURRENT.id >= 1060099); - } - @Before public void loadData() { index("data", "a", "1", "{ \"name\": \"John\", \"token\": \"token1\" }"); @@ -93,33 +71,4 @@ public class SecurityCachePermissionIT extends SecurityIntegTestCase { assertThat(e.toString(), containsString("unauthorized")); } } - - public void testThatScriptServiceDoesntLeakData() { - String source = "{\n" + - "\"template\": {\n" + - " \"query\": {\n" + - " \"exists\": {\n" + - " \"field\": \"{{name}}\"\n" + - " }\n" + - " }\n" + - " }\n" + - "}"; - - //Template template = new Template(source, INLINE, MustacheScriptEngineService.NAME, null, singletonMap("name", "token")); - SearchResponse response = client().prepareSearch("data").setTypes("a") - .setQuery(new TemplateQueryBuilder(source, ScriptService.ScriptType.INLINE, singletonMap("name", "token"))) - .execute().actionGet(); - assertThat(response.isTimedOut(), is(false)); - assertThat(response.getHits().hits().length, is(1)); - - // Repeat with unauthorized user!!!! - ElasticsearchSecurityException e = expectThrows(ElasticsearchSecurityException.class, () -> client() - .filterWithHeader(singletonMap("Authorization", basicAuthHeaderValue(READ_ONE_IDX_USER, - new SecuredString("changeme".toCharArray())))) - .prepareSearch("data").setTypes("a") - .setQuery(new TemplateQueryBuilder(source, ScriptService.ScriptType.INLINE, singletonMap("name", "token"))) - .execute().actionGet()); - assertThat(e.toString(), containsString("ElasticsearchSecurityException[action")); - assertThat(e.toString(), containsString("unauthorized")); - } } diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/ldap/AbstractAdLdapRealmTestCase.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/ldap/AbstractAdLdapRealmTestCase.java index f1334c374de..76e65e995c0 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/ldap/AbstractAdLdapRealmTestCase.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/ldap/AbstractAdLdapRealmTestCase.java @@ -6,6 +6,7 @@ package org.elasticsearch.integration.ldap; import org.elasticsearch.ElasticsearchSecurityException; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.client.Client; @@ -132,7 +133,8 @@ public abstract class AbstractAdLdapRealmTestCase extends SecurityIntegTestCase .endObject()) .execute().actionGet(); - assertThat("user " + user + " should have write access to index " + index, indexResponse.isCreated(), is(true)); + assertEquals("user " + user + " should have write access to index " + index, + DocWriteResponse.Result.CREATED, indexResponse.getResult()); refresh(); diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/plugin/core/LicensingTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/LicensingTests.java similarity index 97% rename from elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/plugin/core/LicensingTests.java rename to elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/LicensingTests.java index a60459d2b76..624eac4aa86 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/plugin/core/LicensingTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/LicensingTests.java @@ -3,12 +3,13 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import java.util.ArrayList; import java.util.Collection; import org.elasticsearch.ElasticsearchSecurityException; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse; import org.elasticsearch.action.admin.cluster.stats.ClusterStatsIndices; @@ -23,7 +24,6 @@ import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; -import org.elasticsearch.license.core.License; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.test.SecurityIntegTestCase; @@ -33,7 +33,6 @@ import org.elasticsearch.xpack.MockNetty3Plugin; import org.elasticsearch.xpack.XPackTransportClient; import org.elasticsearch.xpack.security.Security; import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken; -import org.junit.After; import org.junit.Before; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; @@ -116,14 +115,14 @@ public class LicensingTests extends SecurityIntegTestCase { .startObject() .field("name", "value") .endObject()); - assertThat(indexResponse.isCreated(), is(true)); + assertEquals(DocWriteResponse.Result.CREATED, indexResponse.getResult()); indexResponse = index("test1", "type", jsonBuilder() .startObject() .field("name", "value1") .endObject()); - assertThat(indexResponse.isCreated(), is(true)); + assertEquals(DocWriteResponse.Result.CREATED, indexResponse.getResult()); refresh(); diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/plugin/core/XPackLicenseStateTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/XPackLicenseStateTests.java similarity index 87% rename from elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/plugin/core/XPackLicenseStateTests.java rename to elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/XPackLicenseStateTests.java index 15b922b86e4..2b72f0065dd 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/plugin/core/XPackLicenseStateTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/XPackLicenseStateTests.java @@ -3,25 +3,24 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import java.util.Arrays; import java.util.function.Predicate; import java.util.stream.Collectors; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.core.License.OperationMode; -import org.elasticsearch.license.plugin.core.XPackLicenseState.AllowedRealmType; +import org.elasticsearch.license.License.OperationMode; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.monitoring.Monitoring; import org.elasticsearch.xpack.security.Security; +import org.hamcrest.Matchers; -import static org.elasticsearch.license.core.License.OperationMode.MISSING; -import static org.elasticsearch.license.core.License.OperationMode.BASIC; -import static org.elasticsearch.license.core.License.OperationMode.GOLD; -import static org.elasticsearch.license.core.License.OperationMode.PLATINUM; -import static org.elasticsearch.license.core.License.OperationMode.STANDARD; -import static org.elasticsearch.license.core.License.OperationMode.TRIAL; +import static org.elasticsearch.license.License.OperationMode.MISSING; +import static org.elasticsearch.license.License.OperationMode.BASIC; +import static org.elasticsearch.license.License.OperationMode.GOLD; +import static org.elasticsearch.license.License.OperationMode.PLATINUM; +import static org.elasticsearch.license.License.OperationMode.STANDARD; +import static org.elasticsearch.license.License.OperationMode.TRIAL; import static org.hamcrest.Matchers.is; /** @@ -68,7 +67,7 @@ public class XPackLicenseStateTests extends ESTestCase { assertThat(licenseState.isAuditingAllowed(), is(true)); assertThat(licenseState.isStatsAndHealthAllowed(), is(true)); assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(true)); - assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.ALL)); + assertThat(licenseState.allowedRealmType(), Matchers.is(XPackLicenseState.AllowedRealmType.ALL)); } public void testSecurityBasic() { @@ -80,7 +79,7 @@ public class XPackLicenseStateTests extends ESTestCase { assertThat(licenseState.isAuditingAllowed(), is(false)); assertThat(licenseState.isStatsAndHealthAllowed(), is(true)); assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(false)); - assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.NONE)); + assertThat(licenseState.allowedRealmType(), Matchers.is(XPackLicenseState.AllowedRealmType.NONE)); } public void testSecurityBasicExpired() { @@ -92,7 +91,7 @@ public class XPackLicenseStateTests extends ESTestCase { assertThat(licenseState.isAuditingAllowed(), is(false)); assertThat(licenseState.isStatsAndHealthAllowed(), is(false)); assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(false)); - assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.NONE)); + assertThat(licenseState.allowedRealmType(), Matchers.is(XPackLicenseState.AllowedRealmType.NONE)); } public void testSecurityStandard() { @@ -104,7 +103,7 @@ public class XPackLicenseStateTests extends ESTestCase { assertThat(licenseState.isAuditingAllowed(), is(false)); assertThat(licenseState.isStatsAndHealthAllowed(), is(true)); assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(false)); - assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.NATIVE)); + assertThat(licenseState.allowedRealmType(), Matchers.is(XPackLicenseState.AllowedRealmType.NATIVE)); } public void testSecurityStandardExpired() { @@ -116,7 +115,7 @@ public class XPackLicenseStateTests extends ESTestCase { assertThat(licenseState.isAuditingAllowed(), is(false)); assertThat(licenseState.isStatsAndHealthAllowed(), is(false)); assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(false)); - assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.NATIVE)); + assertThat(licenseState.allowedRealmType(), Matchers.is(XPackLicenseState.AllowedRealmType.NATIVE)); } public void testSecurityGold() { @@ -128,7 +127,7 @@ public class XPackLicenseStateTests extends ESTestCase { assertThat(licenseState.isAuditingAllowed(), is(true)); assertThat(licenseState.isStatsAndHealthAllowed(), is(true)); assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(false)); - assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.DEFAULT)); + assertThat(licenseState.allowedRealmType(), Matchers.is(XPackLicenseState.AllowedRealmType.DEFAULT)); } public void testSecurityGoldExpired() { @@ -140,7 +139,7 @@ public class XPackLicenseStateTests extends ESTestCase { assertThat(licenseState.isAuditingAllowed(), is(true)); assertThat(licenseState.isStatsAndHealthAllowed(), is(false)); assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(false)); - assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.DEFAULT)); + assertThat(licenseState.allowedRealmType(), Matchers.is(XPackLicenseState.AllowedRealmType.DEFAULT)); } public void testSecurityPlatinum() { @@ -152,7 +151,7 @@ public class XPackLicenseStateTests extends ESTestCase { assertThat(licenseState.isAuditingAllowed(), is(true)); assertThat(licenseState.isStatsAndHealthAllowed(), is(true)); assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(true)); - assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.ALL)); + assertThat(licenseState.allowedRealmType(), Matchers.is(XPackLicenseState.AllowedRealmType.ALL)); } public void testSecurityPlatinumExpired() { @@ -164,7 +163,7 @@ public class XPackLicenseStateTests extends ESTestCase { assertThat(licenseState.isAuditingAllowed(), is(true)); assertThat(licenseState.isStatsAndHealthAllowed(), is(false)); assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(true)); - assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.ALL)); + assertThat(licenseState.allowedRealmType(), Matchers.is(XPackLicenseState.AllowedRealmType.ALL)); } public void testSecurityAckBasicToNotGoldOrStandard() { diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/transport/KnownActionsTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/transport/KnownActionsTests.java index 583cbe9edcb..109e1cd4e3a 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/transport/KnownActionsTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/transport/KnownActionsTests.java @@ -9,7 +9,7 @@ import org.apache.lucene.util.IOUtils; import org.elasticsearch.action.Action; import org.elasticsearch.common.io.PathUtils; import org.elasticsearch.common.io.Streams; -import org.elasticsearch.license.plugin.Licensing; +import org.elasticsearch.license.Licensing; import org.elasticsearch.xpack.security.action.SecurityActionModule; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.test.SecurityIntegTestCase; diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityFeatureSetTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityFeatureSetTests.java index bd266827d73..be5689b8488 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityFeatureSetTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityFeatureSetTests.java @@ -8,29 +8,29 @@ package org.elasticsearch.xpack.security; import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.XPackFeatureSet; import org.elasticsearch.xpack.security.audit.AuditTrailService; -import org.elasticsearch.xpack.security.authc.Realm; import org.elasticsearch.xpack.security.authc.Realms; import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore; -import org.elasticsearch.xpack.security.authz.store.RolesStore; import org.elasticsearch.xpack.security.crypto.CryptoService; import org.elasticsearch.xpack.security.transport.filter.IPFilter; import org.elasticsearch.xpack.security.transport.netty3.SecurityNetty3HttpServerTransport; import org.elasticsearch.xpack.security.transport.netty3.SecurityNetty3Transport; +import org.elasticsearch.xpack.security.user.AnonymousUser; import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource; +import org.junit.After; import org.junit.Before; -import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.core.Is.is; import static org.mockito.Matchers.anyObject; @@ -62,6 +62,11 @@ public class SecurityFeatureSetTests extends ESTestCase { cryptoService = mock(CryptoService.class); } + @After + public void resetAnonymous() { + AnonymousUser.initialize(Settings.EMPTY); + } + public void testWritableRegistration() throws Exception { new SecurityFeatureSet(settings, licenseState, realms, namedWriteableRegistry, rolesStore, ipFilter, auditTrail, cryptoService); verify(namedWriteableRegistry).register(eq(SecurityFeatureSet.Usage.class), eq("xpack.usage.security"), anyObject()); @@ -97,11 +102,11 @@ public class SecurityFeatureSetTests extends ESTestCase { when(cryptoService.isEncryptionEnabled()).thenReturn(enabled); - assertThat(SecurityFeatureSet.systemKeyUsage(cryptoService), is(enabled)); + assertThat(SecurityFeatureSet.systemKeyUsage(cryptoService), hasEntry("enabled", enabled)); } public void testSystemKeyUsageNotEnabledIfNull() { - assertThat(SecurityFeatureSet.systemKeyUsage(null), is(false)); + assertThat(SecurityFeatureSet.systemKeyUsage(null), hasEntry("enabled", false)); } public void testUsage() throws Exception { @@ -144,19 +149,20 @@ public class SecurityFeatureSetTests extends ESTestCase { final boolean useSystemKey = randomBoolean(); when(cryptoService.isEncryptionEnabled()).thenReturn(useSystemKey); - List realmsList= new ArrayList<>(); - + Map realmsUsageStats = new HashMap<>(); for (int i = 0; i < 5; i++) { - Realm realm = mock(Realm.class); - when(realm.type()).thenReturn("type" + i); - realmsList.add(realm); Map realmUsage = new HashMap<>(); - realmUsage.put("key1", "value" + i); - realmUsage.put("key2", i); - realmUsage.put("key3", i % 2 == 0); - when(realm.usageStats()).thenReturn(realmUsage); + realmsUsageStats.put("type" + i, realmUsage); + realmUsage.put("key1", Arrays.asList("value" + i)); + realmUsage.put("key2", Arrays.asList(i)); + realmUsage.put("key3", Arrays.asList(i % 2 == 0)); + } + when(realms.usageStats()).thenReturn(realmsUsageStats); + + final boolean anonymousEnabled = randomBoolean(); + if (anonymousEnabled) { + AnonymousUser.initialize(Settings.builder().put(AnonymousUser.ROLES_SETTING.getKey(), "foo").build()); } - when(realms.iterator()).thenReturn(authcAuthzAvailable ? realmsList.iterator() : Collections.emptyIterator()); SecurityFeatureSet featureSet = new SecurityFeatureSet(settings.build(), licenseState, realms, namedWriteableRegistry, rolesStore, ipFilter, auditTrail, cryptoService); @@ -170,12 +176,12 @@ public class SecurityFeatureSetTests extends ESTestCase { if (enabled) { if (authcAuthzAvailable) { for (int i = 0; i < 5; i++) { - assertThat(source.getValue("enabled_realms." + i + ".key1"), is("value" + i)); - assertThat(source.getValue("enabled_realms." + i + ".key2"), is(i)); - assertThat(source.getValue("enabled_realms." + i + ".key3"), is(i % 2 == 0)); + assertThat(source.getValue("realms.type" + i + ".key1"), contains("value" + i)); + assertThat(source.getValue("realms.type" + i + ".key2"), contains(i)); + assertThat(source.getValue("realms.type" + i + ".key3"), contains(i % 2 == 0)); } } else { - assertThat(source.getValue("enabled_realms"), is(notNullValue())); + assertThat(source.getValue("realms"), is(notNullValue())); } // check SSL @@ -198,9 +204,17 @@ public class SecurityFeatureSetTests extends ESTestCase { } // system key - assertThat(source.getValue("system_key"), is(useSystemKey)); + assertThat(source.getValue("system_key.enabled"), is(useSystemKey)); + + // anonymous + assertThat(source.getValue("anonymous.enabled"), is(anonymousEnabled)); } else { - assertThat(source.getValue("enabled_realms"), is(nullValue())); + assertThat(source.getValue("realms"), is(nullValue())); + assertThat(source.getValue("ssl"), is(nullValue())); + assertThat(source.getValue("audit"), is(nullValue())); + assertThat(source.getValue("anonymous"), is(nullValue())); + assertThat(source.getValue("ipfilter"), is(nullValue())); + assertThat(source.getValue("roles"), is(nullValue())); } } } diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java index 63e83c52713..5d3b909d64b 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java @@ -14,14 +14,13 @@ import java.util.Map; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.xpack.extensions.XPackExtension; import org.elasticsearch.xpack.security.audit.AuditTrailService; import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail; import org.elasticsearch.xpack.security.audit.logfile.LoggingAuditTrail; -import org.elasticsearch.xpack.security.authc.AuthenticationService; import org.elasticsearch.xpack.security.authc.Realm; import org.elasticsearch.xpack.security.authc.Realms; import org.elasticsearch.xpack.security.authc.file.FileRealm; diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/VersionCompatibilityTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/VersionCompatibilityTests.java index 89bbe0df04d..d378361da4a 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/VersionCompatibilityTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/VersionCompatibilityTests.java @@ -6,6 +6,7 @@ package org.elasticsearch.xpack.security; import org.elasticsearch.Version; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import static org.hamcrest.CoreMatchers.is; @@ -27,7 +28,7 @@ import static org.hamcrest.CoreMatchers.is; public class VersionCompatibilityTests extends ESTestCase { public void testCompatibility() { /** - * see https://github.com/elasticsearch/elasticsearch/issues/9372 {@link org.elasticsearch.license.plugin.core.XPackLicenseState} + * see https://github.com/elasticsearch/elasticsearch/issues/9372 {@link XPackLicenseState} * Once es core supports merging cluster level custom metadata (licenses in our case), the tribe node will see some license * coming from the tribe and everything will be ok. * diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilterTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilterTests.java index 7ba58060678..6019d77f682 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilterTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilterTests.java @@ -27,7 +27,7 @@ import org.elasticsearch.xpack.security.authz.AuthorizationService; import org.elasticsearch.xpack.security.user.SystemUser; import org.elasticsearch.xpack.security.user.User; import org.elasticsearch.xpack.security.crypto.CryptoService; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.junit.Before; import static org.hamcrest.Matchers.equalTo; diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/audit/AuditTrailServiceTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/audit/AuditTrailServiceTests.java index 514c29e9aa3..3b71f34cd58 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/audit/AuditTrailServiceTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/audit/AuditTrailServiceTests.java @@ -7,7 +7,7 @@ package org.elasticsearch.xpack.security.audit; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.security.user.User; import org.elasticsearch.xpack.security.authc.AuthenticationToken; import org.elasticsearch.xpack.security.transport.filter.IPFilter; @@ -18,9 +18,7 @@ import org.junit.Before; import java.net.InetAddress; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; import static java.util.Collections.unmodifiableList; import static org.mockito.Mockito.mock; diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java index 1a73410842d..64161fc7607 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java @@ -16,7 +16,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.env.Environment; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.rest.FakeRestRequest; diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java index 81faa8cc74b..eb4b8089683 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java @@ -13,8 +13,8 @@ import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm; import org.elasticsearch.xpack.security.authc.esnative.NativeRealm; import org.elasticsearch.xpack.security.authc.file.FileRealm; import org.elasticsearch.xpack.security.authc.ldap.LdapRealm; -import org.elasticsearch.license.plugin.core.XPackLicenseState; -import org.elasticsearch.license.plugin.core.XPackLicenseState.AllowedRealmType; +import org.elasticsearch.license.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState.AllowedRealmType; import org.elasticsearch.test.ESTestCase; import org.junit.Before; @@ -24,10 +24,13 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.mockito.Mockito.mock; @@ -51,6 +54,7 @@ public class RealmsTests extends ESTestCase { reservedRealm = mock(ReservedRealm.class); when(licenseState.isAuthAllowed()).thenReturn(true); when(licenseState.allowedRealmType()).thenReturn(AllowedRealmType.ALL); + when(reservedRealm.type()).thenReturn(ReservedRealm.TYPE); } public void testWithSettings() throws Exception { @@ -352,6 +356,74 @@ public class RealmsTests extends ESTestCase { assertThat(realms.iterator().hasNext(), is(false)); } + public void testUsageStats() { + // test realms with duplicate values + Settings.Builder builder = Settings.builder() + .put("path.home", createTempDir()) + .put("xpack.security.authc.realms.foo.type", "type_0") + .put("xpack.security.authc.realms.foo.order", "0") + .put("xpack.security.authc.realms.bar.type", "type_0") + .put("xpack.security.authc.realms.bar.order", "1"); + Settings settings = builder.build(); + Environment env = new Environment(settings); + Realms realms = new Realms(settings, env, factories, licenseState, reservedRealm); + realms.start(); + + Map usageStats = realms.usageStats(); + assertThat(usageStats.size(), is(factories.size())); + + // first check type_0 + assertThat(usageStats.get("type_0"), instanceOf(Map.class)); + Map type0Map = (Map) usageStats.get("type_0"); + assertThat(type0Map, hasEntry("enabled", true)); + assertThat(type0Map, hasEntry("available", true)); + assertThat((Iterable) type0Map.get("name"), contains("foo", "bar")); + assertThat((Iterable) type0Map.get("order"), contains(0, 1)); + + for (Entry entry : usageStats.entrySet()) { + String type = entry.getKey(); + if ("type_0".equals(type)) { + continue; + } + + Map typeMap = (Map) entry.getValue(); + assertThat(typeMap, hasEntry("enabled", false)); + assertThat(typeMap, hasEntry("available", true)); + assertThat(typeMap.size(), is(2)); + } + + // disable ALL using license + when(licenseState.isAuthAllowed()).thenReturn(false); + when(licenseState.allowedRealmType()).thenReturn(AllowedRealmType.NONE); + usageStats = realms.usageStats(); + assertThat(usageStats.size(), is(factories.size())); + for (Entry entry : usageStats.entrySet()) { + Map typeMap = (Map) entry.getValue(); + assertThat(typeMap, hasEntry("enabled", false)); + assertThat(typeMap, hasEntry("available", false)); + assertThat(typeMap.size(), is(2)); + } + + // check native or internal realms enabled only + when(licenseState.isAuthAllowed()).thenReturn(true); + when(licenseState.allowedRealmType()).thenReturn(randomFrom(AllowedRealmType.NATIVE, AllowedRealmType.DEFAULT)); + usageStats = realms.usageStats(); + assertThat(usageStats.size(), is(factories.size())); + for (Entry entry : usageStats.entrySet()) { + final String type = entry.getKey(); + Map typeMap = (Map) entry.getValue(); + if (FileRealm.TYPE.equals(type) || NativeRealm.TYPE.equals(type)) { + assertThat(typeMap, hasEntry("enabled", true)); + assertThat(typeMap, hasEntry("available", true)); + assertThat((Iterable) typeMap.get("name"), contains("default_" + type)); + } else { + assertThat(typeMap, hasEntry("enabled", false)); + assertThat(typeMap, hasEntry("available", false)); + assertThat(typeMap.size(), is(2)); + } + } + } + static class DummyRealm extends Realm { public DummyRealm(String type, RealmConfig config) { diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/activedirectory/AbstractActiveDirectoryIntegTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/activedirectory/AbstractActiveDirectoryIntegTests.java index ddac569df87..c17e6c5baa3 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/activedirectory/AbstractActiveDirectoryIntegTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/activedirectory/AbstractActiveDirectoryIntegTests.java @@ -43,7 +43,7 @@ public class AbstractActiveDirectoryIntegTests extends ESTestCase { } globalSettings = builder.build(); Environment environment = new Environment(globalSettings); - clientSSLService = new ClientSSLService(globalSettings, environment, new Global(globalSettings), null); + clientSSLService = new ClientSSLService(globalSettings, environment, new Global(globalSettings)); } Settings buildAdSettings(String ldapUrl, String adDomainName, String userSearchDN, LdapSearchScope scope, diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/activedirectory/ActiveDirectoryRealmTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/activedirectory/ActiveDirectoryRealmTests.java index e0c48302f72..75b1e099ee6 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/activedirectory/ActiveDirectoryRealmTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/activedirectory/ActiveDirectoryRealmTests.java @@ -31,6 +31,7 @@ import org.junit.BeforeClass; import java.util.ArrayList; import java.util.List; +import java.util.Map; import static org.elasticsearch.xpack.security.authc.ldap.support.SessionFactory.HOSTNAME_VERIFICATION_SETTING; import static org.elasticsearch.xpack.security.authc.ldap.support.SessionFactory.URLS_SETTING; @@ -38,6 +39,7 @@ import static org.hamcrest.Matchers.arrayContaining; import static org.hamcrest.Matchers.arrayContainingInAnyOrder; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.mockito.Matchers.any; @@ -226,6 +228,26 @@ public class ActiveDirectoryRealmTests extends ESTestCase { assertThat(user.roles(), arrayContainingInAnyOrder(equalTo("group_role"), equalTo("user_role"))); } + public void testRealmUsageStats() throws Exception { + String loadBalanceType = randomFrom("failover", "round_robin"); + Settings settings = settings(Settings.builder() + .put(DnRoleMapper.ROLE_MAPPING_FILE_SETTING, getDataPath("role_mapping.yml")) + .put("load_balance.type", loadBalanceType) + .build()); + RealmConfig config = new RealmConfig("testRealmUsageStats", settings, globalSettings); + ActiveDirectorySessionFactory sessionFactory = new ActiveDirectorySessionFactory(config, null); + DnRoleMapper roleMapper = new DnRoleMapper(ActiveDirectoryRealm.TYPE, config, resourceWatcherService, null); + ActiveDirectoryRealm realm = new ActiveDirectoryRealm(config, sessionFactory, roleMapper); + + Map stats = realm.usageStats(); + assertThat(stats, is(notNullValue())); + assertThat(stats, hasEntry("name", realm.name())); + assertThat(stats, hasEntry("order", realm.order())); + assertThat(stats, hasEntry("size", 0)); + assertThat(stats, hasEntry("ssl", false)); + assertThat(stats, hasEntry("load_balance_type", loadBalanceType)); + } + private Settings settings() throws Exception { return settings(Settings.EMPTY); } diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/activedirectory/ActiveDirectoryRealmUsageTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/activedirectory/ActiveDirectoryRealmUsageTests.java deleted file mode 100644 index 4347c8e9bdb..00000000000 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/activedirectory/ActiveDirectoryRealmUsageTests.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.security.authc.activedirectory; - -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.xpack.security.authc.RealmConfig; -import org.elasticsearch.xpack.security.authc.ldap.support.LdapSearchScope; -import org.elasticsearch.xpack.security.authc.support.DnRoleMapper; -import org.elasticsearch.test.junit.annotations.Network; - -import java.util.Map; - -import static org.hamcrest.Matchers.hasEntry; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.mockito.Mockito.mock; - -@Network -public class ActiveDirectoryRealmUsageTests extends AbstractActiveDirectoryIntegTests { - - public void testUsageStats() throws Exception { - String loadBalanceType = randomFrom("failover", "round_robin"); - Settings settings = Settings.builder() - .put(buildAdSettings(AD_LDAP_URL, AD_DOMAIN, "CN=Bruce Banner, CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com", - LdapSearchScope.BASE, false)) - .put("load_balance.type", loadBalanceType) - .build(); - RealmConfig config = new RealmConfig("ad-test", settings, globalSettings); - ActiveDirectorySessionFactory sessionFactory = new ActiveDirectorySessionFactory(config, clientSSLService); - ActiveDirectoryRealm realm = new ActiveDirectoryRealm(config, sessionFactory, mock(DnRoleMapper.class)); - - Map stats = realm.usageStats(); - assertThat(stats, is(notNullValue())); - assertThat(stats, hasEntry("type", "active_directory")); - assertThat(stats, hasEntry("name", "ad-test")); - assertThat(stats, hasEntry("order", realm.order())); - assertThat(stats, hasEntry("size", "tiny")); - assertThat(stats, hasEntry("ssl", true)); - assertThat(stats, hasEntry("load_balance_type", loadBalanceType)); - } -} diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/file/FileRealmTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/file/FileRealmTests.java index 007668b9bd1..f581d9d49ff 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/file/FileRealmTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/file/FileRealmTests.java @@ -10,7 +10,6 @@ import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.xpack.security.authc.RealmConfig; import org.elasticsearch.xpack.security.authc.support.Hasher; import org.elasticsearch.xpack.security.authc.support.SecuredStringTests; -import org.elasticsearch.xpack.security.authc.support.UsernamePasswordRealm; import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken; import org.elasticsearch.xpack.security.user.User; import org.elasticsearch.test.ESTestCase; @@ -177,11 +176,9 @@ public class FileRealmTests extends ESTestCase { Map usage = realm.usageStats(); assertThat(usage, is(notNullValue())); - assertThat(usage, hasEntry("type", "file")); assertThat(usage, hasEntry("name", "file-realm")); assertThat(usage, hasEntry("order", order)); - assertThat(usage, hasEntry("size", UsernamePasswordRealm.UserbaseSize.resolve(userCount))); - + assertThat(usage, hasEntry("size", userCount)); } static class UserPasswdStore extends FileUserPasswdStore { diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/GroupsResolverTestCase.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/GroupsResolverTestCase.java index d08e1758074..dde4ba5f99c 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/GroupsResolverTestCase.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/GroupsResolverTestCase.java @@ -40,7 +40,7 @@ public abstract class GroupsResolverTestCase extends ESTestCase { } Settings settings = builder.build(); Environment env = new Environment(settings); - ClientSSLService clientSSLService = new ClientSSLService(settings, env, new Global(settings), null); + ClientSSLService clientSSLService = new ClientSSLService(settings, env, new Global(settings)); LDAPURL ldapurl = new LDAPURL(ldapUrl()); LDAPConnectionOptions options = new LDAPConnectionOptions(); diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapRealmTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapRealmTests.java index a99d64373bf..08b495b30d2 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapRealmTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapRealmTests.java @@ -249,10 +249,9 @@ public class LdapRealmTests extends LdapTestCase { Map stats = realm.usageStats(); assertThat(stats, is(notNullValue())); - assertThat(stats, hasEntry("type", "ldap")); assertThat(stats, hasEntry("name", "ldap-realm")); assertThat(stats, hasEntry("order", realm.order())); - assertThat(stats, hasEntry("size", "tiny")); + assertThat(stats, hasEntry("size", 0)); assertThat(stats, hasEntry("ssl", false)); assertThat(stats, hasEntry("user_search", userSearch)); } diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactoryTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactoryTests.java index 60dfe8bbbe3..1ce62427315 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactoryTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactoryTests.java @@ -62,7 +62,7 @@ public class LdapUserSearchSessionFactoryTests extends LdapTestCase { .put("xpack.security.ssl.keystore.path", keystore) .put("xpack.security.ssl.keystore.password", "changeit") .build(); - clientSSLService = new ClientSSLService(settings, env, new Global(settings), null); + clientSSLService = new ClientSSLService(settings, env, new Global(settings)); globalSettings = Settings.builder().put("path.home", createTempDir()).build(); } diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/OpenLdapTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/OpenLdapTests.java index 66491145d82..57963d11341 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/OpenLdapTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/OpenLdapTests.java @@ -6,7 +6,6 @@ package org.elasticsearch.xpack.security.authc.ldap; import com.unboundid.ldap.sdk.LDAPException; -import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.xpack.security.authc.RealmConfig; @@ -14,7 +13,6 @@ import org.elasticsearch.xpack.security.authc.ldap.support.LdapSearchScope; import org.elasticsearch.xpack.security.authc.ldap.support.LdapSession; import org.elasticsearch.xpack.security.authc.ldap.support.LdapTestCase; import org.elasticsearch.xpack.security.authc.ldap.support.SessionFactory; -import org.elasticsearch.xpack.security.authc.support.DnRoleMapper; import org.elasticsearch.xpack.security.authc.support.SecuredStringTests; import org.elasticsearch.xpack.security.ssl.ClientSSLService; import org.elasticsearch.xpack.security.ssl.SSLConfiguration.Global; @@ -22,17 +20,11 @@ import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.junit.annotations.Network; import org.junit.Before; -import java.io.IOException; import java.nio.file.Path; -import java.util.Map; import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.core.Is.is; -import static org.mockito.Mockito.mock; @Network public class OpenLdapTests extends ESTestCase { @@ -60,7 +52,7 @@ public class OpenLdapTests extends ESTestCase { } globalSettings = builder.build(); Environment environment = new Environment(globalSettings); - clientSSLService = new ClientSSLService(globalSettings, environment, new Global(globalSettings), null); + clientSSLService = new ClientSSLService(globalSettings, environment, new Global(globalSettings)); } public void testConnect() throws Exception { @@ -96,36 +88,6 @@ public class OpenLdapTests extends ESTestCase { } } - public void testUsageStats() throws Exception { - String groupSearchBase = "ou=people,dc=oldap,dc=test,dc=elasticsearch,dc=com"; - String userTemplate = "uid={0},ou=people,dc=oldap,dc=test,dc=elasticsearch,dc=com"; - Settings.Builder settings = Settings.builder() - .put(buildLdapSettings(OPEN_LDAP_URL, userTemplate, groupSearchBase, LdapSearchScope.ONE_LEVEL)) - .put("group_search.filter", "(&(objectclass=posixGroup)(memberUID={0}))") - .put("group_search.user_attribute", "uid"); - - boolean userSearch = randomBoolean(); - if (userSearch) { - settings.put("user_search.base_dn", ""); - } - - String loadBalanceType = randomFrom("failover", "round_robin"); - settings.put("load_balance.type", loadBalanceType); - - RealmConfig config = new RealmConfig("oldap-test", settings.build(), globalSettings); - LdapSessionFactory sessionFactory = new LdapSessionFactory(config, clientSSLService); - LdapRealm realm = new LdapRealm(config, sessionFactory, mock(DnRoleMapper.class)); - - Map stats = realm.usageStats(); - assertThat(stats, is(notNullValue())); - assertThat(stats, hasEntry("size", "tiny")); - assertThat(stats, hasEntry("ssl", true)); - assertThat(stats, hasEntry("user_search", userSearch)); - assertThat(stats, hasEntry("load_balance_type", loadBalanceType)); - } - - - public void testCustomFilter() throws Exception { String groupSearchBase = "ou=people,dc=oldap,dc=test,dc=elasticsearch,dc=com"; String userTemplate = "uid={0},ou=people,dc=oldap,dc=test,dc=elasticsearch,dc=com"; diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/pki/PkiAuthenticationTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/pki/PkiAuthenticationTests.java index 22229227eef..84eeae70802 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/pki/PkiAuthenticationTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/pki/PkiAuthenticationTests.java @@ -10,6 +10,7 @@ import org.apache.http.client.methods.HttpPut; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.client.transport.NoNodeAvailableException; import org.elasticsearch.client.transport.TransportClient; @@ -79,7 +80,7 @@ public class PkiAuthenticationTests extends SecurityIntegTestCase { try (TransportClient client = createTransportClient(settings)) { client.addTransportAddress(randomFrom(internalCluster().getInstance(Transport.class).boundAddress().boundAddresses())); IndexResponse response = client.prepareIndex("foo", "bar").setSource("pki", "auth").get(); - assertThat(response.isCreated(), is(true)); + assertEquals(DocWriteResponse.Result.CREATED, response.getResult()); } } diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/support/UsernamePasswordRealmTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/support/UsernamePasswordRealmTests.java deleted file mode 100644 index 01b88d21d33..00000000000 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/support/UsernamePasswordRealmTests.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.security.authc.support; - -import org.elasticsearch.test.ESTestCase; - -import java.util.Locale; - -import static org.hamcrest.core.Is.is; - -/** - * - */ -public class UsernamePasswordRealmTests extends ESTestCase { - - public void testUserbaseScaelResolve() throws Exception { - int count = randomIntBetween(0, 1000); - UsernamePasswordRealm.UserbaseSize size = UsernamePasswordRealm.UserbaseSize.resolve(count); - if (count < 10) { - assertThat(size, is(UsernamePasswordRealm.UserbaseSize.TINY)); - } else if (count < 100) { - assertThat(size, is(UsernamePasswordRealm.UserbaseSize.SMALL)); - } else if (count < 500) { - assertThat(size, is(UsernamePasswordRealm.UserbaseSize.MEDIUM)); - } else if (count < 1000) { - assertThat(size, is(UsernamePasswordRealm.UserbaseSize.LARGE)); - } else { - assertThat(size, is(UsernamePasswordRealm.UserbaseSize.XLARGE)); - } - } - - public void testUserbaseScaleToString() throws Exception { - UsernamePasswordRealm.UserbaseSize size = randomFrom(UsernamePasswordRealm.UserbaseSize.values()); - String value = size.toString(); - if (size == UsernamePasswordRealm.UserbaseSize.XLARGE) { - assertThat(value , is("x-large")); - } else { - assertThat(value , is(size.name().toLowerCase(Locale.ROOT))); - } - } -} diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperIntegrationTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperIntegrationTests.java index 51a836dad05..92ea5be470a 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperIntegrationTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperIntegrationTests.java @@ -34,7 +34,7 @@ import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.index.query.TermQueryBuilder; import org.elasticsearch.index.shard.ShardId; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.script.ScriptService; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.IndexSettingsModule; diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperUnitTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperUnitTests.java index 3e029b98141..cd7d878b4ea 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperUnitTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperUnitTests.java @@ -35,7 +35,6 @@ import org.apache.lucene.util.BitSet; import org.apache.lucene.util.FixedBitSet; import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.SparseFixedBitSet; -import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; @@ -44,7 +43,6 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.env.Environment; import org.elasticsearch.index.Index; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.analysis.AnalysisService; @@ -61,9 +59,8 @@ import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptService; import org.elasticsearch.search.aggregations.LeafBucketCollector; -import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.xpack.security.authz.accesscontrol.DocumentSubsetReader.DocumentSubsetDirectoryReader; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.IndexSettingsModule; import org.elasticsearch.xpack.security.user.User; diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/permission/DefaultRoleTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/permission/DefaultRoleTests.java index 1261a3c49c8..c62c5e6ad23 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/permission/DefaultRoleTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/permission/DefaultRoleTests.java @@ -9,7 +9,7 @@ import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; import org.elasticsearch.action.admin.cluster.state.ClusterStateAction; import org.elasticsearch.action.admin.cluster.stats.ClusterStatsAction; import org.elasticsearch.client.Client; -import org.elasticsearch.license.plugin.action.get.GetLicenseAction; +import org.elasticsearch.license.GetLicenseAction; import org.elasticsearch.xpack.security.action.user.AuthenticateRequestBuilder; import org.elasticsearch.xpack.security.action.user.ChangePasswordRequestBuilder; import org.elasticsearch.xpack.security.authc.Authentication; diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/rest/SecurityRestFilterTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/rest/SecurityRestFilterTests.java index c9f8d291aa6..c693add0a6a 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/rest/SecurityRestFilterTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/rest/SecurityRestFilterTests.java @@ -14,7 +14,7 @@ import org.elasticsearch.rest.RestFilterChain; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.xpack.security.authc.Authentication; import org.elasticsearch.xpack.security.authc.AuthenticationService; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.threadpool.ThreadPool; import org.junit.Before; diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/ssl/ClientSSLServiceTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/ssl/ClientSSLServiceTests.java index 0ba9bb9a680..826c2e42699 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/ssl/ClientSSLServiceTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/ssl/ClientSSLServiceTests.java @@ -59,7 +59,7 @@ public class ClientSSLServiceTests extends ESTestCase { .put("xpack.security.ssl.truststore.path", testclientStore) .put("xpack.security.ssl.truststore.password", "testclient") .build(); - ClientSSLService clientSSLService = new ClientSSLService(settings, null, new Global(settings), null); + ClientSSLService clientSSLService = new ClientSSLService(settings, null, new Global(settings)); clientSSLService.createSSLEngine(); fail("expected an exception"); } catch (ElasticsearchException e) { @@ -284,7 +284,6 @@ public class ClientSSLServiceTests extends ESTestCase { } private ClientSSLService createClientSSLService(Settings settings) { - ClientSSLService clientSSLService = new ClientSSLService(settings, env, new Global(settings), null); - return clientSSLService; + return new ClientSSLService(settings, env, new Global(settings)); } } diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/ssl/SSLConfigurationReloaderTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/ssl/SSLConfigurationReloaderTests.java new file mode 100644 index 00000000000..23b162b06d1 --- /dev/null +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/ssl/SSLConfigurationReloaderTests.java @@ -0,0 +1,652 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.security.ssl; + +import org.apache.lucene.util.SetOnce; +import org.bouncycastle.openssl.jcajce.JcaPEMWriter; +import org.bouncycastle.openssl.jcajce.JcePEMEncryptorBuilder; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.env.Environment; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.threadpool.TestThreadPool; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.watcher.ResourceWatcherService; +import org.elasticsearch.xpack.security.ssl.KeyConfig.ReloadableX509KeyManager; +import org.elasticsearch.xpack.security.ssl.SSLConfiguration.Global; +import org.elasticsearch.xpack.security.ssl.TrustConfig.ReloadableTrustManager; +import org.hamcrest.Matcher; +import org.junit.After; +import org.junit.Before; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.X509ExtendedKeyManager; +import javax.net.ssl.X509ExtendedTrustManager; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; +import java.nio.file.AtomicMoveNotSupportedException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.nio.file.StandardOpenOption; +import java.nio.file.attribute.BasicFileAttributes; +import java.security.KeyPair; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiFunction; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.sameInstance; +import static org.hamcrest.core.Is.is; + +/** + * Unit tests for the reloading of SSL configuration + */ +public class SSLConfigurationReloaderTests extends ESTestCase { + + private ThreadPool threadPool; + private ResourceWatcherService resourceWatcherService; + + @Before + public void setup() { + threadPool = new TestThreadPool("reload tests"); + resourceWatcherService = + new ResourceWatcherService(Settings.builder().put("resource.reload.interval.high", "1s").build(), threadPool); + resourceWatcherService.start(); + } + + @After + public void cleanup() throws Exception { + if (threadPool != null) { + terminate(threadPool); + } + } + + /** + * Tests reloading a keystore. The contents of the keystore is used for both keystore and truststore material, so both key + * config and trust config is checked. + */ + public void testReloadingKeyStore() throws Exception { + final Path tempDir = createTempDir(); + final Path keystorePath = tempDir.resolve("testnode.jks"); + Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"), keystorePath); + final Settings settings = Settings.builder() + .put("path.home", createTempDir()) + .put("xpack.security.ssl.keystore.path", keystorePath) + .put("xpack.security.ssl.keystore.password", "testnode") + .build(); + final Environment env = randomBoolean() ? null : new Environment(settings); + + final BiFunction keyManagerPreChecks = (keyManager, config) -> { + // key manager checks + String[] aliases = keyManager.getServerAliases("RSA", null); + assertNotNull(aliases); + assertThat(aliases.length, is(1)); + assertThat(aliases[0], is("testnode")); + return null; + }; + + final SetOnce trustedCount = new SetOnce<>(); + final BiFunction trustManagerPreChecks = (trustManager, config) -> { + // trust manager checks + Certificate[] certificates = trustManager.getAcceptedIssuers(); + trustedCount.set(certificates.length); + return null; + }; + + final Runnable modifier = () -> { + try { + // modify it + KeyStore keyStore = KeyStore.getInstance("jks"); + keyStore.load(null, null); + Path updated = tempDir.resolve("updated.jks"); + try (OutputStream out = Files.newOutputStream(updated)) { + keyStore.store(out, "testnode".toCharArray()); + } + atomicMoveIfPossible(updated, keystorePath); + } catch (Exception e) { + throw new RuntimeException("modification failed", e); + } + }; + + final BiFunction trustManagerPostChecks = (updatedTrustManager, config) -> { + assertThat(trustedCount.get() - updatedTrustManager.getAcceptedIssuers().length, is(5)); + return null; + }; + validateSSLConfigurationIsReloaded(settings, env, keyManagerPreChecks, trustManagerPreChecks, modifier, (k, c) -> null, + trustManagerPostChecks); + } + + /** + * Tests the reloading of a PEM key config when the key is overwritten. The trust portion is not tested as it is not modified by this + * test. + */ + public void testPEMKeyConfigReloading() throws Exception { + Path tempDir = createTempDir(); + Path keyPath = tempDir.resolve("testnode.pem"); + Path certPath = tempDir.resolve("testnode.crt"); + Path clientCertPath = tempDir.resolve("testclient.crt"); + Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem"), keyPath); + Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"), certPath); + Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt"), clientCertPath); + final Settings settings = Settings.builder() + .put("path.home", createTempDir()) + .put("xpack.security.ssl.key.path", keyPath) + .put("xpack.security.ssl.key.password", "testnode") + .put("xpack.security.ssl.cert", certPath) + .putArray("xpack.security.ssl.ca", certPath.toString(), clientCertPath.toString()) + .build(); + final Environment env = randomBoolean() ? null : + new Environment(Settings.builder().put("path.home", createTempDir()).build()); + + final SetOnce privateKey = new SetOnce<>(); + final BiFunction keyManagerPreChecks = (keyManager, config) -> { + String[] aliases = keyManager.getServerAliases("RSA", null); + assertNotNull(aliases); + assertThat(aliases.length, is(1)); + assertThat(aliases[0], is("key")); + privateKey.set(keyManager.getPrivateKey("key")); + assertNotNull(privateKey.get()); + return null; + }; + + final KeyPair keyPair = CertUtils.generateKeyPair(randomFrom(1024, 2048)); + final Runnable modifier = () -> { + try { + // make sure we wait long enough to see a change. if time is within a second the file may not be seen as modified since the + // size is the same! + assertTrue(awaitBusy(() -> { + try { + BasicFileAttributes attributes = Files.readAttributes(keyPath, BasicFileAttributes.class); + return System.currentTimeMillis() - attributes.lastModifiedTime().toMillis() >= 1000L; + } catch (IOException e) { + throw new RuntimeException("io exception while checking time", e); + } + })); + Path updatedKeyPath = tempDir.resolve("updated.pem"); + try (OutputStream os = Files.newOutputStream(updatedKeyPath); + OutputStreamWriter osWriter = new OutputStreamWriter(os, StandardCharsets.UTF_8); + JcaPEMWriter writer = new JcaPEMWriter(osWriter)) { + writer.writeObject(keyPair, + new JcePEMEncryptorBuilder("DES-EDE3-CBC").setProvider(CertUtils.BC_PROV).build("testnode".toCharArray())); + } + atomicMoveIfPossible(updatedKeyPath, keyPath); + } catch (Exception e) { + throw new RuntimeException("failed to modify file", e); + } + }; + + final BiFunction keyManagerPostChecks = (keyManager, config) -> { + String[] aliases = keyManager.getServerAliases("RSA", null); + assertNotNull(aliases); + assertThat(aliases.length, is(1)); + assertThat(aliases[0], is("key")); + assertThat(keyManager.getPrivateKey(aliases[0]), not(equalTo(privateKey))); + assertThat(keyManager.getPrivateKey(aliases[0]), is(equalTo(keyPair.getPrivate()))); + return null; + }; + validateKeyConfigurationIsReloaded(settings, env, keyManagerPreChecks, modifier, keyManagerPostChecks); + } + + /** + * Tests the reloading of the trust config when the trust store is modified. The key config is not tested as part of this test. + */ + public void testReloadingTrustStore() throws Exception { + Path tempDir = createTempDir(); + Path trustStorePath = tempDir.resolve("testnode.jks"); + Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"), trustStorePath); + Settings settings = Settings.builder() + .put("xpack.security.ssl.truststore.path", trustStorePath) + .put("xpack.security.ssl.truststore.password", "testnode") + .put("path.home", createTempDir()) + .build(); + Environment env = randomBoolean() ? null : new Environment(settings); + + final SetOnce trustedCount = new SetOnce<>(); + final BiFunction trustManagerPreChecks = (trustManager, config) -> { + // trust manager checks + Certificate[] certificates = trustManager.getAcceptedIssuers(); + trustedCount.set(certificates.length); + return null; + }; + + + final Runnable modifier = () -> { + try { + Path updatedTruststore = tempDir.resolve("updated.jks"); + KeyStore keyStore = KeyStore.getInstance("jks"); + keyStore.load(null, null); + try (OutputStream out = Files.newOutputStream(updatedTruststore)) { + keyStore.store(out, "testnode".toCharArray()); + } + atomicMoveIfPossible(updatedTruststore, trustStorePath); + } catch (Exception e) { + throw new RuntimeException("failed to modify file", e); + } + }; + + final BiFunction trustManagerPostChecks = (updatedTrustManager, config) -> { + assertThat(trustedCount.get() - updatedTrustManager.getAcceptedIssuers().length, is(5)); + return null; + }; + + validateTrustConfigurationIsReloaded(settings, env, trustManagerPreChecks, modifier, trustManagerPostChecks); + } + + /** + * Test the reloading of a trust config that is backed by PEM certificate files. The key config is not tested as we only care about the + * trust config in this test. + */ + public void testReloadingPEMTrustConfig() throws Exception { + Path tempDir = createTempDir(); + Path clientCertPath = tempDir.resolve("testclient.crt"); + Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt"), clientCertPath); + Settings settings = Settings.builder() + .putArray("xpack.security.ssl.ca", clientCertPath.toString()) + .put("path.home", createTempDir()) + .put(Global.INCLUDE_JDK_CERTS_SETTING.getKey(), false) + .build(); + Environment env = randomBoolean() ? null : new Environment(settings); + + final BiFunction trustManagerPreChecks = (trustManager, config) -> { + // trust manager checks + Certificate[] certificates = trustManager.getAcceptedIssuers(); + assertThat(certificates.length, is(1)); + assertThat(((X509Certificate)certificates[0]).getSubjectX500Principal().getName(), containsString("Test Client")); + return null; + }; + + final Runnable modifier = () -> { + try { + Path updatedCert = tempDir.resolve("updated.crt"); + Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"), updatedCert, + StandardCopyOption.REPLACE_EXISTING); + atomicMoveIfPossible(updatedCert, clientCertPath); + } catch (Exception e) { + throw new RuntimeException("failed to modify file", e); + } + }; + + final BiFunction trustManagerPostChecks = (updatedTrustManager, config) -> { + Certificate[] updatedCerts = updatedTrustManager.getAcceptedIssuers(); + assertThat(updatedCerts.length, is(1)); + assertThat(((X509Certificate)updatedCerts[0]).getSubjectX500Principal().getName(), containsString("Test Node")); + return null; + }; + + validateTrustConfigurationIsReloaded(settings, env, trustManagerPreChecks, modifier, trustManagerPostChecks); + } + + /** + * Tests the reloading of a keystore when there is an exception during reloading. An exception is caused by truncating the keystore + * that is being monitored + */ + public void testReloadingKeyStoreException() throws Exception { + Path tempDir = createTempDir(); + Path keystorePath = tempDir.resolve("testnode.jks"); + Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"), keystorePath); + Settings settings = Settings.builder() + .put("xpack.security.ssl.keystore.path", keystorePath) + .put("xpack.security.ssl.keystore.password", "testnode") + .put("path.home", createTempDir()) + .build(); + Environment env = randomBoolean() ? null : new Environment(settings); + final Global config = new Global(settings); + final ServerSSLService serverSSLService = new ServerSSLService(settings, env, config) { + @Override + SSLContext getSSLContext(SSLConfiguration configuration) { + fail("get should not be called! [keystore reload exception]"); + return super.getSSLContext(configuration); + } + }; + final ClientSSLService clientSSLService = new ClientSSLService(settings, env, config) { + @Override + SSLContext getSSLContext(SSLConfiguration configuration) { + fail("get should not be called! [keystore reload exception]"); + return super.getSSLContext(configuration); + } + }; + final SSLConfigurationReloader reloader = + new SSLConfigurationReloader(settings, env, serverSSLService, clientSSLService, resourceWatcherService); + reloader.onSSLContextLoaded(config); + + // key manager checks + X509ExtendedKeyManager keyManager = ((ReloadableX509KeyManager)config.keyConfig().keyManagers(env)[0]).getKeyManager(); + String[] aliases = keyManager.getServerAliases("RSA", null); + assertNotNull(aliases); + assertThat(aliases.length, is(1)); + assertThat(aliases[0], is("testnode")); + PrivateKey privateKey = keyManager.getPrivateKey("testnode"); + + // truncate the keystore + try (OutputStream out = Files.newOutputStream(keystorePath, StandardOpenOption.TRUNCATE_EXISTING)) { + } + + // we intentionally don't wait here as we rely on concurrency to catch a failure + assertThat(keyManager.getServerAliases("RSA", null), equalTo(aliases)); + assertThat(keyManager.getPrivateKey("testnode"), is(equalTo(privateKey))); + } + + /** + * Tests the reloading of a key config backed by pem files when there is an exception during reloading. An exception is caused by + * truncating the key file that is being monitored + */ + public void testReloadingPEMKeyConfigException() throws Exception { + Path tempDir = createTempDir(); + Path keyPath = tempDir.resolve("testnode.pem"); + Path certPath = tempDir.resolve("testnode.crt"); + Path clientCertPath = tempDir.resolve("testclient.crt"); + Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem"), keyPath); + Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"), certPath); + Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt"), clientCertPath); + Settings settings = Settings.builder() + .put("xpack.security.ssl.key.path", keyPath) + .put("xpack.security.ssl.key.password", "testnode") + .put("xpack.security.ssl.cert", certPath) + .putArray("xpack.security.ssl.ca", certPath.toString(), clientCertPath.toString()) + .put("path.home", createTempDir()) + .build(); + Environment env = randomBoolean() ? null : new Environment(settings); + final Global config = new Global(settings); + final ServerSSLService serverSSLService = new ServerSSLService(settings, env, config) { + @Override + SSLContext getSSLContext(SSLConfiguration configuration) { + fail("get should not be called! [pem key reload exception]"); + return super.getSSLContext(configuration); + } + }; + final ClientSSLService clientSSLService = new ClientSSLService(settings, env, config) { + @Override + SSLContext getSSLContext(SSLConfiguration configuration) { + fail("get should not be called! [pem key reload exception]"); + return super.getSSLContext(configuration); + } + }; + final SSLConfigurationReloader reloader = + new SSLConfigurationReloader(settings, env, serverSSLService, clientSSLService, resourceWatcherService); + reloader.onSSLContextLoaded(config); + + X509ExtendedKeyManager keyManager = ((ReloadableX509KeyManager)config.keyConfig().keyManagers(env)[0]).getKeyManager(); + String[] aliases = keyManager.getServerAliases("RSA", null); + assertNotNull(aliases); + assertThat(aliases.length, is(1)); + assertThat(aliases[0], is("key")); + PrivateKey privateKey = keyManager.getPrivateKey("key"); + + // truncate the file + try (OutputStream os = Files.newOutputStream(keyPath, StandardOpenOption.TRUNCATE_EXISTING)) { + } + + // we intentionally don't wait here as we rely on concurrency to catch a failure + assertThat(keyManager.getServerAliases("RSA", null), equalTo(aliases)); + assertThat(keyManager.getPrivateKey("key"), is(equalTo(privateKey))); + } + + /** + * Tests the reloading of a truststore when there is an exception during reloading. An exception is caused by truncating the truststore + * that is being monitored + */ + public void testTrustStoreReloadException() throws Exception { + Path tempDir = createTempDir(); + Path trustStorePath = tempDir.resolve("testnode.jks"); + Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"), trustStorePath); + Settings settings = Settings.builder() + .put("xpack.security.ssl.truststore.path", trustStorePath) + .put("xpack.security.ssl.truststore.password", "testnode") + .put("path.home", createTempDir()) + .build(); + Environment env = randomBoolean() ? null : new Environment(settings); + final Global config = new Global(settings); + final ServerSSLService serverSSLService = new ServerSSLService(settings, env, config) { + @Override + SSLContext getSSLContext(SSLConfiguration configuration) { + fail("get should not be called! [truststore reload exception]"); + return super.getSSLContext(configuration); + } + }; + final ClientSSLService clientSSLService = new ClientSSLService(settings, env, config) { + @Override + SSLContext getSSLContext(SSLConfiguration configuration) { + fail("get should not be called! [truststore reload exception]"); + return super.getSSLContext(configuration); + } + }; + final SSLConfigurationReloader reloader = + new SSLConfigurationReloader(settings, env, serverSSLService, clientSSLService, resourceWatcherService); + reloader.onSSLContextLoaded(config); + + X509ExtendedTrustManager trustManager = ((ReloadableTrustManager)config.trustConfig().trustManagers(env)[0]).getTrustManager(); + final Certificate[] certificates = trustManager.getAcceptedIssuers(); + assertContainsCertificateWithMatchingName(certificates, containsString("Test Node")); + + // truncate the truststore + try (OutputStream os = Files.newOutputStream(trustStorePath, StandardOpenOption.TRUNCATE_EXISTING)) { + } + + // we intentionally don't wait here as we rely on concurrency to catch a failure + assertThat(trustManager.getAcceptedIssuers(), equalTo(certificates)); + assertContainsCertificateWithMatchingName(trustManager.getAcceptedIssuers(), containsString("Test Node")); + } + + /** + * Tests the reloading of a trust config backed by pem files when there is an exception during reloading. An exception is caused by + * truncating the certificate file that is being monitored + */ + public void testPEMTrustReloadException() throws Exception { + Path tempDir = createTempDir(); + Path clientCertPath = tempDir.resolve("testclient.crt"); + Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt"), clientCertPath); + Settings settings = Settings.builder() + .putArray("xpack.security.ssl.ca", clientCertPath.toString()) + .put("path.home", createTempDir()) + .build(); + Environment env = randomBoolean() ? null : new Environment(settings); + final Global config = new Global(settings); + final ServerSSLService serverSSLService = new ServerSSLService(settings, env, config) { + @Override + SSLContext getSSLContext(SSLConfiguration configuration) { + fail("get should not be called! [pem trust reload exception]"); + return super.getSSLContext(configuration); + } + }; + final ClientSSLService clientSSLService = new ClientSSLService(settings, env, config) { + @Override + SSLContext getSSLContext(SSLConfiguration configuration) { + fail("get should not be called! [pem trust reload exception]"); + return super.getSSLContext(configuration); + } + }; + final SSLConfigurationReloader reloader = + new SSLConfigurationReloader(settings, env, serverSSLService, clientSSLService, resourceWatcherService); + reloader.onSSLContextLoaded(config); + + X509ExtendedTrustManager trustManager = ((ReloadableTrustManager)config.trustConfig().trustManagers(env)[0]).getTrustManager(); + final Certificate[] certificates = trustManager.getAcceptedIssuers(); + assertContainsCertificateWithMatchingName(certificates, containsString("Test Client")); + + // write bad file + Path updatedCert = tempDir.resolve("updated.crt"); + try (OutputStream os = Files.newOutputStream(updatedCert)) { + os.write(randomByte()); + } + atomicMoveIfPossible(updatedCert, clientCertPath); + + // we intentionally don't wait here as we rely on concurrency to catch a failure + assertThat(trustManager.getAcceptedIssuers(), equalTo(certificates)); + assertContainsCertificateWithMatchingName(trustManager.getAcceptedIssuers(), containsString("Test Client")); + } + + /** + * Validates the trust configuration aspect of the SSLConfiguration is reloaded + */ + private void validateTrustConfigurationIsReloaded(Settings settings, Environment env, + BiFunction trustManagerPreChecks, + Runnable modificationFunction, + BiFunction trustManagerPostChecks) + throws Exception { + validateSSLConfigurationIsReloaded(settings, env, false, true, null, trustManagerPreChecks, modificationFunction, null, + trustManagerPostChecks); + } + + /** + * Validates the trust configuration aspect of the SSLConfiguration is reloaded + */ + private void validateKeyConfigurationIsReloaded(Settings settings, Environment env, + BiFunction keyManagerPreChecks, + Runnable modificationFunction, + BiFunction keyManagerPostChecks) + throws Exception { + validateSSLConfigurationIsReloaded(settings, env, true, false, keyManagerPreChecks, null, modificationFunction, + keyManagerPostChecks, null); + } + + /** + * Validates that both the key and trust configuration aspects of the SSLConfiguration are reloaded + */ + private void validateSSLConfigurationIsReloaded(Settings settings, Environment env, + BiFunction keyManagerPreChecks, + BiFunction trustManagerPreChecks, + Runnable modificationFunction, + BiFunction keyManagerPostChecks, + BiFunction trustManagerPostChecks) + throws Exception { + validateSSLConfigurationIsReloaded(settings, env, true, true, keyManagerPreChecks, trustManagerPreChecks, modificationFunction, + keyManagerPostChecks, trustManagerPostChecks); + } + + private void validateSSLConfigurationIsReloaded(Settings settings, Environment env, boolean checkKeys, boolean checkTrust, + BiFunction keyManagerPreChecks, + BiFunction trustManagerPreChecks, + Runnable modificationFunction, + BiFunction keyManagerPostChecks, + BiFunction trustManagerPostChecks) + throws Exception { + + final AtomicInteger serverCounter = new AtomicInteger(0); + final AtomicInteger clientCounter = new AtomicInteger(0); + final Global config = new Global(settings); + final ServerSSLService serverSSLService = new ServerSSLService(settings, env, config) { + @Override + SSLContext getSSLContext(SSLConfiguration sslConfiguration) { + serverCounter.incrementAndGet(); + return super.getSSLContext(sslConfiguration); + } + }; + final ClientSSLService clientSSLService = new ClientSSLService(settings, env, config) { + @Override + SSLContext getSSLContext(SSLConfiguration sslConfiguration) { + clientCounter.incrementAndGet(); + return super.getSSLContext(sslConfiguration); + } + }; + + final SSLConfigurationReloader reloader = + new SSLConfigurationReloader(settings, env, serverSSLService, clientSSLService, resourceWatcherService); + + final X509ExtendedKeyManager keyManager; + final X509ExtendedKeyManager[] originalKeyManagers; + if (checkKeys) { + originalKeyManagers = config.keyConfig().keyManagers(env); + assertThat(originalKeyManagers.length, is(1)); + keyManager = ((ReloadableX509KeyManager) originalKeyManagers[0]).getKeyManager(); + } else { + originalKeyManagers = null; + keyManager = null; + } + + final X509ExtendedTrustManager[] originalTrustManagers; + final X509ExtendedTrustManager trustManager; + if (checkTrust) { + originalTrustManagers = config.trustConfig().trustManagers(env); + assertThat(originalTrustManagers.length, is(1)); + trustManager = ((ReloadableTrustManager) originalTrustManagers[0]).getTrustManager(); + } else { + originalTrustManagers = null; + trustManager = null; + } + + // register configuration with reloader + reloader.onSSLContextLoaded(config); + + // key manager checks + if (checkKeys) { + assertKeyManagersSame(keyManager, config.keyConfig().keyManagers(env)); + keyManagerPreChecks.apply(keyManager, config); + } + + // trust manager checks + if (checkTrust) { + assertTrustManagersSame(trustManager, config.trustConfig().trustManagers(env)); + trustManagerPreChecks.apply(trustManager, config); + } + + assertEquals(0, clientSSLService.getLoadedSSLConfigurations().size()); + assertEquals(0, serverSSLService.getLoadedSSLConfigurations().size()); + assertEquals("nothing should have called get", 0, clientCounter.get()); + assertEquals("nothing should have called get", 0, serverCounter.get()); + + // modify + modificationFunction.run(); + assertTrue(awaitBusy(() -> clientCounter.get() > 0 && serverCounter.get() > 0)); + + // check key manager + if (checkKeys) { + final X509ExtendedKeyManager[] updatedKeyManagers = config.keyConfig().keyManagers(env); + assertThat(updatedKeyManagers, sameInstance(originalKeyManagers)); + final X509ExtendedKeyManager updatedKeyManager = ((ReloadableX509KeyManager) updatedKeyManagers[0]).getKeyManager(); + keyManagerPostChecks.apply(updatedKeyManager, config); + } + + // check trust manager + if (checkTrust) { + final X509ExtendedTrustManager[] updatedTrustManagers = config.trustConfig().trustManagers(env); + assertThat(updatedTrustManagers, sameInstance(originalTrustManagers)); + final X509ExtendedTrustManager updatedTrustManager = ((ReloadableTrustManager) updatedTrustManagers[0]).getTrustManager(); + assertThat(updatedTrustManager, not(sameInstance(trustManager))); + trustManagerPostChecks.apply(updatedTrustManager, config); + } + } + + private void assertContainsCertificateWithMatchingName(Certificate[] certificates, Matcher matcher) { + for (Certificate certificate : certificates) { + if (certificate instanceof X509Certificate) { + if (matcher.matches(((X509Certificate) certificate).getSubjectX500Principal().getName())) { + return; + } + } + } + fail("no matching certificate could be found"); + } + + private void assertKeyManagersSame(X509ExtendedKeyManager original, X509ExtendedKeyManager[] other) { + assertEquals(1, other.length); + assertThat(other[0], instanceOf(ReloadableX509KeyManager.class)); + X509ExtendedKeyManager otherKeyManager = ((ReloadableX509KeyManager) other[0]).getKeyManager(); + assertThat(otherKeyManager, sameInstance(original)); + } + + private void assertTrustManagersSame(X509ExtendedTrustManager original, X509ExtendedTrustManager[] other) { + assertEquals(1, other.length); + assertThat(other[0], instanceOf(ReloadableTrustManager.class)); + X509ExtendedTrustManager otherTrustManager = ((ReloadableTrustManager) other[0]).getTrustManager(); + assertThat(otherTrustManager, sameInstance(original)); + } + + private static void atomicMoveIfPossible(Path source, Path target) throws IOException { + try { + Files.move(source, target, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE); + } catch (AtomicMoveNotSupportedException e) { + Files.move(source, target, StandardCopyOption.REPLACE_EXISTING); + } + } +} diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/ssl/SSLConfigurationTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/ssl/SSLConfigurationTests.java index cc5cc32cdf8..5f417c0a5b2 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/ssl/SSLConfigurationTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/ssl/SSLConfigurationTests.java @@ -5,45 +5,18 @@ */ package org.elasticsearch.xpack.security.ssl; -import org.bouncycastle.openssl.jcajce.JcaPEMWriter; -import org.bouncycastle.openssl.jcajce.JcePEMEncryptorBuilder; -import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.env.Environment; import org.elasticsearch.xpack.security.ssl.SSLConfiguration.Custom; import org.elasticsearch.xpack.security.ssl.SSLConfiguration.Global; -import org.elasticsearch.xpack.security.ssl.TrustConfig.Reloadable.Listener; import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.threadpool.TestThreadPool; -import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.watcher.ResourceWatcherService; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.TrustManager; -import javax.net.ssl.X509ExtendedKeyManager; -import javax.net.ssl.X509ExtendedTrustManager; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.nio.charset.StandardCharsets; -import java.nio.file.AtomicMoveNotSupportedException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.nio.file.attribute.BasicFileAttributes; -import java.security.KeyPair; -import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.cert.Certificate; -import java.security.cert.X509Certificate; import java.util.Arrays; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicReference; -import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; @@ -273,10 +246,10 @@ public class SSLConfigurationTests extends ESTestCase { SSLConfiguration config = new Global(settings); assertThat(config.keyConfig(), instanceOf(PEMKeyConfig.class)); PEMKeyConfig keyConfig = (PEMKeyConfig) config.keyConfig(); - KeyManager[] keyManagers = keyConfig.keyManagers(env, null, null); + KeyManager[] keyManagers = keyConfig.keyManagers(env); assertThat(keyManagers.length, is(1)); assertThat(config.trustConfig(), sameInstance(keyConfig)); - TrustManager[] trustManagers = keyConfig.trustManagers(env, null, null); + TrustManager[] trustManagers = keyConfig.trustManagers(env); assertThat(trustManagers.length, is(1)); } @@ -296,464 +269,11 @@ public class SSLConfigurationTests extends ESTestCase { SSLConfiguration config = new Global(settings); assertThat(config.keyConfig(), instanceOf(PEMKeyConfig.class)); PEMKeyConfig keyConfig = (PEMKeyConfig) config.keyConfig(); - KeyManager[] keyManagers = keyConfig.keyManagers(env, null, null); + KeyManager[] keyManagers = keyConfig.keyManagers(env); assertThat(keyManagers.length, is(1)); assertThat(config.trustConfig(), not(sameInstance(keyConfig))); assertThat(config.trustConfig(), instanceOf(PEMTrustConfig.class)); - TrustManager[] trustManagers = keyConfig.trustManagers(env, null, null); + TrustManager[] trustManagers = keyConfig.trustManagers(env); assertThat(trustManagers.length, is(1)); } - - public void testReloadingKeyStore() throws Exception { - Environment env = randomBoolean() ? null : - new Environment(Settings.builder().put("path.home", createTempDir()).build()); - Path tempDir = createTempDir(); - Path keystorePath = tempDir.resolve("testnode.jks"); - Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"), keystorePath); - Settings settings = Settings.builder() - .put("xpack.security.ssl.keystore.path", keystorePath) - .put("xpack.security.ssl.keystore.password", "testnode") - .put(Global.INCLUDE_JDK_CERTS_SETTING.getKey(), randomBoolean()) - .build(); - - SSLConfiguration config = new Global(settings); - assertThat(config.keyConfig(), instanceOf(StoreKeyConfig.class)); - StoreKeyConfig keyConfig = (StoreKeyConfig) config.keyConfig(); - - CountDownLatch latch = new CountDownLatch(2); - AtomicReference exceptionRef = new AtomicReference<>(); - Listener listener = createRefreshListener(latch, exceptionRef); - - ThreadPool threadPool = new TestThreadPool("reload"); - try { - ResourceWatcherService resourceWatcherService = - new ResourceWatcherService(Settings.builder().put("resource.reload.interval.high", "1s").build(), threadPool); - resourceWatcherService.start(); - KeyManager[] keyManagers = keyConfig.keyManagers(env, resourceWatcherService, listener); - assertThat(keyManagers.length, is(1)); - assertThat(keyManagers[0], instanceOf(X509ExtendedKeyManager.class)); - X509ExtendedKeyManager keyManager = (X509ExtendedKeyManager) keyManagers[0]; - String[] aliases = keyManager.getServerAliases("RSA", null); - assertNotNull(aliases); - assertThat(aliases.length, is(1)); - assertThat(aliases[0], is("testnode")); - TrustManager[] trustManagers = keyConfig.trustManagers(env, resourceWatcherService, listener); - assertThat(trustManagers.length, is(1)); - assertThat(trustManagers[0], instanceOf(X509ExtendedTrustManager.class)); - X509ExtendedTrustManager trustManager = (X509ExtendedTrustManager) trustManagers[0]; - Certificate[] certificates = trustManager.getAcceptedIssuers(); - final int trustedCount = certificates.length; - assertThat(latch.getCount(), is(2L)); - - KeyStore keyStore = KeyStore.getInstance("jks"); - keyStore.load(null, null); - Path updated = tempDir.resolve("updated.jks"); - try (OutputStream out = Files.newOutputStream(updated)) { - keyStore.store(out, "testnode".toCharArray()); - } - atomicMoveIfPossible(updated, keystorePath); - latch.await(); - assertThat(exceptionRef.get(), is(nullValue())); - aliases = keyManager.getServerAliases("RSA", null); - assertThat(aliases, is(nullValue())); - certificates = trustManager.getAcceptedIssuers(); - assertThat(trustedCount - certificates.length, is(5)); - } finally { - threadPool.shutdown(); - } - } - - public void testReloadingPEMKeyConfig() throws Exception { - Environment env = randomBoolean() ? null : - new Environment(Settings.builder().put("path.home", createTempDir()).build()); - Path tempDir = createTempDir(); - Path keyPath = tempDir.resolve("testnode.pem"); - Path certPath = tempDir.resolve("testnode.crt"); - Path clientCertPath = tempDir.resolve("testclient.crt"); - Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem"), keyPath); - Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"), certPath); - Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt"), clientCertPath); - Settings settings = Settings.builder() - .put("xpack.security.ssl.key.path", keyPath) - .put("xpack.security.ssl.key.password", "testnode") - .put("xpack.security.ssl.cert", certPath) - .putArray("xpack.security.ssl.ca", certPath.toString(), clientCertPath.toString()) - .put(Global.INCLUDE_JDK_CERTS_SETTING.getKey(), randomBoolean()) - .build(); - SSLConfiguration config = new Global(settings); - assertThat(config.keyConfig(), instanceOf(PEMKeyConfig.class)); - PEMKeyConfig keyConfig = (PEMKeyConfig) config.keyConfig(); - - CountDownLatch latch = new CountDownLatch(2); - AtomicReference exceptionRef = new AtomicReference<>(); - Listener listener = createRefreshListener(latch, exceptionRef); - - ThreadPool threadPool = new TestThreadPool("reload pem"); - try { - ResourceWatcherService resourceWatcherService = - new ResourceWatcherService(Settings.builder().put("resource.reload.interval.high", "1s").build(), threadPool); - resourceWatcherService.start(); - KeyManager[] keyManagers = keyConfig.keyManagers(env, resourceWatcherService, listener); - assertThat(keyManagers.length, is(1)); - assertThat(keyManagers[0], instanceOf(X509ExtendedKeyManager.class)); - X509ExtendedKeyManager keyManager = (X509ExtendedKeyManager) keyManagers[0]; - String[] aliases = keyManager.getServerAliases("RSA", null); - assertThat(aliases, is(notNullValue())); - assertThat(aliases.length, is(1)); - assertThat(aliases[0], is("key")); - PrivateKey privateKey = keyManager.getPrivateKey(aliases[0]); - TrustManager[] trustManagers = keyConfig.trustManagers(env, resourceWatcherService, listener); - assertThat(trustManagers.length, is(1)); - assertThat(trustManagers[0], instanceOf(X509ExtendedTrustManager.class)); - X509ExtendedTrustManager trustManager = (X509ExtendedTrustManager) trustManagers[0]; - Certificate[] certificates = trustManager.getAcceptedIssuers(); - final int trustedCount = certificates.length; - assertThat(latch.getCount(), is(2L)); - - // make sure we wait enough to see a change. if time is within a second the file may not be seen as modified since the size is - // the same! - awaitBusy(() -> { - try { - BasicFileAttributes attributes = Files.readAttributes(keyPath, BasicFileAttributes.class); - return System.currentTimeMillis() - attributes.lastModifiedTime().toMillis() >= 1000L; - } catch (IOException e) { - throw new ElasticsearchException("io exception while checking time", e); - } - }); - Path updatedKeyPath = tempDir.resolve("updated.pem"); - KeyPair keyPair = CertUtils.generateKeyPair(randomFrom(1024, 2048)); - try (OutputStream os = Files.newOutputStream(updatedKeyPath); - OutputStreamWriter osWriter = new OutputStreamWriter(os, StandardCharsets.UTF_8); - JcaPEMWriter writer = new JcaPEMWriter(osWriter)) { - writer.writeObject(keyPair, - new JcePEMEncryptorBuilder("DES-EDE3-CBC").setProvider(CertUtils.BC_PROV).build("testnode".toCharArray())); - } - atomicMoveIfPossible(updatedKeyPath, keyPath); - - latch.await(); - assertThat(exceptionRef.get(), is(nullValue())); - aliases = keyManager.getServerAliases("RSA", null); - assertThat(aliases, is(notNullValue())); - assertThat(aliases.length, is(1)); - assertThat(aliases[0], is("key")); - assertThat(keyManager.getPrivateKey(aliases[0]), not(equalTo(privateKey))); - assertThat(keyManager.getPrivateKey(aliases[0]), is(equalTo(keyPair.getPrivate()))); - certificates = trustManager.getAcceptedIssuers(); - assertThat(trustedCount - certificates.length, is(0)); - } finally { - threadPool.shutdown(); - } - } - - public void testReloadingTrustStore() throws Exception { - Environment env = randomBoolean() ? null : - new Environment(Settings.builder().put("path.home", createTempDir()).build()); - Path tempDir = createTempDir(); - Path trustStorePath = tempDir.resolve("testnode.jks"); - Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"), trustStorePath); - Settings settings = Settings.builder() - .put("xpack.security.ssl.truststore.path", trustStorePath) - .put("xpack.security.ssl.truststore.password", "testnode") - .put(Global.INCLUDE_JDK_CERTS_SETTING.getKey(), randomBoolean()) - .build(); - - SSLConfiguration config = new Global(settings); - assertThat(config.trustConfig(), instanceOf(StoreTrustConfig.class)); - StoreTrustConfig trustConfig = (StoreTrustConfig) config.trustConfig(); - - CountDownLatch latch = new CountDownLatch(1); - AtomicReference exceptionRef = new AtomicReference<>(); - Listener listener = createRefreshListener(latch, exceptionRef); - - ThreadPool threadPool = new TestThreadPool("reload"); - try { - ResourceWatcherService resourceWatcherService = - new ResourceWatcherService(Settings.builder().put("resource.reload.interval.high", "1s").build(), threadPool); - resourceWatcherService.start(); - TrustManager[] trustManagers = trustConfig.trustManagers(env, resourceWatcherService, listener); - assertThat(trustManagers.length, is(1)); - assertThat(trustManagers[0], instanceOf(X509ExtendedTrustManager.class)); - X509ExtendedTrustManager trustManager = (X509ExtendedTrustManager) trustManagers[0]; - Certificate[] certificates = trustManager.getAcceptedIssuers(); - final int trustedCount = certificates.length; - - assertThat(latch.getCount(), is(1L)); - - Path updatedTruststore = tempDir.resolve("updated.jks"); - KeyStore keyStore = KeyStore.getInstance("jks"); - keyStore.load(null, null); - try (OutputStream out = Files.newOutputStream(updatedTruststore)) { - keyStore.store(out, "testnode".toCharArray()); - } - atomicMoveIfPossible(updatedTruststore, trustStorePath); - latch.await(); - assertThat(exceptionRef.get(), is(nullValue())); - certificates = trustManager.getAcceptedIssuers(); - assertThat(trustedCount - certificates.length, is(5)); - } finally { - threadPool.shutdown(); - } - } - - public void testReloadingPEMTrustConfig() throws Exception { - Environment env = randomBoolean() ? null : - new Environment(Settings.builder().put("path.home", createTempDir()).build()); - Path tempDir = createTempDir(); - Path clientCertPath = tempDir.resolve("testclient.crt"); - Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt"), clientCertPath); - Settings settings = Settings.builder() - .putArray("xpack.security.ssl.ca", clientCertPath.toString()) - .put(Global.INCLUDE_JDK_CERTS_SETTING.getKey(), false) - .build(); - SSLConfiguration config = new Global(settings); - assertThat(config.trustConfig(), instanceOf(PEMTrustConfig.class)); - PEMTrustConfig trustConfig = (PEMTrustConfig) config.trustConfig(); - CountDownLatch latch = new CountDownLatch(1); - AtomicReference exceptionRef = new AtomicReference<>(); - Listener listener = createRefreshListener(latch, exceptionRef); - - ThreadPool threadPool = new TestThreadPool("reload"); - try { - ResourceWatcherService resourceWatcherService = - new ResourceWatcherService(Settings.builder().put("resource.reload.interval.high", "1s").build(), threadPool); - resourceWatcherService.start(); - TrustManager[] trustManagers = trustConfig.trustManagers(env, resourceWatcherService, listener); - assertThat(trustManagers.length, is(1)); - assertThat(trustManagers[0], instanceOf(X509ExtendedTrustManager.class)); - X509ExtendedTrustManager trustManager = (X509ExtendedTrustManager) trustManagers[0]; - Certificate[] certificates = trustManager.getAcceptedIssuers(); - assertThat(certificates.length, is(1)); - assertThat(((X509Certificate)certificates[0]).getSubjectX500Principal().getName(), containsString("Test Client")); - assertThat(latch.getCount(), is(1L)); - - Path updatedCert = tempDir.resolve("updated.crt"); - Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"), updatedCert, - StandardCopyOption.REPLACE_EXISTING); - atomicMoveIfPossible(updatedCert, clientCertPath); - latch.await(); - assertThat(exceptionRef.get(), is(nullValue())); - Certificate[] updatedCerts = trustManager.getAcceptedIssuers(); - assertThat(updatedCerts.length, is(1)); - assertThat(((X509Certificate)updatedCerts[0]).getSubjectX500Principal().getName(), containsString("Test Node")); - assertThat(updatedCerts[0], not(equalTo(certificates[0]))); - } finally { - threadPool.shutdown(); - } - } - - public void testReloadingKeyStoreException() throws Exception { - Environment env = randomBoolean() ? null : - new Environment(Settings.builder().put("path.home", createTempDir()).build()); - Path tempDir = createTempDir(); - Path keystorePath = tempDir.resolve("testnode.jks"); - Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"), keystorePath); - Settings settings = Settings.builder() - .put("xpack.security.ssl.keystore.path", keystorePath) - .put("xpack.security.ssl.keystore.password", "testnode") - .put(Global.INCLUDE_JDK_CERTS_SETTING.getKey(), randomBoolean()) - .build(); - - SSLConfiguration config = new Global(settings); - assertThat(config.keyConfig(), instanceOf(StoreKeyConfig.class)); - StoreKeyConfig keyConfig = (StoreKeyConfig) config.keyConfig(); - - CountDownLatch latch = new CountDownLatch(1); - AtomicReference exceptionRef = new AtomicReference<>(); - Listener listener = createRefreshListener(latch, exceptionRef); - - ThreadPool threadPool = new TestThreadPool("reload"); - try { - ResourceWatcherService resourceWatcherService = - new ResourceWatcherService(Settings.builder().put("resource.reload.interval.high", "1s").build(), threadPool); - resourceWatcherService.start(); - KeyManager[] keyManagers = keyConfig.keyManagers(env, resourceWatcherService, listener); - X509ExtendedKeyManager keyManager = (X509ExtendedKeyManager) keyManagers[0]; - String[] aliases = keyManager.getServerAliases("RSA", null); - assertNotNull(aliases); - assertThat(aliases.length, is(1)); - assertThat(aliases[0], is("testnode")); - assertThat(latch.getCount(), is(1L)); - - // truncate the keystore - try (OutputStream out = Files.newOutputStream(keystorePath)) { - } - latch.await(); - assertThat(exceptionRef.get(), notNullValue()); - assertThat(exceptionRef.get(), instanceOf(ElasticsearchException.class)); - assertThat(keyManager.getServerAliases("RSA", null), equalTo(aliases)); - } finally { - threadPool.shutdown(); - } - } - - public void testReloadingPEMKeyConfigException() throws Exception { - Environment env = randomBoolean() ? null : - new Environment(Settings.builder().put("path.home", createTempDir()).build()); - Path tempDir = createTempDir(); - Path keyPath = tempDir.resolve("testnode.pem"); - Path certPath = tempDir.resolve("testnode.crt"); - Path clientCertPath = tempDir.resolve("testclient.crt"); - Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem"), keyPath); - Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"), certPath); - Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt"), clientCertPath); - Settings settings = Settings.builder() - .put("xpack.security.ssl.key.path", keyPath) - .put("xpack.security.ssl.key.password", "testnode") - .put("xpack.security.ssl.cert", certPath) - .putArray("xpack.security.ssl.ca", certPath.toString(), clientCertPath.toString()) - .put(Global.INCLUDE_JDK_CERTS_SETTING.getKey(), randomBoolean()) - .build(); - SSLConfiguration config = new Global(settings); - assertThat(config.keyConfig(), instanceOf(PEMKeyConfig.class)); - PEMKeyConfig keyConfig = (PEMKeyConfig) config.keyConfig(); - - CountDownLatch latch = new CountDownLatch(1); - AtomicReference exceptionRef = new AtomicReference<>(); - Listener listener = createRefreshListener(latch, exceptionRef); - - ThreadPool threadPool = new TestThreadPool("reload pem"); - try { - ResourceWatcherService resourceWatcherService = - new ResourceWatcherService(Settings.builder().put("resource.reload.interval.high", "1s").build(), threadPool); - resourceWatcherService.start(); - KeyManager[] keyManagers = keyConfig.keyManagers(env, resourceWatcherService, listener); - assertThat(keyManagers.length, is(1)); - assertThat(keyManagers[0], instanceOf(X509ExtendedKeyManager.class)); - X509ExtendedKeyManager keyManager = (X509ExtendedKeyManager) keyManagers[0]; - String[] aliases = keyManager.getServerAliases("RSA", null); - assertThat(aliases, is(notNullValue())); - assertThat(aliases.length, is(1)); - assertThat(aliases[0], is("key")); - PrivateKey privateKey = keyManager.getPrivateKey(aliases[0]); - assertThat(latch.getCount(), is(1L)); - - // pick a random file to truncate - Path toTruncate = randomFrom(keyPath, certPath); - - // truncate the file - try (OutputStream os = Files.newOutputStream(toTruncate)) { - } - - latch.await(); - assertThat(exceptionRef.get(), is(instanceOf(ElasticsearchException.class))); - assertThat(keyManager.getServerAliases("RSA", null), equalTo(aliases)); - assertThat(keyManager.getPrivateKey(aliases[0]), is(equalTo(privateKey))); - } finally { - threadPool.shutdown(); - } - } - - public void testTrustStoreReloadException() throws Exception { - Environment env = randomBoolean() ? null : - new Environment(Settings.builder().put("path.home", createTempDir()).build()); - Path tempDir = createTempDir(); - Path trustStorePath = tempDir.resolve("testnode.jks"); - Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks"), trustStorePath); - Settings settings = Settings.builder() - .put("xpack.security.ssl.truststore.path", trustStorePath) - .put("xpack.security.ssl.truststore.password", "testnode") - .put(Global.INCLUDE_JDK_CERTS_SETTING.getKey(), randomBoolean()) - .build(); - - SSLConfiguration config = new Global(settings); - assertThat(config.trustConfig(), instanceOf(StoreTrustConfig.class)); - StoreTrustConfig trustConfig = (StoreTrustConfig) config.trustConfig(); - - CountDownLatch latch = new CountDownLatch(1); - AtomicReference exceptionRef = new AtomicReference<>(); - Listener listener = createRefreshListener(latch, exceptionRef); - - ThreadPool threadPool = new TestThreadPool("reload"); - try { - ResourceWatcherService resourceWatcherService = - new ResourceWatcherService(Settings.builder().put("resource.reload.interval.high", "1s").build(), threadPool); - resourceWatcherService.start(); - TrustManager[] trustManagers = trustConfig.trustManagers(env, resourceWatcherService, listener); - assertThat(trustManagers.length, is(1)); - assertThat(trustManagers[0], instanceOf(X509ExtendedTrustManager.class)); - X509ExtendedTrustManager trustManager = (X509ExtendedTrustManager) trustManagers[0]; - Certificate[] certificates = trustManager.getAcceptedIssuers(); - - // truncate the truststore - try (OutputStream os = Files.newOutputStream(trustStorePath)) { - } - - latch.await(); - assertThat(exceptionRef.get(), instanceOf(ElasticsearchException.class)); - assertThat(trustManager.getAcceptedIssuers(), equalTo(certificates)); - } finally { - threadPool.shutdown(); - } - } - - public void testPEMTrustReloadException() throws Exception { - Environment env = randomBoolean() ? null : - new Environment(Settings.builder().put("path.home", createTempDir()).build()); - Path tempDir = createTempDir(); - Path clientCertPath = tempDir.resolve("testclient.crt"); - Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.crt"), clientCertPath); - Settings settings = Settings.builder() - .putArray("xpack.security.ssl.ca", clientCertPath.toString()) - .put(Global.INCLUDE_JDK_CERTS_SETTING.getKey(), false) - .build(); - SSLConfiguration config = new Global(settings); - assertThat(config.trustConfig(), instanceOf(PEMTrustConfig.class)); - PEMTrustConfig trustConfig = (PEMTrustConfig) config.trustConfig(); - CountDownLatch latch = new CountDownLatch(1); - AtomicReference exceptionRef = new AtomicReference<>(); - Listener listener = createRefreshListener(latch, exceptionRef); - - ThreadPool threadPool = new TestThreadPool("reload"); - try { - ResourceWatcherService resourceWatcherService = - new ResourceWatcherService(Settings.builder().put("resource.reload.interval.high", "1s").build(), threadPool); - resourceWatcherService.start(); - TrustManager[] trustManagers = trustConfig.trustManagers(env, resourceWatcherService, listener); - assertThat(trustManagers.length, is(1)); - assertThat(trustManagers[0], instanceOf(X509ExtendedTrustManager.class)); - X509ExtendedTrustManager trustManager = (X509ExtendedTrustManager) trustManagers[0]; - Certificate[] certificates = trustManager.getAcceptedIssuers(); - assertThat(certificates.length, is(1)); - assertThat(((X509Certificate) certificates[0]).getSubjectX500Principal().getName(), containsString("Test Client")); - assertThat(latch.getCount(), is(1L)); - - // write bad file - Path updatedCert = tempDir.resolve("updated.crt"); - try (OutputStream os = Files.newOutputStream(updatedCert)) { - os.write(randomByte()); - } - atomicMoveIfPossible(updatedCert, clientCertPath); - - latch.await(); - assertThat(exceptionRef.get(), instanceOf(ElasticsearchException.class)); - assertThat(trustManager.getAcceptedIssuers(), equalTo(certificates)); - } finally { - threadPool.shutdown(); - } - } - - private Listener createRefreshListener(CountDownLatch latch, AtomicReference exceptionRef) { - return new Listener() { - @Override - public void onReload() { - logger.info("refresh called"); - latch.countDown(); - } - - @Override - public void onFailure(Exception e) { - logger.error("exception " + e); - exceptionRef.set(e); - latch.countDown(); - } - }; - } - - private void atomicMoveIfPossible(Path source, Path target) throws IOException { - try { - Files.move(source, target, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE); - } catch (AtomicMoveNotSupportedException e) { - Files.move(source, target, StandardCopyOption.REPLACE_EXISTING); - } - } } diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/ssl/ServerSSLServiceTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/ssl/ServerSSLServiceTests.java index 6d633279f52..d179604291f 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/ssl/ServerSSLServiceTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/ssl/ServerSSLServiceTests.java @@ -53,7 +53,7 @@ public class ServerSSLServiceTests extends ESTestCase { .put("xpack.security.ssl.truststore.password", "testnode") .build(); try { - new ServerSSLService(settings, env, new Global(settings), null).createSSLEngine(); + new ServerSSLService(settings, env, new Global(settings)).createSSLEngine(); fail("expected an exception"); } catch (ElasticsearchException e) { assertThat(e.getMessage(), containsString("failed to initialize the SSLContext")); @@ -67,7 +67,7 @@ public class ServerSSLServiceTests extends ESTestCase { .put("xpack.security.ssl.keystore.path", testnodeStore) .put("xpack.security.ssl.keystore.password", "testnode") .build(); - ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings), null); + ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings)); Settings.Builder settingsBuilder = Settings.builder() .put("truststore.path", testClientStore) @@ -85,7 +85,7 @@ public class ServerSSLServiceTests extends ESTestCase { .put("xpack.security.ssl.keystore.path", testnodeStore) .put("xpack.security.ssl.keystore.password", "testnode") .build(); - ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings), null); + ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings)); SSLContext sslContext = sslService.sslContext(); SSLContext cachedSslContext = sslService.sslContext(); @@ -101,7 +101,7 @@ public class ServerSSLServiceTests extends ESTestCase { .put("xpack.security.ssl.keystore.password", "testnode") .put("xpack.security.ssl.keystore.key_password", "testnode1") .build(); - new ServerSSLService(settings, env, new Global(settings), null).createSSLEngine(); + new ServerSSLService(settings, env, new Global(settings)).createSSLEngine(); } public void testIncorrectKeyPasswordThrowsException() throws Exception { @@ -112,7 +112,7 @@ public class ServerSSLServiceTests extends ESTestCase { .put("xpack.security.ssl.keystore.path", differentPasswordsStore) .put("xpack.security.ssl.keystore.password", "testnode") .build(); - new ServerSSLService(settings, env, new Global(settings), null).createSSLEngine(); + new ServerSSLService(settings, env, new Global(settings)).createSSLEngine(); fail("expected an exception"); } catch (ElasticsearchException e) { assertThat(e.getMessage(), containsString("failed to initialize a KeyManagerFactory")); @@ -124,7 +124,7 @@ public class ServerSSLServiceTests extends ESTestCase { .put("xpack.security.ssl.keystore.path", testnodeStore) .put("xpack.security.ssl.keystore.password", "testnode") .build(); - ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings), null); + ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings)); SSLEngine engine = sslService.createSSLEngine(); assertThat(Arrays.asList(engine.getEnabledProtocols()), not(hasItem("SSLv3"))); } @@ -134,7 +134,7 @@ public class ServerSSLServiceTests extends ESTestCase { .put("xpack.security.ssl.keystore.path", testnodeStore) .put("xpack.security.ssl.keystore.password", "testnode") .build(); - ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings), null); + ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings)); SSLSessionContext context = sslService.sslContext().getServerSessionContext(); assertThat(context.getSessionCacheSize(), equalTo(1000)); assertThat(context.getSessionTimeout(), equalTo((int) TimeValue.timeValueHours(24).seconds())); @@ -147,14 +147,14 @@ public class ServerSSLServiceTests extends ESTestCase { .put("xpack.security.ssl.session.cache_size", "300") .put("xpack.security.ssl.session.cache_timeout", "600s") .build(); - ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings), null); + ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings)); SSLSessionContext context = sslService.sslContext().getServerSessionContext(); assertThat(context.getSessionCacheSize(), equalTo(300)); assertThat(context.getSessionTimeout(), equalTo(600)); } public void testThatCreateSSLEngineWithoutAnySettingsDoesNotWork() throws Exception { - ServerSSLService sslService = new ServerSSLService(Settings.EMPTY, env, new Global(Settings.EMPTY), null); + ServerSSLService sslService = new ServerSSLService(Settings.EMPTY, env, new Global(Settings.EMPTY)); try { sslService.createSSLEngine(); fail("Expected IllegalArgumentException"); @@ -168,7 +168,7 @@ public class ServerSSLServiceTests extends ESTestCase { .put("xpack.security.ssl.truststore.path", testnodeStore) .put("xpack.security.ssl.truststore.password", "testnode") .build(); - ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings), null); + ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings)); try { sslService.createSSLEngine(); fail("Expected IllegalArgumentException"); @@ -183,7 +183,7 @@ public class ServerSSLServiceTests extends ESTestCase { .put("xpack.security.ssl.keystore.password", "testnode") .put("xpack.security.ssl.truststore.path", testnodeStore) .build(); - ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings), null); + ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings)); try { sslService.sslContext(); fail("Expected IllegalArgumentException"); @@ -196,7 +196,7 @@ public class ServerSSLServiceTests extends ESTestCase { Settings settings = Settings.builder() .put("xpack.security.ssl.keystore.path", testnodeStore) .build(); - ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings), null); + ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings)); try { sslService.sslContext(); fail("Expected IllegalArgumentException"); @@ -214,7 +214,7 @@ public class ServerSSLServiceTests extends ESTestCase { .put("xpack.security.ssl.keystore.password", "testnode") .putArray("xpack.security.ssl.ciphers", ciphers.toArray(new String[ciphers.size()])) .build(); - ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings), null); + ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings)); SSLEngine engine = sslService.createSSLEngine(); assertThat(engine, is(notNullValue())); String[] enabledCiphers = engine.getEnabledCipherSuites(); @@ -227,7 +227,7 @@ public class ServerSSLServiceTests extends ESTestCase { .put("xpack.security.ssl.keystore.password", "testnode") .putArray("xpack.security.ssl.ciphers", new String[] { "foo", "bar" }) .build(); - ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings), null); + ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings)); try { sslService.createSSLEngine(); fail("Expected IllegalArgumentException"); @@ -241,7 +241,7 @@ public class ServerSSLServiceTests extends ESTestCase { .put("xpack.security.ssl.keystore.path", testnodeStore) .put("xpack.security.ssl.keystore.password", "testnode") .build(); - ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings), null); + ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings)); SSLSocketFactory factory = sslService.sslSocketFactory(Settings.EMPTY); final String[] ciphers = sslService.supportedCiphers(factory.getSupportedCipherSuites(), sslService.ciphers(), false); assertThat(factory.getDefaultCipherSuites(), is(ciphers)); diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/TransportFilterTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/TransportFilterTests.java index 2e395d5f16f..37efd75510f 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/TransportFilterTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/TransportFilterTests.java @@ -19,7 +19,7 @@ import org.elasticsearch.transport.MockTcpTransportPlugin; import org.elasticsearch.xpack.security.action.SecurityActionMapper; import org.elasticsearch.xpack.security.authc.AuthenticationService; import org.elasticsearch.xpack.security.authz.AuthorizationService; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.threadpool.ThreadPool; @@ -32,8 +32,6 @@ import org.elasticsearch.transport.TransportResponse; import org.elasticsearch.transport.TransportResponseHandler; import org.elasticsearch.transport.TransportService; import org.elasticsearch.transport.TransportSettings; -import org.elasticsearch.xpack.security.authc.AuthenticationService; -import org.elasticsearch.xpack.security.authz.AuthorizationService; import org.mockito.InOrder; import java.io.IOException; diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/filter/IPFilterTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/filter/IPFilterTests.java index 17e8fdac070..12a368a02d9 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/filter/IPFilterTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/filter/IPFilterTests.java @@ -14,8 +14,7 @@ import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.http.HttpServerTransport; -import org.elasticsearch.xpack.security.audit.AuditTrail; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.junit.annotations.Network; import org.elasticsearch.transport.Transport; diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/HandshakeWaitingHandlerTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/HandshakeWaitingHandlerTests.java index 7f40fff068d..8eed8b303b0 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/HandshakeWaitingHandlerTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/HandshakeWaitingHandlerTests.java @@ -76,7 +76,7 @@ public class HandshakeWaitingHandlerTests extends ESTestCase { .put("xpack.security.ssl.keystore.password", "testnode") .build(); Environment env = new Environment(Settings.builder().put("path.home", createTempDir()).build()); - ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings), null); + ServerSSLService sslService = new ServerSSLService(settings, env, new Global(settings)); sslContext = sslService.sslContext(); diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/IPFilterNetty3UpstreamHandlerTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/IPFilterNetty3UpstreamHandlerTests.java index 2c696d1ba4b..4f78a171f37 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/IPFilterNetty3UpstreamHandlerTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/IPFilterNetty3UpstreamHandlerTests.java @@ -13,7 +13,7 @@ import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.http.HttpServerTransport; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.security.audit.AuditTrailService; import org.elasticsearch.xpack.security.transport.filter.IPFilter; import org.elasticsearch.test.ESTestCase; diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/SecurityNetty3HttpServerTransportTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/SecurityNetty3HttpServerTransportTests.java index 235ad157c7d..e81725bb5ec 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/SecurityNetty3HttpServerTransportTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/SecurityNetty3HttpServerTransportTests.java @@ -43,7 +43,7 @@ public class SecurityNetty3HttpServerTransportTests extends ESTestCase { .put("xpack.security.ssl.keystore.password", "testnode") .build(); Environment env = new Environment(Settings.builder().put("path.home", createTempDir()).build()); - serverSSLService = new ServerSSLService(settings, env, new Global(settings), null); + serverSSLService = new ServerSSLService(settings, env, new Global(settings)); } public void testDefaultClientAuth() throws Exception { diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/SecurityNetty3TransportTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/SecurityNetty3TransportTests.java index ad55149de6f..22a4b86da80 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/SecurityNetty3TransportTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/SecurityNetty3TransportTests.java @@ -43,8 +43,8 @@ public class SecurityNetty3TransportTests extends ESTestCase { .build(); Environment env = new Environment(Settings.builder().put("path.home", createTempDir()).build()); Global globalSSLConfiguration = new Global(settings); - serverSSLService = new ServerSSLService(settings, env, globalSSLConfiguration, null); - clientSSLService = new ClientSSLService(settings, env, globalSSLConfiguration, null); + serverSSLService = new ServerSSLService(settings, env, globalSSLConfiguration); + clientSSLService = new ClientSSLService(settings, env, globalSSLConfiguration); } public void testThatSSLCanBeDisabledByProfile() throws Exception { diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/ssl/SslClientAuthTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/ssl/SslClientAuthTests.java index 5c5a42c36a6..fee11261e0e 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/ssl/SslClientAuthTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/ssl/SslClientAuthTests.java @@ -74,7 +74,7 @@ public class SslClientAuthTests extends SecurityIntegTestCase { Settings settings = Settings.builder() .put(getSSLSettingsForStore("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.jks", "testclient")) .build(); - ClientSSLService sslService = new ClientSSLService(settings, null, new Global(settings), null); + ClientSSLService sslService = new ClientSSLService(settings, null, new Global(settings)); SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(sslService.sslContext(), NoopHostnameVerifier.INSTANCE); try (RestClient restClient = createRestClient(httpClientBuilder -> httpClientBuilder.setSSLStrategy(sessionStrategy), "https")) { Response response = restClient.performRequest("GET", "/", diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/ssl/SslIntegrationTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/ssl/SslIntegrationTests.java index 1fb2bd8f71a..817a44e0b9d 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/ssl/SslIntegrationTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/ssl/SslIntegrationTests.java @@ -99,7 +99,7 @@ public class SslIntegrationTests extends SecurityIntegTestCase { Settings settings = Settings.builder() .put(getSSLSettingsForStore("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.jks", "testclient")) .build(); - ClientSSLService service = new ClientSSLService(settings, null, new Global(settings), null); + ClientSSLService service = new ClientSSLService(settings, null, new Global(settings)); CredentialsProvider provider = new BasicCredentialsProvider(); provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(nodeClientUsername(), diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/user/AnonymousUserTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/user/AnonymousUserTests.java index f801ed792f3..f4b85ad83da 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/user/AnonymousUserTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/user/AnonymousUserTests.java @@ -5,14 +5,11 @@ */ package org.elasticsearch.xpack.security.user; -import org.elasticsearch.common.io.stream.ByteBufferStreamInput; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.test.ESTestCase; import org.junit.After; -import java.nio.ByteBuffer; - import static org.hamcrest.Matchers.arrayContainingInAnyOrder; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; diff --git a/elasticsearch/x-pack/security/src/test/resources/rest-api-spec/test/change_password/10_basic.yaml b/elasticsearch/x-pack/security/src/test/resources/rest-api-spec/test/change_password/10_basic.yaml index a2cc4430a5c..a2e25cb9e2e 100644 --- a/elasticsearch/x-pack/security/src/test/resources/rest-api-spec/test/change_password/10_basic.yaml +++ b/elasticsearch/x-pack/security/src/test/resources/rest-api-spec/test/change_password/10_basic.yaml @@ -52,6 +52,8 @@ teardown: --- "Test changing users password": + - skip: + features: catch_unauthorized # validate that the user actually works - do: headers: @@ -70,7 +72,7 @@ teardown: # attempt to login with invalid credentials - do: - catch: request + catch: unauthorized headers: Authorization: "Basic am9lOnMza3JpdA==" cluster.health: {} @@ -84,6 +86,8 @@ teardown: --- "Test user changing their own password": + - skip: + features: catch_unauthorized # test that the role actually works - do: headers: @@ -103,7 +107,7 @@ teardown: # attempt to login with invalid credentials - do: - catch: request + catch: unauthorized headers: Authorization: "Basic dW5wcml2aWxlZ2VkX3VzZXI6czNrcml0" cluster.health: {} diff --git a/elasticsearch/x-pack/security/src/test/resources/rest-api-spec/test/users/16_update_user.yaml b/elasticsearch/x-pack/security/src/test/resources/rest-api-spec/test/users/16_update_user.yaml index 92c6d3fea1c..019a7014712 100644 --- a/elasticsearch/x-pack/security/src/test/resources/rest-api-spec/test/users/16_update_user.yaml +++ b/elasticsearch/x-pack/security/src/test/resources/rest-api-spec/test/users/16_update_user.yaml @@ -35,7 +35,7 @@ teardown: --- "Test create user and update without and with password": - skip: - features: headers + features: [headers, catch_unauthorized] # test that the role actually works - do: @@ -108,7 +108,7 @@ teardown: # validate old password doesn't work - do: - catch: request + catch: unauthorized headers: Authorization: "Basic am9lOnMza3JpdA==" cluster.health: {} diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/XPackInfoResponse.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/license/XPackInfoResponse.java similarity index 99% rename from elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/XPackInfoResponse.java rename to elasticsearch/x-pack/src/main/java/org/elasticsearch/license/XPackInfoResponse.java index 996f22b42ca..84bed0b7be6 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/XPackInfoResponse.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/license/XPackInfoResponse.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack.action; +package org.elasticsearch.license; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.common.Nullable; @@ -12,7 +12,6 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.license.core.License; import org.elasticsearch.xpack.XPackBuild; import java.io.IOException; diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/license/plugin/core/XPackLicenseState.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/license/XPackLicenseState.java similarity index 99% rename from elasticsearch/x-pack/src/main/java/org/elasticsearch/license/plugin/core/XPackLicenseState.java rename to elasticsearch/x-pack/src/main/java/org/elasticsearch/license/XPackLicenseState.java index 7e4c7a77eca..9cfbe893e67 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/license/plugin/core/XPackLicenseState.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/license/XPackLicenseState.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.license.plugin.core; +package org.elasticsearch.license; import java.util.Collections; import java.util.LinkedHashMap; @@ -13,7 +13,7 @@ import java.util.function.BiFunction; import org.elasticsearch.common.Strings; import org.elasticsearch.common.logging.LoggerMessageFormat; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.core.License.OperationMode; +import org.elasticsearch.license.License.OperationMode; import org.elasticsearch.xpack.graph.Graph; import org.elasticsearch.xpack.monitoring.Monitoring; import org.elasticsearch.xpack.monitoring.MonitoringSettings; diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackClient.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackClient.java index 3a233022fda..50e4c3cdf3c 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackClient.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackClient.java @@ -7,7 +7,7 @@ package org.elasticsearch.xpack; import org.elasticsearch.action.ActionListener; import org.elasticsearch.client.Client; -import org.elasticsearch.license.plugin.LicensingClient; +import org.elasticsearch.license.LicensingClient; import org.elasticsearch.xpack.monitoring.client.MonitoringClient; import org.elasticsearch.xpack.security.authc.support.SecuredString; import org.elasticsearch.xpack.security.client.SecurityClient; @@ -15,7 +15,7 @@ import org.elasticsearch.xpack.watcher.client.WatcherClient; import org.elasticsearch.xpack.action.XPackInfoAction; import org.elasticsearch.xpack.action.XPackInfoRequest; import org.elasticsearch.xpack.action.XPackInfoRequestBuilder; -import org.elasticsearch.xpack.action.XPackInfoResponse; +import org.elasticsearch.license.XPackInfoResponse; import java.util.Collections; import java.util.Map; diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java index 1208b6e20f4..0531f810f93 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java @@ -37,8 +37,9 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.index.IndexModule; import org.elasticsearch.ingest.Processor; -import org.elasticsearch.license.plugin.Licensing; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.LicenseService; +import org.elasticsearch.license.Licensing; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.plugins.ActionPlugin; import org.elasticsearch.plugins.IngestPlugin; import org.elasticsearch.plugins.Plugin; @@ -139,7 +140,7 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I this.licensing = new Licensing(settings); this.security = new Security(settings, env, licenseState); - this.monitoring = new Monitoring(settings); + this.monitoring = new Monitoring(settings, env, licenseState); this.watcher = new Watcher(settings); this.graph = new Graph(settings); this.notification = new Notification(settings); @@ -173,8 +174,6 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I if (transportClientMode == false) { modules.add(new TextTemplateModule()); - // Note: this only exists so LicenseService subclasses can be bound in mock tests - modules.addAll(licensing.nodeModules()); } else { modules.add(b -> b.bind(XPackLicenseState.class).toProvider(Providers.of(null))); } @@ -185,7 +184,6 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I public Collection> getGuiceServiceClasses() { ArrayList> services = new ArrayList<>(); services.addAll(notification.nodeServices()); - services.addAll(monitoring.nodeServices()); return services; } @@ -196,9 +194,14 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I final InternalClient internalClient = new InternalClient(settings, threadPool, client, security.getCryptoService()); components.add(internalClient); - components.addAll(licensing.createComponents(clusterService, getClock(), env, resourceWatcherService, licenseState)); + LicenseService licenseService = new LicenseService(settings, clusterService, getClock(), + env, resourceWatcherService, licenseState); + components.add(licenseService); + components.add(licenseState); + components.addAll(security.createComponents(internalClient, threadPool, clusterService, resourceWatcherService, extensionsService.getExtensions())); + components.addAll(monitoring.createComponents(internalClient, threadPool, clusterService, licenseService)); // watcher http stuff Map httpAuthFactories = new HashMap<>(); diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/TransportXPackInfoAction.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/TransportXPackInfoAction.java index dfc9c6bcb6a..521661adf21 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/TransportXPackInfoAction.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/TransportXPackInfoAction.java @@ -11,14 +11,15 @@ import org.elasticsearch.action.support.HandledTransportAction; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.core.LicenseService; +import org.elasticsearch.license.XPackInfoResponse; +import org.elasticsearch.license.License; +import org.elasticsearch.license.LicenseService; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import org.elasticsearch.xpack.XPackBuild; import org.elasticsearch.xpack.XPackFeatureSet; -import org.elasticsearch.xpack.action.XPackInfoResponse.FeatureSetsInfo.FeatureSet; -import org.elasticsearch.xpack.action.XPackInfoResponse.LicenseInfo; +import org.elasticsearch.license.XPackInfoResponse.FeatureSetsInfo.FeatureSet; +import org.elasticsearch.license.XPackInfoResponse.LicenseInfo; import java.util.Set; import java.util.stream.Collectors; diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/XPackInfoAction.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/XPackInfoAction.java index 9adf597024d..d1045f52b43 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/XPackInfoAction.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/XPackInfoAction.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.action; import org.elasticsearch.action.Action; import org.elasticsearch.client.ElasticsearchClient; +import org.elasticsearch.license.XPackInfoResponse; /** * diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/XPackInfoRequestBuilder.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/XPackInfoRequestBuilder.java index c440c44fa1b..6e4e534e1fc 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/XPackInfoRequestBuilder.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/XPackInfoRequestBuilder.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.action; import org.elasticsearch.action.ActionRequestBuilder; import org.elasticsearch.client.ElasticsearchClient; +import org.elasticsearch.license.XPackInfoResponse; import java.util.EnumSet; diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/XPackUsageResponse.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/XPackUsageResponse.java index 9906acaa181..5afbb725351 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/XPackUsageResponse.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/action/XPackUsageResponse.java @@ -6,25 +6,13 @@ package org.elasticsearch.xpack.action; import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.common.Nullable; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Writeable; -import org.elasticsearch.common.xcontent.ToXContent; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.license.core.License; -import org.elasticsearch.xpack.XPackBuild; import org.elasticsearch.xpack.XPackFeatureSet; import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; /** */ diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/common/http/HttpClient.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/common/http/HttpClient.java index da5f0aa8a93..0f8a1290654 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/common/http/HttpClient.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/common/http/HttpClient.java @@ -10,7 +10,6 @@ import org.elasticsearch.ElasticsearchTimeoutException; import org.elasticsearch.SpecialPermission; import org.elasticsearch.common.Strings; import org.elasticsearch.common.component.AbstractLifecycleComponent; -import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; @@ -69,7 +68,7 @@ public class HttpClient extends AbstractLifecycleComponent { public static final String SETTINGS_SSL_TRUSTSTORE_ALGORITHM = SETTINGS_SSL_PREFIX + "truststore.algorithm"; static final String SETTINGS_SSL_SECURITY_TRUSTSTORE_ALGORITHM = SETTINGS_SSL_SECURITY_PREFIX + "truststore.algorithm"; public static final String SETTINGS_PROXY_HOST = SETTINGS_PROXY_PREFIX + "host"; - public static final String SETTINGS_PROXY_PORT = SETTINGS_PROXY_PREFIX + "post"; + public static final String SETTINGS_PROXY_PORT = SETTINGS_PROXY_PREFIX + "port"; private final HttpAuthRegistry httpAuthRegistry; private final Environment env; @@ -93,6 +92,7 @@ public class HttpClient extends AbstractLifecycleComponent { String proxyHost = settings.get(SETTINGS_PROXY_HOST, null); if (proxyPort != null && Strings.hasText(proxyHost)) { proxy = new HttpProxy(proxyHost, proxyPort); + logger.info("Using default proxy for http input and slack/hipchat/pagerduty/webhook actions [{}:{}]", proxyHost, proxyPort); } else { if (proxyPort == null && Strings.hasText(proxyHost) || proxyPort != null && !Strings.hasText(proxyHost)) { logger.error("disabling proxy. Watcher HTTP HttpProxy requires both settings: [{}] and [{}]", SETTINGS_PROXY_HOST, diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/common/http/HttpRequest.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/common/http/HttpRequest.java index 3b6311a62ae..34c76e46272 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/common/http/HttpRequest.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/common/http/HttpRequest.java @@ -17,7 +17,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.rest.support.RestUtils; +import org.elasticsearch.rest.RestUtils; import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry; import org.elasticsearch.xpack.watcher.support.WatcherDateTimeUtils; import org.elasticsearch.xpack.watcher.support.WatcherUtils; diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/common/http/HttpRequestTemplate.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/common/http/HttpRequestTemplate.java index 936e3faa54e..e514e969c0b 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/common/http/HttpRequestTemplate.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/common/http/HttpRequestTemplate.java @@ -15,7 +15,7 @@ import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.rest.support.RestUtils; +import org.elasticsearch.rest.RestUtils; import org.elasticsearch.xpack.common.http.auth.HttpAuth; import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry; import org.elasticsearch.xpack.watcher.support.WatcherDateTimeUtils; diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/rest/action/RestXPackInfoAction.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/rest/action/RestXPackInfoAction.java index ca6dd8bf4e0..dc007681b76 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/rest/action/RestXPackInfoAction.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/rest/action/RestXPackInfoAction.java @@ -18,7 +18,7 @@ import org.elasticsearch.rest.RestResponse; import org.elasticsearch.rest.action.support.RestBuilderListener; import org.elasticsearch.xpack.XPackClient; import org.elasticsearch.xpack.action.XPackInfoRequest; -import org.elasticsearch.xpack.action.XPackInfoResponse; +import org.elasticsearch.license.XPackInfoResponse; import org.elasticsearch.xpack.rest.XPackRestHandler; import static org.elasticsearch.rest.RestRequest.Method.GET; diff --git a/elasticsearch/x-pack/src/test/java/org/elasticsearch/xpack/action/TransportXPackInfoActionTests.java b/elasticsearch/x-pack/src/test/java/org/elasticsearch/xpack/action/TransportXPackInfoActionTests.java index 8069ac8b7d1..7efd1695ee7 100644 --- a/elasticsearch/x-pack/src/test/java/org/elasticsearch/xpack/action/TransportXPackInfoActionTests.java +++ b/elasticsearch/x-pack/src/test/java/org/elasticsearch/xpack/action/TransportXPackInfoActionTests.java @@ -9,14 +9,15 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.core.LicenseService; +import org.elasticsearch.license.XPackInfoResponse; +import org.elasticsearch.license.License; +import org.elasticsearch.license.LicenseService; import org.elasticsearch.xpack.security.user.AnonymousUser; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import org.elasticsearch.xpack.XPackFeatureSet; -import org.elasticsearch.xpack.action.XPackInfoResponse.FeatureSetsInfo.FeatureSet; +import org.elasticsearch.license.XPackInfoResponse.FeatureSetsInfo.FeatureSet; import org.junit.After; import org.junit.Before; diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherFeatureSet.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherFeatureSet.java index ad5aa66073b..61a3d87db7c 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherFeatureSet.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherFeatureSet.java @@ -12,7 +12,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.XPackFeatureSet; import java.io.IOException; diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherService.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherService.java index 88836a6448e..fb66c4d5062 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherService.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherService.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.watcher; import org.elasticsearch.ElasticsearchTimeoutException; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.common.bytes.BytesReference; @@ -15,7 +16,6 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.engine.VersionConflictEngineException; -import org.elasticsearch.xpack.common.stats.Counters; import org.elasticsearch.xpack.watcher.execution.ExecutionService; import org.elasticsearch.xpack.watcher.support.WatcherIndexTemplateRegistry; import org.elasticsearch.xpack.support.clock.Clock; @@ -29,7 +29,6 @@ import org.joda.time.DateTimeZone; import org.joda.time.PeriodType; import java.io.IOException; -import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; @@ -122,7 +121,7 @@ public class WatcherService extends AbstractComponent { } try { WatchStore.WatchDelete delete = watchStore.delete(id, force); - if (delete.deleteResponse().isFound()) { + if (delete.deleteResponse().getResult() == DocWriteResponse.Result.DELETED) { triggerService.remove(id); } return delete; diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionRegistry.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionRegistry.java index af126a8fbbb..018420f4273 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionRegistry.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionRegistry.java @@ -8,7 +8,7 @@ package org.elasticsearch.xpack.watcher.actions; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.support.clock.Clock; import org.elasticsearch.xpack.watcher.support.validation.Validation; import org.elasticsearch.xpack.watcher.transform.TransformRegistry; diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionWrapper.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionWrapper.java index 056ae4779fb..d0a1811ec3a 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionWrapper.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionWrapper.java @@ -14,7 +14,7 @@ import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.watcher.actions.throttler.ActionThrottler; import org.elasticsearch.xpack.watcher.actions.throttler.Throttler; import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext; diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/index/ExecutableIndexAction.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/index/ExecutableIndexAction.java index b5703c18ff1..2d78c24e3cf 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/index/ExecutableIndexAction.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/index/ExecutableIndexAction.java @@ -5,6 +5,7 @@ */ package org.elasticsearch.xpack.watcher.actions.index; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; @@ -116,7 +117,8 @@ public class ExecutableIndexAction extends ExecutableAction { static void indexResponseToXContent(XContentBuilder builder, IndexResponse response) throws IOException { builder.startObject() - .field("created", response.isCreated()) + .field("created", response.getResult() == DocWriteResponse.Result.CREATED) + .field("result", response.getResult().getLowercase()) .field("id", response.getId()) .field("version", response.getVersion()) .field("type", response.getType()) diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/throttler/ActionThrottler.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/throttler/ActionThrottler.java index d5fb240a574..ca070914a14 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/throttler/ActionThrottler.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/throttler/ActionThrottler.java @@ -7,7 +7,7 @@ package org.elasticsearch.xpack.watcher.actions.throttler; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext; import org.elasticsearch.xpack.support.clock.Clock; diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/WatcherTransportAction.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/WatcherTransportAction.java index a884e2f1068..ac748fcc211 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/WatcherTransportAction.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/WatcherTransportAction.java @@ -13,8 +13,8 @@ import org.elasticsearch.action.support.master.TransportMasterNodeAction; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.LicenseUtils; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.LicenseUtils; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/ack/TransportAckWatchAction.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/ack/TransportAckWatchAction.java index 0ccf499a414..c7bf383fcdf 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/ack/TransportAckWatchAction.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/ack/TransportAckWatchAction.java @@ -15,7 +15,7 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import org.elasticsearch.xpack.watcher.WatcherService; diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/activate/TransportActivateWatchAction.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/activate/TransportActivateWatchAction.java index 307c2122108..bb055963ea2 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/activate/TransportActivateWatchAction.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/activate/TransportActivateWatchAction.java @@ -15,7 +15,7 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import org.elasticsearch.xpack.watcher.WatcherService; diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/delete/TransportDeleteWatchAction.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/delete/TransportDeleteWatchAction.java index f90c20b9aca..cc12b25c90b 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/delete/TransportDeleteWatchAction.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/delete/TransportDeleteWatchAction.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.watcher.transport.actions.delete; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.delete.DeleteResponse; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.cluster.service.ClusterService; @@ -16,7 +17,7 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import org.elasticsearch.xpack.watcher.WatcherService; @@ -56,8 +57,8 @@ public class TransportDeleteWatchAction extends WatcherTransportAction> getMockPlugins() { - Collection> mockPlugins = super.getMockPlugins(); - mockPlugins.remove(MockMustacheScriptEngine.TestPlugin.class); - return mockPlugins; - } - - @Override - protected List> pluginTypes() { - List> types = super.pluginTypes(); - types.add(MustachePlugin.class); - return types; - } - @Override protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() @@ -148,7 +125,7 @@ public class HipChatServiceIT extends AbstractWatcherIntegrationTestCase { switch (profile) { case USER: account = "user_account"; - actionBuilder = hipchatAction(account, "{{ctx.payload.ref}}") + actionBuilder = hipchatAction(account, "_message") .addRooms("test-watcher", "test-watcher-2") .addUsers("watcher@elastic.co") .setFormat(HipChatMessage.Format.TEXT) @@ -158,7 +135,7 @@ public class HipChatServiceIT extends AbstractWatcherIntegrationTestCase { case INTEGRATION: account = "integration_account"; - actionBuilder = hipchatAction(account, "{{ctx.payload.ref}}") + actionBuilder = hipchatAction(account, "_message") .setFormat(HipChatMessage.Format.TEXT) .setColor(color) .setNotify(false); @@ -167,7 +144,7 @@ public class HipChatServiceIT extends AbstractWatcherIntegrationTestCase { default: assertThat(profile, is(HipChatAccount.Profile.V1)); account = "v1_account"; - actionBuilder = hipchatAction(account, "{{ctx.payload.ref}}") + actionBuilder = hipchatAction(account, "_message") .addRooms("test-watcher", "test-watcher-2") .setFrom("watcher-test") .setFormat(HipChatMessage.Format.TEXT) diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/NoMasterNodeIT.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/NoMasterNodeTests.java similarity index 92% rename from elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/NoMasterNodeIT.java rename to elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/NoMasterNodeTests.java index c84e46e9c51..4dff8ce194e 100644 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/NoMasterNodeIT.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/NoMasterNodeTests.java @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.messy.tests; +package org.elasticsearch.xpack.watcher.test.integration; import org.apache.lucene.util.LuceneTestCase.BadApple; import org.elasticsearch.ExceptionsHelper; @@ -18,9 +18,6 @@ import org.elasticsearch.discovery.zen.elect.ElectMasterService; import org.elasticsearch.discovery.zen.ping.ZenPing; import org.elasticsearch.discovery.zen.ping.ZenPingService; import org.elasticsearch.discovery.zen.ping.unicast.UnicastZenPing; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.script.MockMustacheScriptEngine; -import org.elasticsearch.script.mustache.MustachePlugin; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.test.ESIntegTestCase.SuppressLocalMode; import org.elasticsearch.test.discovery.ClusterDiscoveryConfiguration; @@ -36,10 +33,6 @@ import org.elasticsearch.xpack.watcher.test.WatcherTestUtils; import org.elasticsearch.xpack.watcher.transport.actions.delete.DeleteWatchResponse; import org.elasticsearch.xpack.watcher.transport.actions.stats.WatcherStatsResponse; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; import java.util.concurrent.TimeUnit; import static org.elasticsearch.index.query.QueryBuilders.termQuery; @@ -63,7 +56,7 @@ import static org.hamcrest.core.Is.is; @TestLogging("discovery:TRACE,watcher:TRACE") @ClusterScope(scope = TEST, numClientNodes = 0, transportClientRatio = 0, randomDynamicTemplates = false, numDataNodes = 0) @SuppressLocalMode -public class NoMasterNodeIT extends AbstractWatcherIntegrationTestCase { +public class NoMasterNodeTests extends AbstractWatcherIntegrationTestCase { private ClusterDiscoveryConfiguration.UnicastZen config; @Override @@ -88,23 +81,6 @@ public class NoMasterNodeIT extends AbstractWatcherIntegrationTestCase { .build(); } - @Override - protected Collection> nodePlugins() { - Collection> types = new ArrayList<>(); - types.addAll(super.nodePlugins()); - // TODO remove dependency on mustache - types.add(MustachePlugin.class); - return types; - } - - @Override - protected Collection> getMockPlugins() { - Set> plugins = new HashSet<>(super.getMockPlugins()); - // remove the mock because we use mustache here... - plugins.remove(MockMustacheScriptEngine.TestPlugin.class); - return plugins; - } - public void testSimpleFailure() throws Exception { // we need 3 hosts here because we stop the master and start another - it doesn't restart the pre-existing node... config = new ClusterDiscoveryConfiguration.UnicastZen(3, Settings.EMPTY); @@ -178,7 +154,7 @@ public class NoMasterNodeIT extends AbstractWatcherIntegrationTestCase { .trigger(schedule(interval("5s"))) .input(simpleInput("key", "value")) .condition(alwaysCondition()) - .addAction("_id", loggingAction("[{{ctx.watch_id}}] executed!")); + .addAction("_id", loggingAction("executed!")); watcherClient().preparePutWatch("_watch_id") .setSource(watchSource) diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/PagerDutyServiceIT.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/PagerDutyServiceTests.java similarity index 83% rename from elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/PagerDutyServiceIT.java rename to elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/PagerDutyServiceTests.java index 9f5e582b68a..f34f3ae4fde 100644 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/PagerDutyServiceIT.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/PagerDutyServiceTests.java @@ -3,13 +3,10 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.messy.tests; +package org.elasticsearch.xpack.watcher.test.integration; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.script.MockMustacheScriptEngine; -import org.elasticsearch.script.mustache.MustachePlugin; import org.elasticsearch.test.junit.annotations.Network; import org.elasticsearch.xpack.watcher.actions.pagerduty.PagerDutyAction; import org.elasticsearch.xpack.notification.pagerduty.IncidentEvent; @@ -21,9 +18,6 @@ import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase; import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse; import org.elasticsearch.xpack.watcher.watch.Payload; -import java.util.Collection; -import java.util.List; - import static org.elasticsearch.index.query.QueryBuilders.boolQuery; import static org.elasticsearch.index.query.QueryBuilders.termQuery; import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource; @@ -38,11 +32,8 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.lessThan; import static org.hamcrest.Matchers.notNullValue; -/** - * - */ @Network -public class PagerDutyServiceIT extends AbstractWatcherIntegrationTestCase { +public class PagerDutyServiceTests extends AbstractWatcherIntegrationTestCase { @Override protected boolean timeWarped() { @@ -54,20 +45,6 @@ public class PagerDutyServiceIT extends AbstractWatcherIntegrationTestCase { return false; } - @Override - protected Collection> getMockPlugins() { - Collection> mockPlugins = super.getMockPlugins(); - mockPlugins.remove(MockMustacheScriptEngine.TestPlugin.class); - return mockPlugins; - } - - @Override - protected List> pluginTypes() { - List> types = super.pluginTypes(); - types.add(MustachePlugin.class); - return types; - } - @Override protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() @@ -100,7 +77,7 @@ public class PagerDutyServiceIT extends AbstractWatcherIntegrationTestCase { public void testWatchWithPagerDutyAction() throws Exception { String account = "test_account"; PagerDutyAction.Builder actionBuilder = pagerDutyAction(IncidentEvent - .templateBuilder("pager duty integration test `{{ctx.payload.ref}}`").setAccount(account)); + .templateBuilder("pager duty integration test").setAccount(account)); PutWatchResponse putWatchResponse = watcherClient().preparePutWatch("1").setSource(watchBuilder() .trigger(schedule(interval("10m"))) diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SearchInputTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SearchInputTests.java new file mode 100644 index 00000000000..aa5c721369f --- /dev/null +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SearchInputTests.java @@ -0,0 +1,199 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.watcher.test.integration; + +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchType; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.json.JsonXContent; +import org.elasticsearch.common.xcontent.support.XContentMapValues; +import org.elasticsearch.indices.query.IndicesQueriesRegistry; +import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.plugins.ScriptPlugin; +import org.elasticsearch.script.MockMustacheScriptEngine; +import org.elasticsearch.script.ScriptContext; +import org.elasticsearch.script.ScriptService; +import org.elasticsearch.search.aggregations.AggregatorParsers; +import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.elasticsearch.search.suggest.Suggesters; +import org.elasticsearch.test.ESIntegTestCase; +import org.elasticsearch.test.ESIntegTestCase.ClusterScope; +import org.elasticsearch.xpack.watcher.actions.ExecutableActions; +import org.elasticsearch.xpack.watcher.condition.always.ExecutableAlwaysCondition; +import org.elasticsearch.xpack.watcher.execution.TriggeredExecutionContext; +import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext; +import org.elasticsearch.xpack.watcher.input.Input; +import org.elasticsearch.xpack.watcher.input.search.ExecutableSearchInput; +import org.elasticsearch.xpack.watcher.input.search.SearchInput; +import org.elasticsearch.xpack.watcher.input.search.SearchInputFactory; +import org.elasticsearch.xpack.watcher.input.simple.ExecutableSimpleInput; +import org.elasticsearch.xpack.watcher.input.simple.SimpleInput; +import org.elasticsearch.xpack.watcher.support.WatcherScript; +import org.elasticsearch.xpack.watcher.support.init.proxy.WatcherClientProxy; +import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateRequest; +import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateService; +import org.elasticsearch.xpack.watcher.trigger.schedule.IntervalSchedule; +import org.elasticsearch.xpack.watcher.trigger.schedule.ScheduleTrigger; +import org.elasticsearch.xpack.watcher.trigger.schedule.ScheduleTriggerEvent; +import org.elasticsearch.xpack.watcher.watch.Payload; +import org.elasticsearch.xpack.watcher.watch.Watch; +import org.elasticsearch.xpack.watcher.watch.WatchStatus; +import org.joda.time.DateTime; + +import java.util.ArrayList; +import java.util.Collection; + +import static java.util.Collections.emptyMap; +import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds; +import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; +import static org.elasticsearch.index.query.QueryBuilders.boolQuery; +import static org.elasticsearch.index.query.QueryBuilders.matchQuery; +import static org.elasticsearch.index.query.QueryBuilders.rangeQuery; +import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource; +import static org.elasticsearch.test.ESIntegTestCase.Scope.SUITE; +import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.getRandomSupportedSearchType; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.joda.time.DateTimeZone.UTC; + +@ClusterScope(scope = SUITE, numClientNodes = 0, transportClientRatio = 0, randomDynamicTemplates = false, supportsDedicatedMasters = false, + numDataNodes = 1) +public class SearchInputTests extends ESIntegTestCase { + + @Override + protected Collection> nodePlugins() { + Collection> types = new ArrayList<>(); + types.addAll(super.nodePlugins()); + types.add(MockMustacheScriptEngine.TestPlugin.class); + types.add(CustomScriptContextPlugin.class); + return types; + } + + public void testExecute() throws Exception { + SearchSourceBuilder searchSourceBuilder = searchSource().query( + boolQuery().must(matchQuery("event_type", "a"))); + SearchRequest searchRequest = client() + .prepareSearch() + .setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE) + .request() + .source(searchSourceBuilder); + + WatcherSearchTemplateRequest request = new WatcherSearchTemplateRequest(searchRequest); + ExecutableSearchInput searchInput = new ExecutableSearchInput(new SearchInput(request, null, null, null), logger, + WatcherClientProxy.of(client()), watcherSearchTemplateService(), null); + WatchExecutionContext ctx = new TriggeredExecutionContext( + new Watch("test-watch", + new ScheduleTrigger(new IntervalSchedule(new IntervalSchedule.Interval(1, IntervalSchedule.Interval.Unit.MINUTES))), + new ExecutableSimpleInput(new SimpleInput(new Payload.Simple()), logger), + new ExecutableAlwaysCondition(logger), + null, + null, + new ExecutableActions(new ArrayList<>()), + null, + new WatchStatus(new DateTime(0, UTC), emptyMap())), + new DateTime(0, UTC), + new ScheduleTriggerEvent("test-watch", new DateTime(0, UTC), new DateTime(0, UTC)), + timeValueSeconds(5)); + SearchInput.Result result = searchInput.execute(ctx, new Payload.Simple()); + + assertThat(XContentMapValues.extractValue("hits.total", result.payload().data()), equalTo(0)); + assertNotNull(result.executedRequest()); + assertThat(result.status(), is(Input.Result.Status.SUCCESS)); + assertEquals(result.executedRequest().searchType(), request.getRequest().searchType()); + assertArrayEquals(result.executedRequest().indices(), request.getRequest().indices()); + assertEquals(result.executedRequest().indicesOptions(), request.getRequest().indicesOptions()); + } + + public void testDifferentSearchType() throws Exception { + SearchSourceBuilder searchSourceBuilder = searchSource().query( + boolQuery().must(matchQuery("event_type", "a")) + ); + SearchType searchType = getRandomSupportedSearchType(); + + SearchRequest searchRequest = client() + .prepareSearch() + .setSearchType(searchType) + .request() + .source(searchSourceBuilder); + + WatcherSearchTemplateRequest request = new WatcherSearchTemplateRequest(searchRequest); + + ExecutableSearchInput searchInput = new ExecutableSearchInput(new SearchInput(request, null, null, null), logger, + WatcherClientProxy.of(client()), watcherSearchTemplateService(), null); + WatchExecutionContext ctx = new TriggeredExecutionContext( + new Watch("test-watch", + new ScheduleTrigger(new IntervalSchedule(new IntervalSchedule.Interval(1, IntervalSchedule.Interval.Unit.MINUTES))), + new ExecutableSimpleInput(new SimpleInput(new Payload.Simple()), logger), + new ExecutableAlwaysCondition(logger), + null, + null, + new ExecutableActions(new ArrayList<>()), + null, + new WatchStatus(new DateTime(0, UTC), emptyMap())), + new DateTime(0, UTC), + new ScheduleTriggerEvent("test-watch", new DateTime(0, UTC), new DateTime(0, UTC)), + timeValueSeconds(5)); + SearchInput.Result result = searchInput.execute(ctx, new Payload.Simple()); + + assertThat(XContentMapValues.extractValue("hits.total", result.payload().data()), equalTo(0)); + assertNotNull(result.executedRequest()); + assertThat(result.status(), is(Input.Result.Status.SUCCESS)); + assertEquals(result.executedRequest().searchType(), searchType); + assertArrayEquals(result.executedRequest().indices(), searchRequest.indices()); + assertEquals(result.executedRequest().indicesOptions(), searchRequest.indicesOptions()); + } + + public void testParserValid() throws Exception { + SearchRequest searchRequest = client().prepareSearch() + .setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE) + .request() + .source(searchSource() + .query(boolQuery().must(matchQuery("event_type", "a")).must(rangeQuery("_timestamp") + .from("{{ctx.trigger.scheduled_time}}||-30s").to("{{ctx.trigger.triggered_time}}")))); + + TimeValue timeout = randomBoolean() ? TimeValue.timeValueSeconds(randomInt(10)) : null; + XContentBuilder builder = jsonBuilder().value( + new SearchInput(new WatcherSearchTemplateRequest(searchRequest), null, timeout, null)); + XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes()); + parser.nextToken(); + + IndicesQueriesRegistry indicesQueryRegistry = internalCluster().getInstance(IndicesQueriesRegistry.class); + SearchInputFactory factory = new SearchInputFactory(Settings.EMPTY, WatcherClientProxy.of(client()), indicesQueryRegistry, + null, null, scriptService()); + + SearchInput searchInput = factory.parseInput("_id", parser); + assertEquals(SearchInput.TYPE, searchInput.type()); + assertThat(searchInput.getTimeout(), equalTo(timeout)); + } + + private WatcherSearchTemplateService watcherSearchTemplateService() { + String master = internalCluster().getMasterName(); + return new WatcherSearchTemplateService(internalCluster().clusterService(master).getSettings(), + internalCluster().getInstance(ScriptService.class, master), + internalCluster().getInstance(IndicesQueriesRegistry.class, master), + internalCluster().getInstance(AggregatorParsers.class, master), + internalCluster().getInstance(Suggesters.class, master) + ); + } + + private ScriptService scriptService() { + return internalCluster().getInstance(ScriptService.class); + } + + /** + * Custom plugin that registers XPack script context. + */ + public static class CustomScriptContextPlugin extends Plugin implements ScriptPlugin { + + @Override + public ScriptContext.Plugin getCustomScriptContexts() { + return WatcherScript.CTX_PLUGIN; + } + } +} diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/SearchTransformIT.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SearchTransformTests.java similarity index 53% rename from elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/SearchTransformIT.java rename to elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SearchTransformTests.java index c45db63abb7..b09a5c85b76 100644 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/SearchTransformIT.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SearchTransformTests.java @@ -3,15 +3,12 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.messy.tests; +package org.elasticsearch.xpack.watcher.test.integration; -import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequest; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchType; import org.elasticsearch.client.Requests; -import org.elasticsearch.common.bytes.BytesArray; -import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.ToXContent; @@ -24,9 +21,9 @@ import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.indices.query.IndicesQueriesRegistry; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.ScriptPlugin; +import org.elasticsearch.script.MockMustacheScriptEngine; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptService; -import org.elasticsearch.script.mustache.MustachePlugin; import org.elasticsearch.search.aggregations.AggregatorParsers; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.suggest.Suggesters; @@ -43,7 +40,6 @@ import org.elasticsearch.xpack.watcher.support.WatcherScript; import org.elasticsearch.xpack.watcher.support.init.proxy.WatcherClientProxy; import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateRequest; import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateService; -import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource; import org.elasticsearch.xpack.watcher.transform.Transform; import org.elasticsearch.xpack.watcher.transform.TransformBuilders; import org.elasticsearch.xpack.watcher.transform.search.ExecutableSearchTransform; @@ -56,35 +52,24 @@ import org.elasticsearch.xpack.watcher.watch.Payload; import org.elasticsearch.xpack.watcher.watch.Watch; import org.elasticsearch.xpack.watcher.watch.WatchStatus; import org.joda.time.DateTime; -import org.joda.time.chrono.ISOChronology; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.ArrayList; import java.util.Base64; import java.util.Collection; -import java.util.HashMap; import java.util.Map; import static java.util.Collections.emptyMap; import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.index.query.QueryBuilders.boolQuery; -import static org.elasticsearch.index.query.QueryBuilders.constantScoreQuery; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; -import static org.elasticsearch.index.query.QueryBuilders.rangeQuery; -import static org.elasticsearch.index.query.QueryBuilders.termQuery; import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource; import static org.elasticsearch.test.ESIntegTestCase.Scope.SUITE; -import static org.elasticsearch.xpack.watcher.support.WatcherDateTimeUtils.parseDate; import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.EMPTY_PAYLOAD; import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.getRandomSupportedSearchType; import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.mockExecutionContext; -import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.simplePayload; import static org.hamcrest.Matchers.arrayContainingInAnyOrder; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; @@ -94,63 +79,26 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.joda.time.DateTimeZone.UTC; -/** - * - */ @ClusterScope(scope = SUITE, numClientNodes = 0, transportClientRatio = 0, randomDynamicTemplates = false, supportsDedicatedMasters = false, numDataNodes = 1) -public class SearchTransformIT extends ESIntegTestCase { +public class SearchTransformTests extends ESIntegTestCase { @Override protected Collection> nodePlugins() { - Collection> types = new ArrayList<>(); - types.addAll(super.nodePlugins()); - types.add(MustachePlugin.class); - types.add(CustomScriptContextPlugin.class); - return types; - } - - @Override - public Settings nodeSettings(int nodeOrdinal) { - final Path tempDir = createTempDir(); - final Path configPath = tempDir.resolve("config"); - final Path scriptPath = configPath.resolve("scripts"); - try { - Files.createDirectories(scriptPath); - } catch (IOException e) { - throw new RuntimeException("failed to create config dir"); - - } - String path = "/org/elasticsearch/xpack/watcher/transform/search/config/scripts/test_disk_template.mustache"; - try (InputStream stream = SearchTransformIT.class.getResourceAsStream(path); - OutputStream out = Files.newOutputStream(scriptPath.resolve("test_disk_template.mustache"))) { - Streams.copy(stream, out); - } catch (IOException e) { - throw new RuntimeException("failed to copy mustache template"); - } - //Set path so ScriptService will pick up the test scripts - return Settings.builder() - .put(super.nodeSettings(nodeOrdinal)) - // we're not extending from the base watcher test case, so we should prevent the watcher plugin from being loaded - .put("path.conf", configPath).build(); - } - - @Override - protected Settings transportClientSettings() { - return Settings.builder() - .put(super.transportClientSettings()) - .build(); + Collection> plugins = new ArrayList<>(); + plugins.addAll(super.nodePlugins()); + plugins.add(CustomScriptContextPlugin.class); + plugins.add(MockMustacheScriptEngine.TestPlugin.class); + return plugins; } @Override public Settings indexSettings() { return Settings.builder() .put(super.indexSettings()) - // we have to test this on an index that has at least 2 shards. Otherwise when searching indices with // a single shard the QUERY_THEN_FETCH search type will change to QUERY_AND_FETCH during execution. .put("index.number_of_shards", randomIntBetween(2, 5)) - .build(); } @@ -232,71 +180,6 @@ public class SearchTransformIT extends ESIntegTestCase { } } - public void testExecuteMustacheTemplate() throws Exception { - - // The rational behind this test: - // - // - we index 4 documents each one associated with a unique value and each is associated with a day - // - we build a search transform such that with a filter that - // - the date must be after [scheduled_time] variable - // - the date must be before [execution_time] variable - // - the value must match [payload.value] variable - // - the variable are set as such: - // - scheduled_time = youngest document's date - // - fired_time = oldest document's date - // - payload.value = val_3 - // - when executed, the variables will be replaced with the scheduled_time, fired_time and the payload.value. - // - we set all these variables accordingly (the search transform is responsible to populate them) - // - when replaced correctly, the search should return document 3. - // - // we then do a search for document 3, and compare the response to the payload returned by the transform - - index("idx", "type", "1", doc("2015-01-01T00:00:00", "val_1")); - index("idx", "type", "2", doc("2015-01-02T00:00:00", "val_2")); - index("idx", "type", "3", doc("2015-01-03T00:00:00", "val_3")); - index("idx", "type", "4", doc("2015-01-04T00:00:00", "val_4")); - - ensureGreen("idx"); - refresh(); - - SearchRequest request = Requests.searchRequest("idx").source(searchSource().query(boolQuery() - .must(constantScoreQuery(rangeQuery("date").gt("{{ctx.trigger.scheduled_time}}"))) - .must(constantScoreQuery(rangeQuery("date").lt("{{ctx.execution_time}}"))) - .must(termQuery("value", "{{ctx.payload.value}}")))); - - SearchTransform searchTransform = TransformBuilders.searchTransform(request).build(); - ExecutableSearchTransform transform = new ExecutableSearchTransform(searchTransform, logger, WatcherClientProxy.of(client()), - watcherSearchTemplateService(), null); - - ScheduleTriggerEvent event = new ScheduleTriggerEvent("_name", parseDate("2015-01-04T00:00:00", UTC), - parseDate("2015-01-01T00:00:00", UTC)); - WatchExecutionContext ctx = mockExecutionContext("_name", parseDate("2015-01-04T00:00:00", UTC), event, EMPTY_PAYLOAD); - - Payload payload = simplePayload("value", "val_3"); - - Transform.Result result = transform.execute(ctx, payload); - assertThat(result, notNullValue()); - assertThat(result.type(), is(SearchTransform.TYPE)); - - SearchResponse response = client().prepareSearch("idx").setSearchType(ExecutableSearchTransform.DEFAULT_SEARCH_TYPE).setQuery( - boolQuery() - .must(constantScoreQuery(rangeQuery("date").gt(parseDate("2015-01-01T00:00:00", UTC)))) - .must(constantScoreQuery(rangeQuery("date").lt(parseDate("2015-01-04T00:00:00", UTC)))) - .must(termQuery("value", "val_3")) - ).get(); - Payload expectedPayload = new Payload.XContent(response); - - // we need to remove the "took" field from teh response as this is the only field - // that most likely be different between the two... we don't really care about this - // field, we just want to make sure that the important parts of the response are the same - Map resultData = result.payload().data(); - resultData.remove("took"); - Map expectedData = expectedPayload.data(); - expectedData.remove("took"); - - assertThat(resultData, equalTo(expectedData)); - } - public void testParser() throws Exception { String[] indices = rarely() ? null : randomBoolean() ? new String[] { "idx" } : new String[] { "idx1", "idx2" }; SearchType searchType = getRandomSupportedSearchType(); @@ -354,116 +237,11 @@ public class SearchTransformIT extends ESIntegTestCase { assertThat(executable.transform().getTimeout(), equalTo(readTimeout)); } - public void testSearchInlineTemplate() throws Exception { - WatchExecutionContext ctx = createContext(); - - final String templateQuery = "{\"query\":{\"bool\":{\"must\":[{\"match\":{\"event_type\":{\"query\":\"a\"," + - "\"type\":\"boolean\"}}},{\"range\":{\"_timestamp\":" + - "{\"from\":\"{{ctx.trigger.scheduled_time}}||-{{seconds_param}}\",\"to\":\"{{ctx.trigger.scheduled_time}}\"," + - "\"include_lower\":true,\"include_upper\":true}}}]}}}"; - - Map triggerParams = new HashMap(); - triggerParams.put("triggered_time", new DateTime(1970, 01, 01, 00, 01, 00, 000, ISOChronology.getInstanceUTC())); - triggerParams.put("scheduled_time", new DateTime(1970, 01, 01, 00, 01, 00, 000, ISOChronology.getInstanceUTC())); - Map ctxParams = new HashMap(); - ctxParams.put("id", ctx.id().value()); - ctxParams.put("metadata", null); - ctxParams.put("vars", new HashMap()); - ctxParams.put("watch_id", "test-watch"); - ctxParams.put("payload", new HashMap()); - ctxParams.put("trigger", triggerParams); - ctxParams.put("execution_time", new DateTime(1970, 01, 01, 00, 01, 00, 000, ISOChronology.getInstanceUTC())); - Map expectedParams = new HashMap(); - expectedParams.put("seconds_param", "30s"); - expectedParams.put("ctx", ctxParams); - - Map params = new HashMap<>(); - params.put("seconds_param", "30s"); - - WatcherScript template = WatcherScript.inline(templateQuery).lang("mustache").params(params).build(); - SearchRequest request = client().prepareSearch().setSearchType(ExecutableSearchTransform.DEFAULT_SEARCH_TYPE) - .setIndices("test-search-index").request(); - - SearchTransform.Result executedResult = executeSearchTransform(request, template, ctx); - - assertThat(executedResult.status(), is(Transform.Result.Status.SUCCESS)); - assertEquals(executedResult.executedRequest().searchType(), request.searchType()); - assertArrayEquals(executedResult.executedRequest().indices(), request.indices()); - assertEquals(executedResult.executedRequest().indicesOptions(), request.indicesOptions()); - - XContentSource source = toXContentSource(executedResult); - assertThat(source.getValue("query.bool.must.1.range._timestamp.from"), equalTo("1970-01-01T00:01:00.000Z||-30s")); - assertThat(source.getValue("query.bool.must.1.range._timestamp.to"), equalTo("1970-01-01T00:01:00.000Z")); - } - - public void testSearchIndexedTemplate() throws Exception { - WatchExecutionContext ctx = createContext(); - - final String templateQuery = "{\"query\":{\"bool\":{\"must\":[{\"match\":{\"event_type\":{\"query\":\"a\"," + - "\"type\":\"boolean\"}}},{\"range\":{\"_timestamp\":" + - "{\"from\":\"{{ctx.trigger.scheduled_time}}||-{{seconds_param}}\",\"to\":\"{{ctx.trigger.scheduled_time}}\"," + - "\"include_lower\":true,\"include_upper\":true}}}]}}}"; - - PutStoredScriptRequest indexedScriptRequest = client().admin().cluster().preparePutStoredScript() - .setId("test-script") - .setScriptLang("mustache") - .setSource(new BytesArray(templateQuery)) - .request(); - assertThat(client().admin().cluster().putStoredScript(indexedScriptRequest).actionGet().isAcknowledged(), is(true)); - - Map params = new HashMap<>(); - params.put("seconds_param", "30s"); - - WatcherScript template = WatcherScript.indexed("test-script").lang("mustache").params(params).build(); - - SearchRequest request = client() - .prepareSearch() - .setSearchType(ExecutableSearchTransform.DEFAULT_SEARCH_TYPE) - .setIndices("test-search-index") - .request(); - - SearchTransform.Result result = executeSearchTransform(request, template, ctx); - - assertNotNull(result.executedRequest()); - assertThat(result.status(), is(Transform.Result.Status.SUCCESS)); - assertArrayEquals(result.executedRequest().indices(), request.indices()); - assertEquals(result.executedRequest().indicesOptions(), request.indicesOptions()); - - XContentSource source = toXContentSource(result); - assertThat(source.getValue("query.bool.must.1.range._timestamp.from"), equalTo("1970-01-01T00:01:00.000Z||-30s")); - assertThat(source.getValue("query.bool.must.1.range._timestamp.to"), equalTo("1970-01-01T00:01:00.000Z")); - } - - public void testSearchOnDiskTemplate() throws Exception { - WatchExecutionContext ctx = createContext(); - - Map params = new HashMap<>(); - params.put("seconds_param", "30s"); - - WatcherScript template = WatcherScript.file("test_disk_template").lang("mustache").params(params).build(); - SearchRequest request = client().prepareSearch().setSearchType(ExecutableSearchTransform.DEFAULT_SEARCH_TYPE) - .setIndices("test-search-index").request(); - - SearchTransform.Result result = executeSearchTransform(request, template, ctx); - - assertNotNull(result.executedRequest()); - assertThat(result.status(), is(Transform.Result.Status.SUCCESS)); - assertArrayEquals(result.executedRequest().indices(), request.indices()); - assertEquals(result.executedRequest().indicesOptions(), request.indicesOptions()); - - XContentSource source = toXContentSource(result); - assertThat(source.getValue("query.bool.must.1.range._timestamp.from"), equalTo("1970-01-01T00:01:00.000Z||-30s")); - assertThat(source.getValue("query.bool.must.1.range._timestamp.to"), equalTo("1970-01-01T00:01:00.000Z")); - } - public void testDifferentSearchType() throws Exception { WatchExecutionContext ctx = createContext(); SearchSourceBuilder searchSourceBuilder = searchSource().query(boolQuery() - .must(matchQuery("event_type", "a")) - .must(rangeQuery("_timestamp") - .from("{{ctx.trigger.scheduled_time}}||-30s") - .to("{{ctx.trigger.triggered_time}}"))); + .must(matchQuery("event_type", "a"))); final SearchType searchType = getRandomSupportedSearchType(); SearchRequest request = client() @@ -480,10 +258,6 @@ public class SearchTransformIT extends ESIntegTestCase { assertThat(result.executedRequest().searchType(), is(searchType)); assertThat(result.executedRequest().indices(), arrayContainingInAnyOrder(request.indices())); assertThat(result.executedRequest().indicesOptions(), equalTo(request.indicesOptions())); - - XContentSource source = toXContentSource(result); - assertThat(source.getValue("query.bool.must.1.range._timestamp.from"), equalTo("1970-01-01T00:01:00.000Z||-30s")); - assertThat(source.getValue("query.bool.must.1.range._timestamp.to"), equalTo("1970-01-01T00:01:00.000Z")); } private WatchExecutionContext createContext() { @@ -515,7 +289,7 @@ public class SearchTransformIT extends ESIntegTestCase { return executableSearchTransform.execute(ctx, Payload.Simple.EMPTY); } - protected WatcherSearchTemplateService watcherSearchTemplateService() { + private WatcherSearchTemplateService watcherSearchTemplateService() { String master = internalCluster().getMasterName(); return new WatcherSearchTemplateService(internalCluster().clusterService(master).getSettings(), internalCluster().getInstance(ScriptService.class, master), @@ -525,24 +299,10 @@ public class SearchTransformIT extends ESIntegTestCase { ); } - protected ScriptService scriptService() { + private ScriptService scriptService() { return internalCluster().getInstance(ScriptService.class); } - private static Map doc(String date, String value) { - Map doc = new HashMap<>(); - doc.put("date", parseDate(date, UTC)); - doc.put("value", value); - return doc; - } - - private XContentSource toXContentSource(SearchTransform.Result result) throws IOException { - try (XContentBuilder builder = jsonBuilder()) { - result.executedRequest().source().toXContent(builder, ToXContent.EMPTY_PARAMS); - return new XContentSource(builder); - } - } - /** * Custom plugin that registers XPack script context. */ diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/SlackServiceIT.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SlackServiceTests.java similarity index 82% rename from elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/SlackServiceIT.java rename to elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SlackServiceTests.java index 8f83dcc73aa..16ba7afb603 100644 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/SlackServiceIT.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SlackServiceTests.java @@ -3,25 +3,20 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.messy.tests; +package org.elasticsearch.xpack.watcher.test.integration; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.script.MockMustacheScriptEngine; -import org.elasticsearch.script.mustache.MustachePlugin; import org.elasticsearch.test.junit.annotations.Network; -import org.elasticsearch.xpack.watcher.actions.slack.SlackAction; import org.elasticsearch.xpack.notification.slack.SentMessages; import org.elasticsearch.xpack.notification.slack.SlackAccount; import org.elasticsearch.xpack.notification.slack.SlackService; import org.elasticsearch.xpack.notification.slack.message.Attachment; import org.elasticsearch.xpack.notification.slack.message.SlackMessage; +import org.elasticsearch.xpack.watcher.actions.slack.SlackAction; import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase; import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse; - -import java.util.Collection; -import java.util.List; +import org.joda.time.DateTime; import static org.elasticsearch.index.query.QueryBuilders.boolQuery; import static org.elasticsearch.index.query.QueryBuilders.termQuery; @@ -36,11 +31,8 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.lessThan; import static org.hamcrest.Matchers.notNullValue; -/** - * - */ @Network -public class SlackServiceIT extends AbstractWatcherIntegrationTestCase { +public class SlackServiceTests extends AbstractWatcherIntegrationTestCase { @Override protected boolean timeWarped() { return true; @@ -51,20 +43,6 @@ public class SlackServiceIT extends AbstractWatcherIntegrationTestCase { return false; } - @Override - protected Collection> getMockPlugins() { - Collection> mockPlugins = super.getMockPlugins(); - mockPlugins.remove(MockMustacheScriptEngine.TestPlugin.class); - return mockPlugins; - } - - @Override - protected List> pluginTypes() { - List> types = super.pluginTypes(); - types.add(MustachePlugin.class); - return types; - } - @Override protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() @@ -72,7 +50,7 @@ public class SlackServiceIT extends AbstractWatcherIntegrationTestCase { // this is for the `test-watcher-integration` group level integration in HipChat .put("xpack.notification.slack.account.test_account.url", - "https://hooks.slack.com/services/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") + "https://hooks.slack.com/services/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") .build(); } @@ -86,7 +64,7 @@ public class SlackServiceIT extends AbstractWatcherIntegrationTestCase { "SlackServiceTests", new String[] { "#watcher-test", "#watcher-test-2"}, // TODO once we have a dedicated test user in slack, add it here null, - "slack integration test `testSendMessage()`", attachments); + "slack integration test `testSendMessage()` " + DateTime.now(), attachments); SlackAccount account = service.getAccount("test_account"); assertThat(account, notNullValue()); @@ -103,7 +81,7 @@ public class SlackServiceIT extends AbstractWatcherIntegrationTestCase { public void testWatchWithSlackAction() throws Exception { String account = "test_account"; SlackAction.Builder actionBuilder = slackAction(account, SlackMessage.Template.builder() - .setText("slack integration test `{{ctx.payload.ref}}`") + .setText("slack integration test` " + DateTime.now()) .addTo("#watcher-test", "#watcher-test-2")); PutWatchResponse putWatchResponse = watcherClient().preparePutWatch("1").setSource(watchBuilder() diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/WatchAckIT.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/WatchAckTests.java similarity index 92% rename from elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/WatchAckIT.java rename to elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/WatchAckTests.java index 0669ae7ad43..9664f41bcda 100644 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/WatchAckIT.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/WatchAckTests.java @@ -3,19 +3,17 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.messy.tests; +package org.elasticsearch.xpack.watcher.test.integration; import org.apache.lucene.util.LuceneTestCase.BadApple; import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.delete.DeleteResponse; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.script.MockMustacheScriptEngine; -import org.elasticsearch.script.mustache.MustachePlugin; import org.elasticsearch.xpack.watcher.actions.ActionStatus; import org.elasticsearch.xpack.watcher.client.WatcherClient; import org.elasticsearch.xpack.watcher.condition.compare.CompareCondition; @@ -32,10 +30,6 @@ import org.elasticsearch.xpack.watcher.watch.Watch; import org.elasticsearch.xpack.watcher.watch.WatchStore; import org.hamcrest.Matchers; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; import java.util.concurrent.TimeUnit; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; @@ -54,28 +48,9 @@ import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.core.IsEqual.equalTo; -/** - */ //test is just too slow, please fix it to not be sleep-based @BadApple(bugUrl = "https://github.com/elastic/x-plugins/issues/1007") -public class WatchAckIT extends AbstractWatcherIntegrationTestCase { - - @Override - protected Collection> nodePlugins() { - Collection> types = new ArrayList<>(); - types.addAll(super.nodePlugins()); - // TODO remove dependency on mustache - types.add(MustachePlugin.class); - return types; - } - - @Override - protected Collection> getMockPlugins() { - Set> plugins = new HashSet<>(super.getMockPlugins()); - // remove the mock because we use mustache here... - plugins.remove(MockMustacheScriptEngine.TestPlugin.class); - return plugins; - } +public class WatchAckTests extends AbstractWatcherIntegrationTestCase { private IndexResponse indexTestDoc() { createIndex("actions", "events"); @@ -84,7 +59,7 @@ public class WatchAckIT extends AbstractWatcherIntegrationTestCase { IndexResponse eventIndexResponse = client().prepareIndex("events", "event") .setSource("level", "error") .get(); - assertThat(eventIndexResponse.isCreated(), is(true)); + assertEquals(DocWriteResponse.Result.CREATED, eventIndexResponse.getResult()); refresh(); return eventIndexResponse; } @@ -140,7 +115,7 @@ public class WatchAckIT extends AbstractWatcherIntegrationTestCase { // Now delete the event and the ack states should change to AWAITS_EXECUTION DeleteResponse response = client().prepareDelete("events", "event", eventIndexResponse.getId()).get(); - assertThat(response.isFound(), is(true)); + assertEquals(DocWriteResponse.Result.DELETED, response.getResult()); refresh(); if (timeWarped()) { @@ -222,7 +197,7 @@ public class WatchAckIT extends AbstractWatcherIntegrationTestCase { // Now delete the event and the ack states should change to AWAITS_EXECUTION DeleteResponse response = client().prepareDelete("events", "event", eventIndexResponse.getId()).get(); - assertThat(response.isFound(), is(true)); + assertEquals(DocWriteResponse.Result.DELETED, response.getResult()); refresh(); if (timeWarped()) { diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/watch/WatchTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/watch/WatchTests.java index 121bcf639a7..aacba162bbc 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/watch/WatchTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/watch/WatchTests.java @@ -24,7 +24,7 @@ import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.index.query.MatchAllQueryBuilder; import org.elasticsearch.index.query.QueryParser; import org.elasticsearch.indices.query.IndicesQueriesRegistry; -import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.script.ScriptService; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.common.http.HttpClient;