Merge branch 'master' into security/redirect-to-login-on-401-xhr-response
Original commit: elastic/x-pack-elasticsearch@4a14381b93
This commit is contained in:
commit
a1e80e18c9
|
@ -1,3 +1,5 @@
|
||||||
|
import org.elasticsearch.gradle.precommit.LicenseHeadersTask
|
||||||
|
|
||||||
File checkstyleSuppressions = file('checkstyle_suppressions.xml')
|
File checkstyleSuppressions = file('checkstyle_suppressions.xml')
|
||||||
subprojects {
|
subprojects {
|
||||||
tasks.withType(Checkstyle) {
|
tasks.withType(Checkstyle) {
|
||||||
|
@ -7,4 +9,9 @@ subprojects {
|
||||||
suppressions: checkstyleSuppressions
|
suppressions: checkstyleSuppressions
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType(LicenseHeadersTask.class) {
|
||||||
|
approvedLicenses = ['Elasticsearch Confidential']
|
||||||
|
additionalLicense 'ESCON', 'Elasticsearch Confidential', 'ELASTICSEARCH CONFIDENTIAL'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,7 @@ public class License implements ToXContent {
|
||||||
case "gold":
|
case "gold":
|
||||||
return GOLD;
|
return GOLD;
|
||||||
case "platinum":
|
case "platinum":
|
||||||
|
case "cloud_internal":
|
||||||
case "internal": // bwc for 1.x subscription_type field
|
case "internal": // bwc for 1.x subscription_type field
|
||||||
return PLATINUM;
|
return PLATINUM;
|
||||||
default:
|
default:
|
||||||
|
@ -196,12 +197,42 @@ public class License implements ToXContent {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the operation mode of the license as computed from the license type
|
* @return the operation mode of the license as computed from the license type or from
|
||||||
|
* the license mode file
|
||||||
*/
|
*/
|
||||||
public OperationMode operationMode() {
|
public OperationMode operationMode() {
|
||||||
|
synchronized (this) {
|
||||||
|
if (canReadOperationModeFromFile() && operationModeFileWatcher != null) {
|
||||||
|
return operationModeFileWatcher.getCurrentOperationMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
return operationMode;
|
return operationMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean canReadOperationModeFromFile() {
|
||||||
|
return type.equals("cloud_internal");
|
||||||
|
}
|
||||||
|
|
||||||
|
private volatile OperationModeFileWatcher operationModeFileWatcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the operation mode file watcher for the license and initializes the
|
||||||
|
* file watcher when the license type allows to override operation mode from file
|
||||||
|
*/
|
||||||
|
public synchronized void setOperationModeFileWatcher(final OperationModeFileWatcher operationModeFileWatcher) {
|
||||||
|
this.operationModeFileWatcher = operationModeFileWatcher;
|
||||||
|
if (canReadOperationModeFromFile()) {
|
||||||
|
this.operationModeFileWatcher.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes operation mode file watcher, so unused license objects can be gc'ed
|
||||||
|
*/
|
||||||
|
public synchronized void removeOperationModeFileWatcher() {
|
||||||
|
this.operationModeFileWatcher = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the current license's status
|
* @return the current license's status
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* 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.core;
|
||||||
|
|
||||||
|
|
||||||
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
|
import org.elasticsearch.license.core.License.OperationMode;
|
||||||
|
import org.elasticsearch.watcher.FileChangesListener;
|
||||||
|
import org.elasticsearch.watcher.FileWatcher;
|
||||||
|
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File based watcher for license {@link OperationMode}
|
||||||
|
* Watches for changes in <code>licenseModePath</code>, use
|
||||||
|
* {@link #getCurrentOperationMode()} to access the latest mode
|
||||||
|
*
|
||||||
|
* In case of failure to read a valid operation mode from <code>licenseModePath</code>,
|
||||||
|
* the operation mode will default to PLATINUM
|
||||||
|
*/
|
||||||
|
public final class OperationModeFileWatcher extends FileChangesListener {
|
||||||
|
private final ResourceWatcherService resourceWatcherService;
|
||||||
|
private final Path licenseModePath;
|
||||||
|
private final AtomicBoolean initialized = new AtomicBoolean();
|
||||||
|
private final OperationMode defaultOperationMode = OperationMode.PLATINUM;
|
||||||
|
private volatile OperationMode currentOperationMode = defaultOperationMode;
|
||||||
|
private final ESLogger logger;
|
||||||
|
private final Runnable onChange;
|
||||||
|
|
||||||
|
public OperationModeFileWatcher(ResourceWatcherService resourceWatcherService, Path licenseModePath,
|
||||||
|
ESLogger logger, Runnable onChange) {
|
||||||
|
this.resourceWatcherService = resourceWatcherService;
|
||||||
|
this.licenseModePath = licenseModePath;
|
||||||
|
this.logger = logger;
|
||||||
|
this.onChange = onChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init() {
|
||||||
|
if (initialized.compareAndSet(false, true)) {
|
||||||
|
final FileWatcher watcher = new FileWatcher(licenseModePath);
|
||||||
|
watcher.addListener(this);
|
||||||
|
try {
|
||||||
|
resourceWatcherService.add(watcher, ResourceWatcherService.Frequency.HIGH);
|
||||||
|
if (Files.exists(licenseModePath)) {
|
||||||
|
onChange(licenseModePath);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("couldn't initialize watching license mode file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current operation mode based on license mode file.
|
||||||
|
* Defaults to {@link OperationMode#PLATINUM}
|
||||||
|
*/
|
||||||
|
public OperationMode getCurrentOperationMode() {
|
||||||
|
return currentOperationMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFileInit(Path file) {
|
||||||
|
onChange(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFileCreated(Path file) {
|
||||||
|
onChange(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFileDeleted(Path file) {
|
||||||
|
onChange(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFileChanged(Path file) {
|
||||||
|
onChange(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void onChange(Path file) {
|
||||||
|
if (file.equals(licenseModePath)) {
|
||||||
|
currentOperationMode = defaultOperationMode;
|
||||||
|
if (Files.exists(licenseModePath)
|
||||||
|
&& Files.isReadable(licenseModePath)) {
|
||||||
|
final byte[] content;
|
||||||
|
try {
|
||||||
|
content = Files.readAllBytes(licenseModePath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("couldn't read operation mode from [{}]", e, licenseModePath.toAbsolutePath().toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String operationMode = new String(content, StandardCharsets.UTF_8);
|
||||||
|
try {
|
||||||
|
currentOperationMode = OperationMode.resolve(operationMode);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
logger.error("invalid operation mode in [{}]", e, licenseModePath.toAbsolutePath().toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onChange.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* 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.core;
|
||||||
|
|
||||||
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
import org.elasticsearch.watcher.FileWatcher;
|
||||||
|
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||||
|
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;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||||
|
|
||||||
|
public class LicenseOperationModeUpdateTests extends ESTestCase {
|
||||||
|
|
||||||
|
private OperationModeFileWatcher operationModeFileWatcher;
|
||||||
|
private Path licenseModeFile;
|
||||||
|
private ResourceWatcherService resourceWatcherService;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() throws Exception {
|
||||||
|
licenseModeFile = createTempFile();
|
||||||
|
resourceWatcherService = mock(ResourceWatcherService.class);
|
||||||
|
operationModeFileWatcher = new OperationModeFileWatcher(resourceWatcherService, licenseModeFile, logger, () -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testLicenseOperationModeUpdate() throws Exception {
|
||||||
|
String type = randomFrom("trial", "basic", "standard", "gold", "platinum");
|
||||||
|
License license = License.builder()
|
||||||
|
.uid("id")
|
||||||
|
.expiryDate(0)
|
||||||
|
.issueDate(0)
|
||||||
|
.issuedTo("elasticsearch")
|
||||||
|
.issuer("issuer")
|
||||||
|
.type(type)
|
||||||
|
.maxNodes(1)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(license.operationMode(), equalTo(License.OperationMode.resolve(type)));
|
||||||
|
writeMode("gold", licenseModeFile);
|
||||||
|
license.setOperationModeFileWatcher(operationModeFileWatcher);
|
||||||
|
verifyZeroInteractions(resourceWatcherService);
|
||||||
|
assertThat(license.operationMode(), equalTo(License.OperationMode.resolve(type)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCloudInternalLicenseOperationModeUpdate() throws Exception {
|
||||||
|
License license = License.builder()
|
||||||
|
.uid("id")
|
||||||
|
.expiryDate(0)
|
||||||
|
.issueDate(0)
|
||||||
|
.issuedTo("elasticsearch")
|
||||||
|
.issuer("issuer")
|
||||||
|
.type("cloud_internal")
|
||||||
|
.maxNodes(1)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(license.operationMode(), equalTo(License.OperationMode.PLATINUM));
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* 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.core;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
import org.elasticsearch.threadpool.TestThreadPool;
|
||||||
|
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
public class OperationModeFileWatcherTests extends ESTestCase {
|
||||||
|
private ResourceWatcherService watcherService;
|
||||||
|
private TestThreadPool threadPool;
|
||||||
|
private Path licenseModePath;
|
||||||
|
private OperationModeFileWatcher operationModeFileWatcher;
|
||||||
|
private AtomicInteger onChangeCounter;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws Exception {
|
||||||
|
threadPool = new TestThreadPool("license mode file watcher tests");
|
||||||
|
Settings settings = Settings.builder()
|
||||||
|
.put("resource.reload.interval.high", "10ms")
|
||||||
|
.build();
|
||||||
|
watcherService = new ResourceWatcherService(settings,
|
||||||
|
threadPool);
|
||||||
|
watcherService.start();
|
||||||
|
licenseModePath = createTempFile();
|
||||||
|
onChangeCounter = new AtomicInteger();
|
||||||
|
operationModeFileWatcher = new OperationModeFileWatcher(watcherService, licenseModePath, logger,
|
||||||
|
() -> onChangeCounter.incrementAndGet());
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void shutdown() throws InterruptedException {
|
||||||
|
terminate(threadPool);
|
||||||
|
watcherService.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testInit() throws Exception {
|
||||||
|
writeMode("gold");
|
||||||
|
assertThat(operationModeFileWatcher.getCurrentOperationMode(), equalTo(License.OperationMode.PLATINUM));
|
||||||
|
operationModeFileWatcher.init();
|
||||||
|
assertThat(onChangeCounter.get(), equalTo(2));
|
||||||
|
assertThat(operationModeFileWatcher.getCurrentOperationMode(), equalTo(License.OperationMode.GOLD));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUpdateModeFromFile() throws Exception {
|
||||||
|
Files.delete(licenseModePath);
|
||||||
|
operationModeFileWatcher.init();
|
||||||
|
assertThat(operationModeFileWatcher.getCurrentOperationMode(), equalTo(License.OperationMode.PLATINUM));
|
||||||
|
writeMode("gold");
|
||||||
|
assertBusy(() -> assertThat(operationModeFileWatcher.getCurrentOperationMode(), equalTo(License.OperationMode.GOLD)));
|
||||||
|
writeMode("basic");
|
||||||
|
assertBusy(() -> assertThat(operationModeFileWatcher.getCurrentOperationMode(), equalTo(License.OperationMode.BASIC)));
|
||||||
|
assertThat(onChangeCounter.get(), equalTo(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDeleteModeFromFile() throws Exception {
|
||||||
|
Files.delete(licenseModePath);
|
||||||
|
operationModeFileWatcher.init();
|
||||||
|
writeMode("gold");
|
||||||
|
assertBusy(() -> assertThat(operationModeFileWatcher.getCurrentOperationMode(), equalTo(License.OperationMode.GOLD)));
|
||||||
|
Files.delete(licenseModePath);
|
||||||
|
assertBusy(() -> assertThat(operationModeFileWatcher.getCurrentOperationMode(), equalTo(License.OperationMode.PLATINUM)));
|
||||||
|
assertThat(onChangeCounter.get(), equalTo(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testInvalidModeFromFile() throws Exception {
|
||||||
|
writeMode("invalid");
|
||||||
|
operationModeFileWatcher.init();
|
||||||
|
assertThat(operationModeFileWatcher.getCurrentOperationMode(), equalTo(License.OperationMode.PLATINUM));
|
||||||
|
operationModeFileWatcher.onFileChanged(licenseModePath);
|
||||||
|
assertThat(operationModeFileWatcher.getCurrentOperationMode(), equalTo(License.OperationMode.PLATINUM));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testLicenseModeFileIsDirectory() throws Exception {
|
||||||
|
licenseModePath = createTempDir();
|
||||||
|
operationModeFileWatcher.init();
|
||||||
|
assertThat(operationModeFileWatcher.getCurrentOperationMode(), equalTo(License.OperationMode.PLATINUM));
|
||||||
|
operationModeFileWatcher.onFileChanged(licenseModePath);
|
||||||
|
assertThat(operationModeFileWatcher.getCurrentOperationMode(), equalTo(License.OperationMode.PLATINUM));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testLicenseModeFileCreatedAfterInit() throws Exception {
|
||||||
|
Files.delete(licenseModePath);
|
||||||
|
operationModeFileWatcher.init();
|
||||||
|
assertThat(operationModeFileWatcher.getCurrentOperationMode(), equalTo(License.OperationMode.PLATINUM));
|
||||||
|
Path tempFile = createTempFile();
|
||||||
|
writeMode("gold", tempFile);
|
||||||
|
licenseModePath = tempFile;
|
||||||
|
assertBusy(() -> assertThat(operationModeFileWatcher.getCurrentOperationMode(), equalTo(License.OperationMode.GOLD)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeMode(String mode) throws IOException {
|
||||||
|
writeMode(mode, licenseModePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeMode(String mode, Path file) throws IOException {
|
||||||
|
Files.write(file, mode.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,5 @@ subprojects {
|
||||||
project.forbiddenPatterns {
|
project.forbiddenPatterns {
|
||||||
exclude '**/*.key'
|
exclude '**/*.key'
|
||||||
}
|
}
|
||||||
// someone figure out what the x-plugins logic should be
|
|
||||||
project.licenseHeaders.enabled = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ project.sourceSets.test.output.dir(outputDir, builtBy: copyXPackPluginProps)
|
||||||
|
|
||||||
integTest {
|
integTest {
|
||||||
cluster {
|
cluster {
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
setting 'xpack.security.audit.enabled', 'true'
|
setting 'xpack.security.audit.enabled', 'true'
|
||||||
setting 'xpack.security.audit.outputs', 'index'
|
setting 'xpack.security.audit.outputs', 'index'
|
||||||
setting 'logger.level', 'DEBUG'
|
setting 'logger.level', 'DEBUG'
|
||||||
|
|
|
@ -38,11 +38,10 @@ public class IndexAuditIT extends ESIntegTestCase {
|
||||||
|
|
||||||
@AwaitsFix(bugUrl = "https://github.com/elastic/x-plugins/issues/2354")
|
@AwaitsFix(bugUrl = "https://github.com/elastic/x-plugins/issues/2354")
|
||||||
public void testShieldIndexAuditTrailWorking() throws Exception {
|
public void testShieldIndexAuditTrailWorking() throws Exception {
|
||||||
try (Response response = getRestClient().performRequest("GET", "/",
|
Response response = getRestClient().performRequest("GET", "/",
|
||||||
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
||||||
UsernamePasswordToken.basicAuthHeaderValue(USER, new SecuredString(PASS.toCharArray()))))) {
|
UsernamePasswordToken.basicAuthHeaderValue(USER, new SecuredString(PASS.toCharArray()))));
|
||||||
assertThat(response.getStatusLine().getStatusCode(), is(200));
|
assertThat(response.getStatusLine().getStatusCode(), is(200));
|
||||||
}
|
|
||||||
final AtomicReference<ClusterState> lastClusterState = new AtomicReference<>();
|
final AtomicReference<ClusterState> lastClusterState = new AtomicReference<>();
|
||||||
final AtomicBoolean indexExists = new AtomicBoolean(false);
|
final AtomicBoolean indexExists = new AtomicBoolean(false);
|
||||||
boolean found = awaitBusy(() -> {
|
boolean found = awaitBusy(() -> {
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
subprojects {
|
|
||||||
tasks.withType(org.elasticsearch.gradle.precommit.LicenseHeadersTask) {
|
|
||||||
// someone figure out what the x-plugins logic should be
|
|
||||||
project.licenseHeaders.enabled = false
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -34,7 +34,7 @@ integTest {
|
||||||
'search/80_date_math_index_names/Missing index with catch'].join(',')
|
'search/80_date_math_index_names/Missing index with catch'].join(',')
|
||||||
|
|
||||||
cluster {
|
cluster {
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
setting 'xpack.watcher.enabled', 'false'
|
setting 'xpack.watcher.enabled', 'false'
|
||||||
setting 'xpack.monitoring.enabled', 'false'
|
setting 'xpack.monitoring.enabled', 'false'
|
||||||
setupCommand 'setupDummyUser',
|
setupCommand 'setupDummyUser',
|
||||||
|
|
|
@ -7,29 +7,30 @@ package org.elasticsearch.xpack.security;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
import com.carrotsearch.randomizedtesting.annotations.Name;
|
||||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||||
|
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
|
||||||
import org.elasticsearch.test.rest.RestTestCandidate;
|
|
||||||
import org.elasticsearch.test.rest.parser.RestTestParseException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||||
|
|
||||||
public class RestIT extends ESRestTestCase {
|
public class CoreWithSecurityClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
||||||
|
|
||||||
private static final String USER = "test_user";
|
private static final String USER = "test_user";
|
||||||
private static final String PASS = "changeme";
|
private static final String PASS = "changeme";
|
||||||
|
|
||||||
public RestIT(@Name("yaml") RestTestCandidate testCandidate) {
|
public CoreWithSecurityClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
||||||
super(testCandidate);
|
super(testCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersFactory
|
@ParametersFactory
|
||||||
public static Iterable<Object[]> parameters() throws IOException, RestTestParseException {
|
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||||
return ESRestTestCase.createParameters(0, 1);
|
return ESClientYamlSuiteTestCase.createParameters(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -14,7 +14,7 @@ import org.elasticsearch.xpack.watcher.condition.script.ScriptCondition;
|
||||||
import org.elasticsearch.xpack.watcher.execution.ManualExecutionContext;
|
import org.elasticsearch.xpack.watcher.execution.ManualExecutionContext;
|
||||||
import org.elasticsearch.xpack.watcher.execution.ManualExecutionTests.ExecutionRunner;
|
import org.elasticsearch.xpack.watcher.execution.ManualExecutionTests.ExecutionRunner;
|
||||||
import org.elasticsearch.xpack.watcher.history.WatchRecord;
|
import org.elasticsearch.xpack.watcher.history.WatchRecord;
|
||||||
import org.elasticsearch.xpack.watcher.support.Script;
|
import org.elasticsearch.xpack.watcher.support.WatcherScript;
|
||||||
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
||||||
import org.elasticsearch.xpack.watcher.transport.actions.delete.DeleteWatchResponse;
|
import org.elasticsearch.xpack.watcher.transport.actions.delete.DeleteWatchResponse;
|
||||||
import org.elasticsearch.xpack.watcher.transport.actions.get.GetWatchRequest;
|
import org.elasticsearch.xpack.watcher.transport.actions.get.GetWatchRequest;
|
||||||
|
@ -65,7 +65,7 @@ public class GroovyManualExecutionIT extends AbstractWatcherIntegrationTestCase
|
||||||
WatchSourceBuilder watchBuilder = watchBuilder()
|
WatchSourceBuilder watchBuilder = watchBuilder()
|
||||||
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
|
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
|
||||||
.input(simpleInput("foo", "bar"))
|
.input(simpleInput("foo", "bar"))
|
||||||
.condition(new ScriptCondition((new Script.Builder.Inline("sleep 100; return true")).build()))
|
.condition(new ScriptCondition((new WatcherScript.Builder.Inline("sleep 100; return true")).build()))
|
||||||
.addAction("log", loggingAction("foobar"));
|
.addAction("log", loggingAction("foobar"));
|
||||||
|
|
||||||
Watch watch = watchParser().parse("_id", false, watchBuilder.buildAsBytes(XContentType.JSON));
|
Watch watch = watchParser().parse("_id", false, watchBuilder.buildAsBytes(XContentType.JSON));
|
||||||
|
@ -80,7 +80,7 @@ public class GroovyManualExecutionIT extends AbstractWatcherIntegrationTestCase
|
||||||
WatchSourceBuilder watchBuilder = watchBuilder()
|
WatchSourceBuilder watchBuilder = watchBuilder()
|
||||||
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
|
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
|
||||||
.input(simpleInput("foo", "bar"))
|
.input(simpleInput("foo", "bar"))
|
||||||
.condition(new ScriptCondition((new Script.Builder.Inline("sleep 10000; return true")).build()))
|
.condition(new ScriptCondition((new WatcherScript.Builder.Inline("sleep 10000; return true")).build()))
|
||||||
.defaultThrottlePeriod(new TimeValue(1, TimeUnit.HOURS))
|
.defaultThrottlePeriod(new TimeValue(1, TimeUnit.HOURS))
|
||||||
.addAction("log", loggingAction("foobar"));
|
.addAction("log", loggingAction("foobar"));
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.elasticsearch.messy.tests;
|
||||||
import org.elasticsearch.action.search.SearchRequestBuilder;
|
import org.elasticsearch.action.search.SearchRequestBuilder;
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.plugins.Plugin;
|
import org.elasticsearch.plugins.Plugin;
|
||||||
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.script.groovy.GroovyPlugin;
|
import org.elasticsearch.script.groovy.GroovyPlugin;
|
||||||
import org.elasticsearch.search.aggregations.AggregationBuilders;
|
import org.elasticsearch.search.aggregations.AggregationBuilders;
|
||||||
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
|
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
|
||||||
|
@ -16,8 +17,7 @@ import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.xpack.watcher.condition.script.ExecutableScriptCondition;
|
import org.elasticsearch.xpack.watcher.condition.script.ExecutableScriptCondition;
|
||||||
import org.elasticsearch.xpack.watcher.condition.script.ScriptCondition;
|
import org.elasticsearch.xpack.watcher.condition.script.ScriptCondition;
|
||||||
import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext;
|
import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext;
|
||||||
import org.elasticsearch.xpack.watcher.support.Script;
|
import org.elasticsearch.xpack.watcher.support.WatcherScript;
|
||||||
import org.elasticsearch.xpack.common.ScriptServiceProxy;
|
|
||||||
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
||||||
import org.elasticsearch.xpack.watcher.watch.Payload;
|
import org.elasticsearch.xpack.watcher.watch.Payload;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
@ -28,7 +28,7 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static org.elasticsearch.messy.tests.MessyTestUtils.getScriptServiceProxy;
|
import static org.elasticsearch.messy.tests.MessyTestUtils.createScriptService;
|
||||||
import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.mockExecutionContext;
|
import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.mockExecutionContext;
|
||||||
|
|
||||||
public class GroovyScriptConditionIT extends AbstractWatcherIntegrationTestCase {
|
public class GroovyScriptConditionIT extends AbstractWatcherIntegrationTestCase {
|
||||||
|
@ -46,7 +46,7 @@ public class GroovyScriptConditionIT extends AbstractWatcherIntegrationTestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ThreadPool THREAD_POOL;
|
private static ThreadPool THREAD_POOL;
|
||||||
private ScriptServiceProxy scriptService;
|
private ScriptService scriptService;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void startThreadPool() {
|
public static void startThreadPool() {
|
||||||
|
@ -55,7 +55,7 @@ public class GroovyScriptConditionIT extends AbstractWatcherIntegrationTestCase
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void init() throws Exception {
|
public void init() throws Exception {
|
||||||
scriptService = getScriptServiceProxy(THREAD_POOL);
|
scriptService = createScriptService(THREAD_POOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
|
@ -83,7 +83,7 @@ public class GroovyScriptConditionIT extends AbstractWatcherIntegrationTestCase
|
||||||
SearchResponse unmetResponse = builder.get();
|
SearchResponse unmetResponse = builder.get();
|
||||||
|
|
||||||
ExecutableScriptCondition condition =
|
ExecutableScriptCondition condition =
|
||||||
new ExecutableScriptCondition(new ScriptCondition(Script.inline(
|
new ExecutableScriptCondition(new ScriptCondition(WatcherScript.inline(
|
||||||
String.join(
|
String.join(
|
||||||
" ",
|
" ",
|
||||||
"if (ctx.payload.hits.total < 1) return false;",
|
"if (ctx.payload.hits.total < 1) return false;",
|
||||||
|
|
|
@ -1,215 +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.search.SearchRequest;
|
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
|
||||||
import org.elasticsearch.action.search.SearchType;
|
|
||||||
import org.elasticsearch.plugins.Plugin;
|
|
||||||
import org.elasticsearch.script.groovy.GroovyPlugin;
|
|
||||||
import org.elasticsearch.search.SearchHit;
|
|
||||||
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
|
|
||||||
import org.elasticsearch.search.sort.SortOrder;
|
|
||||||
import org.elasticsearch.xpack.watcher.history.HistoryStore;
|
|
||||||
import org.elasticsearch.xpack.watcher.support.WatcherDateTimeUtils;
|
|
||||||
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
|
||||||
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchResponse;
|
|
||||||
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
|
|
||||||
import org.elasticsearch.xpack.watcher.trigger.schedule.ScheduleTriggerEvent;
|
|
||||||
import org.joda.time.DateTime;
|
|
||||||
import org.joda.time.DateTimeZone;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
|
|
||||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.dateHistogram;
|
|
||||||
import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource;
|
|
||||||
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.indexAction;
|
|
||||||
import static org.elasticsearch.xpack.watcher.client.WatchSourceBuilders.watchBuilder;
|
|
||||||
import static org.elasticsearch.xpack.watcher.input.InputBuilders.searchInput;
|
|
||||||
import static org.elasticsearch.xpack.watcher.input.InputBuilders.simpleInput;
|
|
||||||
import static org.elasticsearch.xpack.watcher.transform.TransformBuilders.scriptTransform;
|
|
||||||
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
|
|
||||||
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.cron;
|
|
||||||
import static org.hamcrest.Matchers.hasEntry;
|
|
||||||
import static org.hamcrest.Matchers.hasKey;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class IndexActionIT extends AbstractWatcherIntegrationTestCase {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<Class<? extends Plugin>> pluginTypes() {
|
|
||||||
List<Class<? extends Plugin>> types = super.pluginTypes();
|
|
||||||
types.add(GroovyPlugin.class);
|
|
||||||
return types;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSimple() throws Exception {
|
|
||||||
PutWatchResponse putWatchResponse = watcherClient().preparePutWatch("_id").setSource(watchBuilder()
|
|
||||||
.trigger(schedule(cron("0/1 * * * * ? 2020")))
|
|
||||||
.input(simpleInput("foo", "bar"))
|
|
||||||
.addAction("index-buckets", indexAction("idx", "type").setExecutionTimeField("@timestamp")))
|
|
||||||
.get();
|
|
||||||
|
|
||||||
assertThat(putWatchResponse.isCreated(), is(true));
|
|
||||||
|
|
||||||
DateTime now = timeWarped() ? timeWarp().clock().now(DateTimeZone.UTC) : DateTime.now(DateTimeZone.UTC);
|
|
||||||
|
|
||||||
ExecuteWatchResponse executeWatchResponse = watcherClient().prepareExecuteWatch("_id")
|
|
||||||
.setTriggerEvent(new ScheduleTriggerEvent(now, now))
|
|
||||||
.get();
|
|
||||||
|
|
||||||
assertThat(executeWatchResponse.getRecordSource().getValue("state"), is((Object) "executed"));
|
|
||||||
|
|
||||||
flush("idx");
|
|
||||||
refresh();
|
|
||||||
|
|
||||||
SearchResponse searchResponse = client().prepareSearch("idx").setTypes("type").get();
|
|
||||||
assertThat(searchResponse.getHits().totalHits(), is(1L));
|
|
||||||
SearchHit hit = searchResponse.getHits().getAt(0);
|
|
||||||
if (timeWarped()) {
|
|
||||||
assertThat(hit.getSource(), hasEntry("@timestamp", (Object) WatcherDateTimeUtils.formatDate(now)));
|
|
||||||
} else {
|
|
||||||
assertThat(hit.getSource(), hasKey("@timestamp"));
|
|
||||||
DateTime timestamp = WatcherDateTimeUtils.parseDate((String) hit.getSource().get("@timestamp"));
|
|
||||||
assertThat(timestamp.isEqual(now) || timestamp.isAfter(now), is(true));
|
|
||||||
}
|
|
||||||
assertThat(hit.getSource(), hasEntry("foo", (Object) "bar"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSimpleWithDocField() throws Exception {
|
|
||||||
PutWatchResponse putWatchResponse = watcherClient().preparePutWatch("_id").setSource(watchBuilder()
|
|
||||||
.trigger(schedule(cron("0/1 * * * * ? 2020")))
|
|
||||||
.input(simpleInput("foo", "bar"))
|
|
||||||
.addAction("index-buckets",
|
|
||||||
scriptTransform("return [ '_doc' : ctx.payload ]"),
|
|
||||||
indexAction("idx", "type").setExecutionTimeField("@timestamp")))
|
|
||||||
|
|
||||||
.get();
|
|
||||||
|
|
||||||
assertThat(putWatchResponse.isCreated(), is(true));
|
|
||||||
|
|
||||||
DateTime now = timeWarped() ? timeWarp().clock().now(DateTimeZone.UTC) : DateTime.now(DateTimeZone.UTC);
|
|
||||||
|
|
||||||
ExecuteWatchResponse executeWatchResponse = watcherClient().prepareExecuteWatch("_id")
|
|
||||||
.setTriggerEvent(new ScheduleTriggerEvent(now, now))
|
|
||||||
.get();
|
|
||||||
|
|
||||||
assertThat(executeWatchResponse.getRecordSource().getValue("state"), is((Object) "executed"));
|
|
||||||
|
|
||||||
flush("idx");
|
|
||||||
refresh();
|
|
||||||
|
|
||||||
SearchResponse searchResponse = client().prepareSearch("idx").setTypes("type").get();
|
|
||||||
assertThat(searchResponse.getHits().totalHits(), is(1L));
|
|
||||||
SearchHit hit = searchResponse.getHits().getAt(0);
|
|
||||||
if (timeWarped()) {
|
|
||||||
assertThat(hit.getSource(), hasEntry("@timestamp", (Object) WatcherDateTimeUtils.formatDate(now)));
|
|
||||||
} else {
|
|
||||||
assertThat(hit.getSource(), hasKey("@timestamp"));
|
|
||||||
DateTime timestamp = WatcherDateTimeUtils.parseDate((String) hit.getSource().get("@timestamp"));
|
|
||||||
assertThat(timestamp.isEqual(now) || timestamp.isAfter(now), is(true));
|
|
||||||
}
|
|
||||||
assertThat(hit.getSource(), hasEntry("foo", (Object) "bar"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSimpleWithDocFieldWrongFieldType() throws Exception {
|
|
||||||
PutWatchResponse putWatchResponse = watcherClient().preparePutWatch("_id").setSource(watchBuilder()
|
|
||||||
.trigger(schedule(cron("0/1 * * * * ? 2020")))
|
|
||||||
.input(simpleInput("foo", "bar"))
|
|
||||||
.addAction("index-buckets",
|
|
||||||
scriptTransform("return [ '_doc' : 1 ]"),
|
|
||||||
indexAction("idx", "type").setExecutionTimeField("@timestamp")))
|
|
||||||
.get();
|
|
||||||
|
|
||||||
assertThat(putWatchResponse.isCreated(), is(true));
|
|
||||||
|
|
||||||
DateTime now = timeWarped() ? timeWarp().clock().now(DateTimeZone.UTC) : DateTime.now(DateTimeZone.UTC);
|
|
||||||
|
|
||||||
ExecuteWatchResponse executeWatchResponse = watcherClient().prepareExecuteWatch("_id")
|
|
||||||
.setTriggerEvent(new ScheduleTriggerEvent(now, now))
|
|
||||||
.setRecordExecution(true)
|
|
||||||
.get();
|
|
||||||
|
|
||||||
assertThat(executeWatchResponse.getRecordSource().getValue("state"), is((Object) "executed"));
|
|
||||||
|
|
||||||
flush();
|
|
||||||
refresh();
|
|
||||||
|
|
||||||
assertThat(client().admin().indices().prepareExists("idx").get().isExists(), is(false));
|
|
||||||
|
|
||||||
assertThat(docCount(HistoryStore.INDEX_PREFIX + "*", HistoryStore.DOC_TYPE, searchSource()
|
|
||||||
.query(matchQuery("result.actions.status", "failure"))), is(1L));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testIndexAggsBucketsAsDocuments() throws Exception {
|
|
||||||
DateTime now = timeWarped() ? timeWarp().clock().now(DateTimeZone.UTC) : DateTime.now(DateTimeZone.UTC);
|
|
||||||
long bucketCount = randomIntBetween(2, 5);
|
|
||||||
for (int i = 0; i < bucketCount; i++) {
|
|
||||||
index("idx", "type", jsonBuilder().startObject()
|
|
||||||
.field("timestamp", now.minusDays(i))
|
|
||||||
.endObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
flush("idx");
|
|
||||||
refresh();
|
|
||||||
|
|
||||||
PutWatchResponse putWatchResponse = watcherClient().preparePutWatch("_id").setSource(watchBuilder()
|
|
||||||
.trigger(schedule(cron("0/1 * * * * ? 2020")))
|
|
||||||
.input(searchInput(new SearchRequest("idx")
|
|
||||||
.types("type")
|
|
||||||
.searchType(SearchType.QUERY_THEN_FETCH)
|
|
||||||
.source(searchSource()
|
|
||||||
.aggregation(dateHistogram("trend")
|
|
||||||
.field("timestamp")
|
|
||||||
.dateHistogramInterval(DateHistogramInterval.DAY)))))
|
|
||||||
.addAction("index-buckets",
|
|
||||||
|
|
||||||
// this transform takes the bucket list and assigns it to `_doc`
|
|
||||||
// this means each bucket will be indexed as a separate doc,
|
|
||||||
// so we expect to have the same number of documents as the number
|
|
||||||
// of buckets.
|
|
||||||
scriptTransform("return [ '_doc' : ctx.payload.aggregations.trend.buckets]"),
|
|
||||||
|
|
||||||
indexAction("idx", "bucket").setExecutionTimeField("@timestamp")))
|
|
||||||
|
|
||||||
.get();
|
|
||||||
|
|
||||||
assertThat(putWatchResponse.isCreated(), is(true));
|
|
||||||
|
|
||||||
ExecuteWatchResponse executeWatchResponse = watcherClient().prepareExecuteWatch("_id")
|
|
||||||
.setTriggerEvent(new ScheduleTriggerEvent(now, now))
|
|
||||||
.get();
|
|
||||||
|
|
||||||
assertThat(executeWatchResponse.getRecordSource().getValue("state"), is((Object) "executed"));
|
|
||||||
|
|
||||||
flush("idx");
|
|
||||||
refresh();
|
|
||||||
|
|
||||||
SearchResponse searchResponse = client().prepareSearch("idx").setTypes("bucket")
|
|
||||||
.addSort("key", SortOrder.DESC)
|
|
||||||
.get();
|
|
||||||
assertThat(searchResponse.getHits().getTotalHits(), is(bucketCount));
|
|
||||||
DateTime key = now.withMillisOfDay(0);
|
|
||||||
int i = 0;
|
|
||||||
for (SearchHit hit : searchResponse.getHits()) {
|
|
||||||
if (timeWarped()) {
|
|
||||||
assertThat(hit.getSource(), hasEntry("@timestamp", (Object) WatcherDateTimeUtils.formatDate(now)));
|
|
||||||
} else {
|
|
||||||
assertThat(hit.getSource(), hasKey("@timestamp"));
|
|
||||||
DateTime timestamp = WatcherDateTimeUtils.parseDate((String) hit.getSource().get("@timestamp"));
|
|
||||||
assertThat(timestamp.isEqual(now) || timestamp.isAfter(now), is(true));
|
|
||||||
}
|
|
||||||
assertThat(hit.getSource(), hasEntry("key", (Object) key.getMillis()));
|
|
||||||
key = key.minusDays(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,9 +6,6 @@
|
||||||
package org.elasticsearch.messy.tests;
|
package org.elasticsearch.messy.tests;
|
||||||
|
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
import org.elasticsearch.cluster.ClusterName;
|
|
||||||
import org.elasticsearch.cluster.ClusterState;
|
|
||||||
import org.elasticsearch.cluster.service.ClusterService;
|
|
||||||
import org.elasticsearch.common.SuppressForbidden;
|
import org.elasticsearch.common.SuppressForbidden;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.env.Environment;
|
import org.elasticsearch.env.Environment;
|
||||||
|
@ -19,9 +16,8 @@ import org.elasticsearch.script.ScriptSettings;
|
||||||
import org.elasticsearch.script.groovy.GroovyScriptEngineService;
|
import org.elasticsearch.script.groovy.GroovyScriptEngineService;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.watcher.ResourceWatcherService;
|
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||||
import org.elasticsearch.xpack.common.ScriptServiceProxy;
|
import org.elasticsearch.xpack.watcher.support.WatcherScript;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.mockito.Mockito;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -29,7 +25,7 @@ import java.util.Collections;
|
||||||
@Ignore // not a test.
|
@Ignore // not a test.
|
||||||
@SuppressForbidden(reason = "gradle is broken and tries to run me as a test")
|
@SuppressForbidden(reason = "gradle is broken and tries to run me as a test")
|
||||||
public final class MessyTestUtils {
|
public final class MessyTestUtils {
|
||||||
public static ScriptServiceProxy getScriptServiceProxy(ThreadPool tp) throws Exception {
|
public static ScriptService createScriptService(ThreadPool tp) throws Exception {
|
||||||
Settings settings = Settings.builder()
|
Settings settings = Settings.builder()
|
||||||
.put("script.inline", "true")
|
.put("script.inline", "true")
|
||||||
.put("script.indexed", "true")
|
.put("script.indexed", "true")
|
||||||
|
@ -37,10 +33,10 @@ public final class MessyTestUtils {
|
||||||
.build();
|
.build();
|
||||||
GroovyScriptEngineService groovyScriptEngineService = new GroovyScriptEngineService(settings);
|
GroovyScriptEngineService groovyScriptEngineService = new GroovyScriptEngineService(settings);
|
||||||
ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry(Collections.singleton(groovyScriptEngineService));
|
ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry(Collections.singleton(groovyScriptEngineService));
|
||||||
ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Arrays.asList(ScriptServiceProxy.INSTANCE));
|
ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Arrays.asList(WatcherScript.CTX_PLUGIN));
|
||||||
|
|
||||||
ScriptSettings scriptSettings = new ScriptSettings(scriptEngineRegistry, scriptContextRegistry);
|
ScriptSettings scriptSettings = new ScriptSettings(scriptEngineRegistry, scriptContextRegistry);
|
||||||
return ScriptServiceProxy.of(new ScriptService(settings, new Environment(settings),
|
return new ScriptService(settings, new Environment(settings), new ResourceWatcherService(settings, tp),
|
||||||
new ResourceWatcherService(settings, tp), scriptEngineRegistry, scriptContextRegistry, scriptSettings));
|
scriptEngineRegistry, scriptContextRegistry, scriptSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import org.elasticsearch.action.search.ShardSearchFailure;
|
||||||
import org.elasticsearch.common.text.Text;
|
import org.elasticsearch.common.text.Text;
|
||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.plugins.Plugin;
|
import org.elasticsearch.plugins.Plugin;
|
||||||
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.script.groovy.GroovyPlugin;
|
import org.elasticsearch.script.groovy.GroovyPlugin;
|
||||||
import org.elasticsearch.search.SearchShardTarget;
|
import org.elasticsearch.search.SearchShardTarget;
|
||||||
import org.elasticsearch.search.aggregations.AggregationBuilders;
|
import org.elasticsearch.search.aggregations.AggregationBuilders;
|
||||||
|
@ -20,11 +21,10 @@ import org.elasticsearch.search.internal.InternalSearchHits;
|
||||||
import org.elasticsearch.search.internal.InternalSearchResponse;
|
import org.elasticsearch.search.internal.InternalSearchResponse;
|
||||||
import org.elasticsearch.threadpool.TestThreadPool;
|
import org.elasticsearch.threadpool.TestThreadPool;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.xpack.common.ScriptServiceProxy;
|
|
||||||
import org.elasticsearch.xpack.watcher.condition.script.ExecutableScriptCondition;
|
import org.elasticsearch.xpack.watcher.condition.script.ExecutableScriptCondition;
|
||||||
import org.elasticsearch.xpack.watcher.condition.script.ScriptCondition;
|
import org.elasticsearch.xpack.watcher.condition.script.ScriptCondition;
|
||||||
import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext;
|
import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext;
|
||||||
import org.elasticsearch.xpack.watcher.support.Script;
|
import org.elasticsearch.xpack.watcher.support.WatcherScript;
|
||||||
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
||||||
import org.elasticsearch.xpack.watcher.watch.Payload;
|
import org.elasticsearch.xpack.watcher.watch.Payload;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
@ -40,7 +40,7 @@ import static org.mockito.Mockito.when;
|
||||||
*/
|
*/
|
||||||
public class ScriptConditionSearchIT extends AbstractWatcherIntegrationTestCase {
|
public class ScriptConditionSearchIT extends AbstractWatcherIntegrationTestCase {
|
||||||
private ThreadPool tp = null;
|
private ThreadPool tp = null;
|
||||||
private ScriptServiceProxy scriptService;
|
private ScriptService scriptService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<Class<? extends Plugin>> pluginTypes() {
|
protected List<Class<? extends Plugin>> pluginTypes() {
|
||||||
|
@ -52,7 +52,7 @@ public class ScriptConditionSearchIT extends AbstractWatcherIntegrationTestCase
|
||||||
@Before
|
@Before
|
||||||
public void init() throws Exception {
|
public void init() throws Exception {
|
||||||
tp = new TestThreadPool(ThreadPool.Names.SAME);
|
tp = new TestThreadPool(ThreadPool.Names.SAME);
|
||||||
scriptService = MessyTestUtils.getScriptServiceProxy(tp);
|
scriptService = MessyTestUtils.createScriptService(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -73,7 +73,7 @@ public class ScriptConditionSearchIT extends AbstractWatcherIntegrationTestCase
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
ExecutableScriptCondition condition = new ExecutableScriptCondition(
|
ExecutableScriptCondition condition = new ExecutableScriptCondition(
|
||||||
new ScriptCondition(Script.inline("ctx.payload.aggregations.rate.buckets[0]?.doc_count >= 5").build()),
|
new ScriptCondition(WatcherScript.inline("ctx.payload.aggregations.rate.buckets[0]?.doc_count >= 5").build()),
|
||||||
logger, scriptService);
|
logger, scriptService);
|
||||||
|
|
||||||
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
|
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
|
||||||
|
@ -92,7 +92,7 @@ public class ScriptConditionSearchIT extends AbstractWatcherIntegrationTestCase
|
||||||
|
|
||||||
public void testExecuteAccessHits() throws Exception {
|
public void testExecuteAccessHits() throws Exception {
|
||||||
ExecutableScriptCondition condition = new ExecutableScriptCondition(new ScriptCondition(
|
ExecutableScriptCondition condition = new ExecutableScriptCondition(new ScriptCondition(
|
||||||
Script.inline("ctx.payload.hits?.hits[0]?._score == 1.0").build()), logger, scriptService);
|
WatcherScript.inline("ctx.payload.hits?.hits[0]?._score == 1.0").build()), logger, scriptService);
|
||||||
InternalSearchHit hit = new InternalSearchHit(0, "1", new Text("type"), null);
|
InternalSearchHit hit = new InternalSearchHit(0, "1", new Text("type"), null);
|
||||||
hit.score(1f);
|
hit.score(1f);
|
||||||
hit.shard(new SearchShardTarget("a", new Index("a", "testUUID"), 0));
|
hit.shard(new SearchShardTarget("a", new Index("a", "testUUID"), 0));
|
||||||
|
|
|
@ -15,17 +15,17 @@ import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.script.GeneralScriptException;
|
import org.elasticsearch.script.GeneralScriptException;
|
||||||
import org.elasticsearch.script.ScriptException;
|
import org.elasticsearch.script.ScriptException;
|
||||||
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.script.ScriptService.ScriptType;
|
import org.elasticsearch.script.ScriptService.ScriptType;
|
||||||
import org.elasticsearch.search.internal.InternalSearchResponse;
|
import org.elasticsearch.search.internal.InternalSearchResponse;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.threadpool.TestThreadPool;
|
import org.elasticsearch.threadpool.TestThreadPool;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.xpack.common.ScriptServiceProxy;
|
|
||||||
import org.elasticsearch.xpack.watcher.condition.script.ExecutableScriptCondition;
|
import org.elasticsearch.xpack.watcher.condition.script.ExecutableScriptCondition;
|
||||||
import org.elasticsearch.xpack.watcher.condition.script.ScriptCondition;
|
import org.elasticsearch.xpack.watcher.condition.script.ScriptCondition;
|
||||||
import org.elasticsearch.xpack.watcher.condition.script.ScriptConditionFactory;
|
import org.elasticsearch.xpack.watcher.condition.script.ScriptConditionFactory;
|
||||||
import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext;
|
import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext;
|
||||||
import org.elasticsearch.xpack.watcher.support.Script;
|
import org.elasticsearch.xpack.watcher.support.WatcherScript;
|
||||||
import org.elasticsearch.xpack.watcher.watch.Payload;
|
import org.elasticsearch.xpack.watcher.watch.Payload;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
import org.joda.time.DateTimeZone;
|
||||||
|
@ -36,7 +36,7 @@ import java.io.IOException;
|
||||||
|
|
||||||
import static java.util.Collections.singletonMap;
|
import static java.util.Collections.singletonMap;
|
||||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||||
import static org.elasticsearch.messy.tests.MessyTestUtils.getScriptServiceProxy;
|
import static org.elasticsearch.messy.tests.MessyTestUtils.createScriptService;
|
||||||
import static org.elasticsearch.xpack.watcher.support.Exceptions.illegalArgument;
|
import static org.elasticsearch.xpack.watcher.support.Exceptions.illegalArgument;
|
||||||
import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.mockExecutionContext;
|
import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.mockExecutionContext;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
@ -57,18 +57,18 @@ public class ScriptConditionTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testExecute() throws Exception {
|
public void testExecute() throws Exception {
|
||||||
ScriptServiceProxy scriptService = getScriptServiceProxy(tp);
|
ScriptService scriptService = createScriptService(tp);
|
||||||
ExecutableScriptCondition condition = new ExecutableScriptCondition(
|
ExecutableScriptCondition condition = new ExecutableScriptCondition(
|
||||||
new ScriptCondition(Script.inline("ctx.payload.hits.total > 1").build()), logger, scriptService);
|
new ScriptCondition(WatcherScript.inline("ctx.payload.hits.total > 1").build()), logger, scriptService);
|
||||||
SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500L, new ShardSearchFailure[0]);
|
SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500L, new ShardSearchFailure[0]);
|
||||||
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
|
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
|
||||||
assertFalse(condition.execute(ctx).met());
|
assertFalse(condition.execute(ctx).met());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testExecuteMergedParams() throws Exception {
|
public void testExecuteMergedParams() throws Exception {
|
||||||
ScriptServiceProxy scriptService = getScriptServiceProxy(tp);
|
ScriptService scriptService = createScriptService(tp);
|
||||||
Script script = Script.inline("ctx.payload.hits.total > threshold")
|
WatcherScript script = WatcherScript.inline("ctx.payload.hits.total > threshold")
|
||||||
.lang(Script.DEFAULT_LANG).params(singletonMap("threshold", 1)).build();
|
.lang(WatcherScript.DEFAULT_LANG).params(singletonMap("threshold", 1)).build();
|
||||||
ExecutableScriptCondition executable = new ExecutableScriptCondition(new ScriptCondition(script), logger, scriptService);
|
ExecutableScriptCondition executable = new ExecutableScriptCondition(new ScriptCondition(script), logger, scriptService);
|
||||||
SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500L, new ShardSearchFailure[0]);
|
SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500L, new ShardSearchFailure[0]);
|
||||||
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
|
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
|
||||||
|
@ -76,7 +76,7 @@ public class ScriptConditionTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testParserValid() throws Exception {
|
public void testParserValid() throws Exception {
|
||||||
ScriptConditionFactory factory = new ScriptConditionFactory(Settings.builder().build(), getScriptServiceProxy(tp));
|
ScriptConditionFactory factory = new ScriptConditionFactory(Settings.builder().build(), createScriptService(tp));
|
||||||
|
|
||||||
XContentBuilder builder = createConditionContent("ctx.payload.hits.total > 1", null, ScriptType.INLINE);
|
XContentBuilder builder = createConditionContent("ctx.payload.hits.total > 1", null, ScriptType.INLINE);
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ public class ScriptConditionTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testParserInvalid() throws Exception {
|
public void testParserInvalid() throws Exception {
|
||||||
ScriptConditionFactory factory = new ScriptConditionFactory(Settings.builder().build(), getScriptServiceProxy(tp));
|
ScriptConditionFactory factory = new ScriptConditionFactory(Settings.builder().build(), createScriptService(tp));
|
||||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||||
builder.startObject().endObject();
|
builder.startObject().endObject();
|
||||||
XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
|
XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
|
||||||
|
@ -118,7 +118,7 @@ public class ScriptConditionTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testScriptConditionParserBadScript() throws Exception {
|
public void testScriptConditionParserBadScript() throws Exception {
|
||||||
ScriptConditionFactory conditionParser = new ScriptConditionFactory(Settings.builder().build(), getScriptServiceProxy(tp));
|
ScriptConditionFactory conditionParser = new ScriptConditionFactory(Settings.builder().build(), createScriptService(tp));
|
||||||
ScriptType scriptType = randomFrom(ScriptType.values());
|
ScriptType scriptType = randomFrom(ScriptType.values());
|
||||||
String script;
|
String script;
|
||||||
switch (scriptType) {
|
switch (scriptType) {
|
||||||
|
@ -139,7 +139,7 @@ public class ScriptConditionTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testScriptConditionParser_badLang() throws Exception {
|
public void testScriptConditionParser_badLang() throws Exception {
|
||||||
ScriptConditionFactory conditionParser = new ScriptConditionFactory(Settings.builder().build(), getScriptServiceProxy(tp));
|
ScriptConditionFactory conditionParser = new ScriptConditionFactory(Settings.builder().build(), createScriptService(tp));
|
||||||
ScriptType scriptType = ScriptType.INLINE;
|
ScriptType scriptType = ScriptType.INLINE;
|
||||||
String script = "return true";
|
String script = "return true";
|
||||||
XContentBuilder builder = createConditionContent(script, "not_a_valid_lang", scriptType);
|
XContentBuilder builder = createConditionContent(script, "not_a_valid_lang", scriptType);
|
||||||
|
@ -152,9 +152,9 @@ public class ScriptConditionTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testScriptConditionThrowException() throws Exception {
|
public void testScriptConditionThrowException() throws Exception {
|
||||||
ScriptServiceProxy scriptService = getScriptServiceProxy(tp);
|
ScriptService scriptService = createScriptService(tp);
|
||||||
ExecutableScriptCondition condition = new ExecutableScriptCondition(
|
ExecutableScriptCondition condition = new ExecutableScriptCondition(
|
||||||
new ScriptCondition(Script.inline("null.foo").build()), logger, scriptService);
|
new ScriptCondition(WatcherScript.inline("null.foo").build()), logger, scriptService);
|
||||||
SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500L, new ShardSearchFailure[0]);
|
SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500L, new ShardSearchFailure[0]);
|
||||||
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
|
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
|
||||||
ScriptException exception = expectThrows(ScriptException.class, () -> condition.execute(ctx));
|
ScriptException exception = expectThrows(ScriptException.class, () -> condition.execute(ctx));
|
||||||
|
@ -162,9 +162,9 @@ public class ScriptConditionTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testScriptConditionReturnObjectThrowsException() throws Exception {
|
public void testScriptConditionReturnObjectThrowsException() throws Exception {
|
||||||
ScriptServiceProxy scriptService = getScriptServiceProxy(tp);
|
ScriptService scriptService = createScriptService(tp);
|
||||||
ExecutableScriptCondition condition = new ExecutableScriptCondition(
|
ExecutableScriptCondition condition = new ExecutableScriptCondition(
|
||||||
new ScriptCondition(Script.inline("return new Object()").build()), logger, scriptService);
|
new ScriptCondition(WatcherScript.inline("return new Object()").build()), logger, scriptService);
|
||||||
SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500L, new ShardSearchFailure[0]);
|
SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500L, new ShardSearchFailure[0]);
|
||||||
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
|
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
|
||||||
Exception exception = expectThrows(GeneralScriptException.class, () -> condition.execute(ctx));
|
Exception exception = expectThrows(GeneralScriptException.class, () -> condition.execute(ctx));
|
||||||
|
@ -173,9 +173,9 @@ public class ScriptConditionTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testScriptConditionAccessCtx() throws Exception {
|
public void testScriptConditionAccessCtx() throws Exception {
|
||||||
ScriptServiceProxy scriptService = getScriptServiceProxy(tp);
|
ScriptService scriptService = createScriptService(tp);
|
||||||
ExecutableScriptCondition condition = new ExecutableScriptCondition(
|
ExecutableScriptCondition condition = new ExecutableScriptCondition(
|
||||||
new ScriptCondition(Script.inline("ctx.trigger.scheduled_time.getMillis() < new Date().time ").build()),
|
new ScriptCondition(WatcherScript.inline("ctx.trigger.scheduled_time.getMillis() < new Date().time ").build()),
|
||||||
logger, scriptService);
|
logger, scriptService);
|
||||||
SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500L, new ShardSearchFailure[0]);
|
SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500L, new ShardSearchFailure[0]);
|
||||||
WatchExecutionContext ctx = mockExecutionContext("_name", new DateTime(DateTimeZone.UTC), new Payload.XContent(response));
|
WatchExecutionContext ctx = mockExecutionContext("_name", new DateTime(DateTimeZone.UTC), new Payload.XContent(response));
|
||||||
|
|
|
@ -13,7 +13,7 @@ import org.elasticsearch.common.io.Streams;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.plugins.Plugin;
|
import org.elasticsearch.plugins.Plugin;
|
||||||
import org.elasticsearch.script.groovy.GroovyPlugin;
|
import org.elasticsearch.script.groovy.GroovyPlugin;
|
||||||
import org.elasticsearch.xpack.watcher.support.Script;
|
import org.elasticsearch.xpack.watcher.support.WatcherScript;
|
||||||
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
||||||
import org.elasticsearch.xpack.watcher.test.WatcherTestUtils;
|
import org.elasticsearch.xpack.watcher.test.WatcherTestUtils;
|
||||||
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
|
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
|
||||||
|
@ -72,10 +72,10 @@ public class TransformIT extends AbstractWatcherIntegrationTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testScriptTransform() throws Exception {
|
public void testScriptTransform() throws Exception {
|
||||||
final Script script;
|
final WatcherScript script;
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
logger.info("testing script transform with an inline script");
|
logger.info("testing script transform with an inline script");
|
||||||
script = Script.inline("return [key3 : ctx.payload.key1 + ctx.payload.key2]").lang("groovy").build();
|
script = WatcherScript.inline("return [key3 : ctx.payload.key1 + ctx.payload.key2]").lang("groovy").build();
|
||||||
} else if (randomBoolean()) {
|
} else if (randomBoolean()) {
|
||||||
logger.info("testing script transform with an indexed script");
|
logger.info("testing script transform with an indexed script");
|
||||||
client().admin().cluster().preparePutStoredScript()
|
client().admin().cluster().preparePutStoredScript()
|
||||||
|
@ -83,10 +83,10 @@ public class TransformIT extends AbstractWatcherIntegrationTestCase {
|
||||||
.setScriptLang("groovy")
|
.setScriptLang("groovy")
|
||||||
.setSource(new BytesArray("{\"script\" : \"return [key3 : ctx.payload.key1 + ctx.payload.key2]\"}"))
|
.setSource(new BytesArray("{\"script\" : \"return [key3 : ctx.payload.key1 + ctx.payload.key2]\"}"))
|
||||||
.get();
|
.get();
|
||||||
script = Script.indexed("_id").lang("groovy").build();
|
script = WatcherScript.indexed("_id").lang("groovy").build();
|
||||||
} else {
|
} else {
|
||||||
logger.info("testing script transform with a file script");
|
logger.info("testing script transform with a file script");
|
||||||
script = Script.file("my-script").lang("groovy").build();
|
script = WatcherScript.file("my-script").lang("groovy").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
// put a watch that has watch level transform:
|
// put a watch that has watch level transform:
|
||||||
|
@ -182,8 +182,8 @@ public class TransformIT extends AbstractWatcherIntegrationTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testChainTransform() throws Exception {
|
public void testChainTransform() throws Exception {
|
||||||
final Script script1 = Script.inline("return [key3 : ctx.payload.key1 + ctx.payload.key2]").lang("groovy").build();
|
final WatcherScript script1 = WatcherScript.inline("return [key3 : ctx.payload.key1 + ctx.payload.key2]").lang("groovy").build();
|
||||||
final Script script2 = Script.inline("return [key4 : ctx.payload.key3 + 10]").lang("groovy").build();
|
final WatcherScript script2 = WatcherScript.inline("return [key4 : ctx.payload.key3 + 10]").lang("groovy").build();
|
||||||
// put a watch that has watch level transform:
|
// put a watch that has watch level transform:
|
||||||
PutWatchResponse putWatchResponse = watcherClient().preparePutWatch("_id1")
|
PutWatchResponse putWatchResponse = watcherClient().preparePutWatch("_id1")
|
||||||
.setSource(watchBuilder()
|
.setSource(watchBuilder()
|
||||||
|
|
|
@ -28,7 +28,6 @@ import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||||
import org.elasticsearch.search.suggest.Suggesters;
|
import org.elasticsearch.search.suggest.Suggesters;
|
||||||
import org.elasticsearch.test.ESIntegTestCase;
|
import org.elasticsearch.test.ESIntegTestCase;
|
||||||
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
|
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
|
||||||
import org.elasticsearch.xpack.common.ScriptServiceProxy;
|
|
||||||
import org.elasticsearch.xpack.common.text.TextTemplate;
|
import org.elasticsearch.xpack.common.text.TextTemplate;
|
||||||
import org.elasticsearch.xpack.watcher.actions.ActionWrapper;
|
import org.elasticsearch.xpack.watcher.actions.ActionWrapper;
|
||||||
import org.elasticsearch.xpack.watcher.actions.ExecutableActions;
|
import org.elasticsearch.xpack.watcher.actions.ExecutableActions;
|
||||||
|
@ -41,7 +40,7 @@ import org.elasticsearch.xpack.watcher.input.search.SearchInput;
|
||||||
import org.elasticsearch.xpack.watcher.input.search.SearchInputFactory;
|
import org.elasticsearch.xpack.watcher.input.search.SearchInputFactory;
|
||||||
import org.elasticsearch.xpack.watcher.input.simple.ExecutableSimpleInput;
|
import org.elasticsearch.xpack.watcher.input.simple.ExecutableSimpleInput;
|
||||||
import org.elasticsearch.xpack.watcher.input.simple.SimpleInput;
|
import org.elasticsearch.xpack.watcher.input.simple.SimpleInput;
|
||||||
import org.elasticsearch.xpack.watcher.support.Script;
|
import org.elasticsearch.xpack.watcher.support.WatcherScript;
|
||||||
import org.elasticsearch.xpack.watcher.support.init.proxy.WatcherClientProxy;
|
import org.elasticsearch.xpack.watcher.support.init.proxy.WatcherClientProxy;
|
||||||
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateRequest;
|
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateRequest;
|
||||||
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateService;
|
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateService;
|
||||||
|
@ -190,7 +189,7 @@ public class SearchInputIT extends ESIntegTestCase {
|
||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.put("seconds_param", "30s");
|
params.put("seconds_param", "30s");
|
||||||
|
|
||||||
Script template = Script.inline(TEMPLATE_QUERY).lang("mustache").params(params).build();
|
WatcherScript template = WatcherScript.inline(TEMPLATE_QUERY).lang("mustache").params(params).build();
|
||||||
|
|
||||||
SearchRequest request = client().prepareSearch()
|
SearchRequest request = client().prepareSearch()
|
||||||
.setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE)
|
.setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE)
|
||||||
|
@ -224,7 +223,7 @@ public class SearchInputIT extends ESIntegTestCase {
|
||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.put("seconds_param", "30s");
|
params.put("seconds_param", "30s");
|
||||||
|
|
||||||
Script template = Script.indexed("test-template").lang("mustache").params(params).build();
|
WatcherScript template = WatcherScript.indexed("test-template").lang("mustache").params(params).build();
|
||||||
|
|
||||||
jsonBuilder().value(TextTemplate.indexed("test-template").params(params).build()).bytes();
|
jsonBuilder().value(TextTemplate.indexed("test-template").params(params).build()).bytes();
|
||||||
SearchRequest request = client().prepareSearch().setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE)
|
SearchRequest request = client().prepareSearch().setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE)
|
||||||
|
@ -252,7 +251,7 @@ public class SearchInputIT extends ESIntegTestCase {
|
||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.put("seconds_param", "30s");
|
params.put("seconds_param", "30s");
|
||||||
|
|
||||||
Script template = Script.file("test_disk_template").lang("mustache").params(params).build();
|
WatcherScript template = WatcherScript.file("test_disk_template").lang("mustache").params(params).build();
|
||||||
SearchRequest request = client().prepareSearch().setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE)
|
SearchRequest request = client().prepareSearch().setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE)
|
||||||
.setIndices("test-search-index").request();
|
.setIndices("test-search-index").request();
|
||||||
|
|
||||||
|
@ -347,7 +346,8 @@ public class SearchInputIT extends ESIntegTestCase {
|
||||||
timeValueSeconds(5));
|
timeValueSeconds(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
private SearchInput.Result executeSearchInput(SearchRequest request, Script template, WatchExecutionContext ctx) throws IOException {
|
private SearchInput.Result executeSearchInput(SearchRequest request, WatcherScript template,
|
||||||
|
WatchExecutionContext ctx) throws IOException {
|
||||||
createIndex("test-search-index");
|
createIndex("test-search-index");
|
||||||
ensureGreen("test-search-index");
|
ensureGreen("test-search-index");
|
||||||
SearchInput.Builder siBuilder = SearchInput.builder(new WatcherSearchTemplateRequest(request, template));
|
SearchInput.Builder siBuilder = SearchInput.builder(new WatcherSearchTemplateRequest(request, template));
|
||||||
|
@ -362,15 +362,15 @@ public class SearchInputIT extends ESIntegTestCase {
|
||||||
protected WatcherSearchTemplateService watcherSearchTemplateService() {
|
protected WatcherSearchTemplateService watcherSearchTemplateService() {
|
||||||
String master = internalCluster().getMasterName();
|
String master = internalCluster().getMasterName();
|
||||||
return new WatcherSearchTemplateService(internalCluster().clusterService(master).getSettings(),
|
return new WatcherSearchTemplateService(internalCluster().clusterService(master).getSettings(),
|
||||||
ScriptServiceProxy.of(internalCluster().getInstance(ScriptService.class, master)),
|
internalCluster().getInstance(ScriptService.class, master),
|
||||||
internalCluster().getInstance(IndicesQueriesRegistry.class, master),
|
internalCluster().getInstance(IndicesQueriesRegistry.class, master),
|
||||||
internalCluster().getInstance(AggregatorParsers.class, master),
|
internalCluster().getInstance(AggregatorParsers.class, master),
|
||||||
internalCluster().getInstance(Suggesters.class, master)
|
internalCluster().getInstance(Suggesters.class, master)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ScriptServiceProxy scriptService() {
|
protected ScriptService scriptService() {
|
||||||
return ScriptServiceProxy.of(internalCluster().getInstance(ScriptService.class));
|
return internalCluster().getInstance(ScriptService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private XContentSource toXContentSource(SearchInput.Result result) throws IOException {
|
private XContentSource toXContentSource(SearchInput.Result result) throws IOException {
|
||||||
|
@ -387,7 +387,7 @@ public class SearchInputIT extends ESIntegTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ScriptContext.Plugin getCustomScriptContexts() {
|
public ScriptContext.Plugin getCustomScriptContexts() {
|
||||||
return ScriptServiceProxy.INSTANCE;
|
return WatcherScript.CTX_PLUGIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||||
import org.elasticsearch.search.suggest.Suggesters;
|
import org.elasticsearch.search.suggest.Suggesters;
|
||||||
import org.elasticsearch.test.ESIntegTestCase;
|
import org.elasticsearch.test.ESIntegTestCase;
|
||||||
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
|
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
|
||||||
import org.elasticsearch.xpack.common.ScriptServiceProxy;
|
|
||||||
import org.elasticsearch.xpack.common.text.TextTemplate;
|
import org.elasticsearch.xpack.common.text.TextTemplate;
|
||||||
import org.elasticsearch.xpack.watcher.actions.ExecutableActions;
|
import org.elasticsearch.xpack.watcher.actions.ExecutableActions;
|
||||||
import org.elasticsearch.xpack.watcher.condition.always.ExecutableAlwaysCondition;
|
import org.elasticsearch.xpack.watcher.condition.always.ExecutableAlwaysCondition;
|
||||||
|
@ -40,7 +39,7 @@ import org.elasticsearch.xpack.watcher.execution.TriggeredExecutionContext;
|
||||||
import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext;
|
import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext;
|
||||||
import org.elasticsearch.xpack.watcher.input.simple.ExecutableSimpleInput;
|
import org.elasticsearch.xpack.watcher.input.simple.ExecutableSimpleInput;
|
||||||
import org.elasticsearch.xpack.watcher.input.simple.SimpleInput;
|
import org.elasticsearch.xpack.watcher.input.simple.SimpleInput;
|
||||||
import org.elasticsearch.xpack.watcher.support.Script;
|
import org.elasticsearch.xpack.watcher.support.WatcherScript;
|
||||||
import org.elasticsearch.xpack.watcher.support.init.proxy.WatcherClientProxy;
|
import org.elasticsearch.xpack.watcher.support.init.proxy.WatcherClientProxy;
|
||||||
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateRequest;
|
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateRequest;
|
||||||
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateService;
|
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateService;
|
||||||
|
@ -348,7 +347,7 @@ public class SearchTransformIT extends ESIntegTestCase {
|
||||||
}
|
}
|
||||||
if (templateName != null) {
|
if (templateName != null) {
|
||||||
assertThat(executable.transform().getRequest().getTemplate(),
|
assertThat(executable.transform().getRequest().getTemplate(),
|
||||||
equalTo(Script.file("template1").build()));
|
equalTo(WatcherScript.file("template1").build()));
|
||||||
}
|
}
|
||||||
SearchSourceBuilder source = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
|
SearchSourceBuilder source = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
|
||||||
assertThat(executable.transform().getRequest().getRequest().source(), equalTo(source));
|
assertThat(executable.transform().getRequest().getRequest().source(), equalTo(source));
|
||||||
|
@ -381,7 +380,7 @@ public class SearchTransformIT extends ESIntegTestCase {
|
||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.put("seconds_param", "30s");
|
params.put("seconds_param", "30s");
|
||||||
|
|
||||||
Script template = Script.inline(templateQuery).lang("mustache").params(params).build();
|
WatcherScript template = WatcherScript.inline(templateQuery).lang("mustache").params(params).build();
|
||||||
SearchRequest request = client().prepareSearch().setSearchType(ExecutableSearchTransform.DEFAULT_SEARCH_TYPE)
|
SearchRequest request = client().prepareSearch().setSearchType(ExecutableSearchTransform.DEFAULT_SEARCH_TYPE)
|
||||||
.setIndices("test-search-index").request();
|
.setIndices("test-search-index").request();
|
||||||
|
|
||||||
|
@ -415,7 +414,7 @@ public class SearchTransformIT extends ESIntegTestCase {
|
||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.put("seconds_param", "30s");
|
params.put("seconds_param", "30s");
|
||||||
|
|
||||||
Script template = Script.indexed("test-script").lang("mustache").params(params).build();
|
WatcherScript template = WatcherScript.indexed("test-script").lang("mustache").params(params).build();
|
||||||
|
|
||||||
SearchRequest request = client()
|
SearchRequest request = client()
|
||||||
.prepareSearch()
|
.prepareSearch()
|
||||||
|
@ -441,7 +440,7 @@ public class SearchTransformIT extends ESIntegTestCase {
|
||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.put("seconds_param", "30s");
|
params.put("seconds_param", "30s");
|
||||||
|
|
||||||
Script template = Script.file("test_disk_template").lang("mustache").params(params).build();
|
WatcherScript template = WatcherScript.file("test_disk_template").lang("mustache").params(params).build();
|
||||||
SearchRequest request = client().prepareSearch().setSearchType(ExecutableSearchTransform.DEFAULT_SEARCH_TYPE)
|
SearchRequest request = client().prepareSearch().setSearchType(ExecutableSearchTransform.DEFAULT_SEARCH_TYPE)
|
||||||
.setIndices("test-search-index").request();
|
.setIndices("test-search-index").request();
|
||||||
|
|
||||||
|
@ -504,7 +503,7 @@ public class SearchTransformIT extends ESIntegTestCase {
|
||||||
timeValueSeconds(5));
|
timeValueSeconds(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
private SearchTransform.Result executeSearchTransform(SearchRequest request, Script template, WatchExecutionContext ctx)
|
private SearchTransform.Result executeSearchTransform(SearchRequest request, WatcherScript template, WatchExecutionContext ctx)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
createIndex("test-search-index");
|
createIndex("test-search-index");
|
||||||
ensureGreen("test-search-index");
|
ensureGreen("test-search-index");
|
||||||
|
@ -519,15 +518,15 @@ public class SearchTransformIT extends ESIntegTestCase {
|
||||||
protected WatcherSearchTemplateService watcherSearchTemplateService() {
|
protected WatcherSearchTemplateService watcherSearchTemplateService() {
|
||||||
String master = internalCluster().getMasterName();
|
String master = internalCluster().getMasterName();
|
||||||
return new WatcherSearchTemplateService(internalCluster().clusterService(master).getSettings(),
|
return new WatcherSearchTemplateService(internalCluster().clusterService(master).getSettings(),
|
||||||
ScriptServiceProxy.of(internalCluster().getInstance(ScriptService.class, master)),
|
internalCluster().getInstance(ScriptService.class, master),
|
||||||
internalCluster().getInstance(IndicesQueriesRegistry.class, master),
|
internalCluster().getInstance(IndicesQueriesRegistry.class, master),
|
||||||
internalCluster().getInstance(AggregatorParsers.class, master),
|
internalCluster().getInstance(AggregatorParsers.class, master),
|
||||||
internalCluster().getInstance(Suggesters.class, master)
|
internalCluster().getInstance(Suggesters.class, master)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ScriptServiceProxy scriptService() {
|
protected ScriptService scriptService() {
|
||||||
return ScriptServiceProxy.of(internalCluster().getInstance(ScriptService.class));
|
return internalCluster().getInstance(ScriptService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, Object> doc(String date, String value) {
|
private static Map<String, Object> doc(String date, String value) {
|
||||||
|
@ -551,7 +550,7 @@ public class SearchTransformIT extends ESIntegTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ScriptContext.Plugin getCustomScriptContexts() {
|
public ScriptContext.Plugin getCustomScriptContexts() {
|
||||||
return ScriptServiceProxy.INSTANCE;
|
return WatcherScript.CTX_PLUGIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,13 @@ package org.elasticsearch.messy.tests;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchSecurityException;
|
import org.elasticsearch.ElasticsearchSecurityException;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.action.search.SearchPhaseExecutionException;
|
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.index.query.QueryBuilders;
|
import org.elasticsearch.index.query.QueryBuilders;
|
||||||
import org.elasticsearch.indices.TermsLookup;
|
import org.elasticsearch.indices.TermsLookup;
|
||||||
import org.elasticsearch.plugins.Plugin;
|
import org.elasticsearch.plugins.Plugin;
|
||||||
import org.elasticsearch.script.Template;
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.script.mustache.MustachePlugin;
|
import org.elasticsearch.script.mustache.MustachePlugin;
|
||||||
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
import org.elasticsearch.script.mustache.TemplateQueryBuilder;
|
||||||
import org.elasticsearch.test.SecurityIntegTestCase;
|
import org.elasticsearch.test.SecurityIntegTestCase;
|
||||||
import org.elasticsearch.test.SecuritySettingsSource;
|
import org.elasticsearch.test.SecuritySettingsSource;
|
||||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||||
|
@ -25,7 +24,6 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import static java.util.Collections.singletonMap;
|
import static java.util.Collections.singletonMap;
|
||||||
import static org.elasticsearch.script.ScriptService.ScriptType.INLINE;
|
|
||||||
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
@ -109,7 +107,7 @@ public class SecurityCachePermissionIT extends SecurityIntegTestCase {
|
||||||
|
|
||||||
//Template template = new Template(source, INLINE, MustacheScriptEngineService.NAME, null, singletonMap("name", "token"));
|
//Template template = new Template(source, INLINE, MustacheScriptEngineService.NAME, null, singletonMap("name", "token"));
|
||||||
SearchResponse response = client().prepareSearch("data").setTypes("a")
|
SearchResponse response = client().prepareSearch("data").setTypes("a")
|
||||||
.setQuery(QueryBuilders.templateQuery(source, singletonMap("name", "token")))
|
.setQuery(new TemplateQueryBuilder(source, ScriptService.ScriptType.INLINE, singletonMap("name", "token")))
|
||||||
.execute().actionGet();
|
.execute().actionGet();
|
||||||
assertThat(response.isTimedOut(), is(false));
|
assertThat(response.isTimedOut(), is(false));
|
||||||
assertThat(response.getHits().hits().length, is(1));
|
assertThat(response.getHits().hits().length, is(1));
|
||||||
|
@ -119,7 +117,7 @@ public class SecurityCachePermissionIT extends SecurityIntegTestCase {
|
||||||
.filterWithHeader(singletonMap("Authorization", basicAuthHeaderValue(READ_ONE_IDX_USER,
|
.filterWithHeader(singletonMap("Authorization", basicAuthHeaderValue(READ_ONE_IDX_USER,
|
||||||
new SecuredString("changeme".toCharArray()))))
|
new SecuredString("changeme".toCharArray()))))
|
||||||
.prepareSearch("data").setTypes("a")
|
.prepareSearch("data").setTypes("a")
|
||||||
.setQuery(QueryBuilders.templateQuery(source, singletonMap("name", "token")))
|
.setQuery(new TemplateQueryBuilder(source, ScriptService.ScriptType.INLINE, singletonMap("name", "token")))
|
||||||
.execute().actionGet());
|
.execute().actionGet());
|
||||||
assertThat(e.toString(), containsString("ElasticsearchSecurityException[action"));
|
assertThat(e.toString(), containsString("ElasticsearchSecurityException[action"));
|
||||||
assertThat(e.toString(), containsString("unauthorized"));
|
assertThat(e.toString(), containsString("unauthorized"));
|
||||||
|
|
|
@ -158,7 +158,7 @@ public class WatchAckIT extends AbstractWatcherIntegrationTestCase {
|
||||||
assertThat(parsedWatch.status().actionStatus("_a2").ackStatus().state(),
|
assertThat(parsedWatch.status().actionStatus("_a2").ackStatus().state(),
|
||||||
is(ActionStatus.AckStatus.State.AWAITS_SUCCESSFUL_EXECUTION));
|
is(ActionStatus.AckStatus.State.AWAITS_SUCCESSFUL_EXECUTION));
|
||||||
|
|
||||||
long throttledCount = docCount(HistoryStore.INDEX_PREFIX + "*", null,
|
long throttledCount = docCount(HistoryStore.INDEX_PREFIX_WITH_TEMPLATE + "*", null,
|
||||||
matchQuery(WatchRecord.Field.STATE.getPreferredName(), ExecutionState.THROTTLED.id()));
|
matchQuery(WatchRecord.Field.STATE.getPreferredName(), ExecutionState.THROTTLED.id()));
|
||||||
assertThat(throttledCount, greaterThan(0L));
|
assertThat(throttledCount, greaterThan(0L));
|
||||||
}
|
}
|
||||||
|
@ -240,7 +240,7 @@ public class WatchAckIT extends AbstractWatcherIntegrationTestCase {
|
||||||
assertThat(parsedWatch.status().actionStatus("_a2").ackStatus().state(),
|
assertThat(parsedWatch.status().actionStatus("_a2").ackStatus().state(),
|
||||||
is(ActionStatus.AckStatus.State.AWAITS_SUCCESSFUL_EXECUTION));
|
is(ActionStatus.AckStatus.State.AWAITS_SUCCESSFUL_EXECUTION));
|
||||||
|
|
||||||
long throttledCount = docCount(HistoryStore.INDEX_PREFIX + "*", null,
|
long throttledCount = docCount(HistoryStore.INDEX_PREFIX_WITH_TEMPLATE + "*", null,
|
||||||
matchQuery(WatchRecord.Field.STATE.getPreferredName(), ExecutionState.THROTTLED.id()));
|
matchQuery(WatchRecord.Field.STATE.getPreferredName(), ExecutionState.THROTTLED.id()));
|
||||||
assertThat(throttledCount, greaterThan(0L));
|
assertThat(throttledCount, greaterThan(0L));
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ dependencies {
|
||||||
integTest {
|
integTest {
|
||||||
cluster {
|
cluster {
|
||||||
setting 'script.inline', 'true'
|
setting 'script.inline', 'true'
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
extraConfigFile 'x-pack/roles.yml', 'roles.yml'
|
extraConfigFile 'x-pack/roles.yml', 'roles.yml'
|
||||||
[
|
[
|
||||||
test_admin: 'superuser',
|
test_admin: 'superuser',
|
||||||
|
|
|
@ -7,28 +7,29 @@ package org.elasticsearch.xpack.security;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
import com.carrotsearch.randomizedtesting.annotations.Name;
|
||||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||||
|
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
|
||||||
import org.elasticsearch.test.rest.RestTestCandidate;
|
|
||||||
import org.elasticsearch.test.rest.parser.RestTestParseException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||||
|
|
||||||
public class RestIT extends ESRestTestCase {
|
public class ReindexWithSecurityClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
||||||
private static final String USER = "test_admin";
|
private static final String USER = "test_admin";
|
||||||
private static final String PASS = "changeme";
|
private static final String PASS = "changeme";
|
||||||
|
|
||||||
public RestIT(@Name("yaml") RestTestCandidate testCandidate) {
|
public ReindexWithSecurityClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
||||||
super(testCandidate);
|
super(testCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersFactory
|
@ParametersFactory
|
||||||
public static Iterable<Object[]> parameters() throws IOException, RestTestParseException {
|
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||||
return ESRestTestCase.createParameters(0, 1);
|
return ESClientYamlSuiteTestCase.createParameters(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -14,7 +14,7 @@ project.sourceSets.test.output.dir(outputDir, builtBy: copyXPackPluginProps)
|
||||||
|
|
||||||
integTest {
|
integTest {
|
||||||
cluster {
|
cluster {
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
setupCommand 'setupDummyUser',
|
setupCommand 'setupDummyUser',
|
||||||
'bin/x-pack/users', 'useradd', 'test_user', '-p', 'changeme', '-r', 'superuser'
|
'bin/x-pack/users', 'useradd', 'test_user', '-p', 'changeme', '-r', 'superuser'
|
||||||
setupCommand 'setupTransportClientUser',
|
setupCommand 'setupTransportClientUser',
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.elasticsearch.client.transport.TransportClient;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.transport.TransportAddress;
|
import org.elasticsearch.common.transport.TransportAddress;
|
||||||
import org.elasticsearch.plugins.Plugin;
|
import org.elasticsearch.plugins.Plugin;
|
||||||
|
import org.elasticsearch.transport.MockTransportClient;
|
||||||
import org.elasticsearch.xpack.security.Security;
|
import org.elasticsearch.xpack.security.Security;
|
||||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||||
import org.elasticsearch.test.ESIntegTestCase;
|
import org.elasticsearch.test.ESIntegTestCase;
|
||||||
|
@ -115,6 +116,6 @@ public class SecurityTransportClientIT extends ESIntegTestCase {
|
||||||
.put("cluster.name", clusterName)
|
.put("cluster.name", clusterName)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return TransportClient.builder().settings(settings).addPlugin(XPackPlugin.class).build().addTransportAddress(publishAddress);
|
return new MockTransportClient(settings, XPackPlugin.class).addTransportAddress(publishAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ task buildZip(type:Zip, dependsOn: [jar]) {
|
||||||
|
|
||||||
task integTest(type: org.elasticsearch.gradle.test.RestIntegTestTask, dependsOn: buildZip) {
|
task integTest(type: org.elasticsearch.gradle.test.RestIntegTestTask, dependsOn: buildZip) {
|
||||||
cluster {
|
cluster {
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
setting 'xpack.security.authc.realms.custom.order', '0'
|
setting 'xpack.security.authc.realms.custom.order', '0'
|
||||||
setting 'xpack.security.authc.realms.custom.type', 'custom'
|
setting 'xpack.security.authc.realms.custom.type', 'custom'
|
||||||
setting 'xpack.security.authc.realms.esusers.order', '1'
|
setting 'xpack.security.authc.realms.esusers.order', '1'
|
||||||
|
|
|
@ -7,14 +7,27 @@ package org.elasticsearch.example;
|
||||||
|
|
||||||
import org.elasticsearch.example.realm.CustomAuthenticationFailureHandler;
|
import org.elasticsearch.example.realm.CustomAuthenticationFailureHandler;
|
||||||
import org.elasticsearch.example.realm.CustomRealm;
|
import org.elasticsearch.example.realm.CustomRealm;
|
||||||
import org.elasticsearch.example.realm.CustomRealmFactory;
|
import org.elasticsearch.xpack.security.authc.AuthenticationFailureHandler;
|
||||||
import org.elasticsearch.xpack.security.authc.AuthenticationModule;
|
|
||||||
import org.elasticsearch.xpack.extensions.XPackExtension;
|
import org.elasticsearch.xpack.extensions.XPackExtension;
|
||||||
|
import org.elasticsearch.xpack.security.authc.Realm;
|
||||||
|
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class ExampleRealmExtension extends XPackExtension {
|
public class ExampleRealmExtension extends XPackExtension {
|
||||||
|
|
||||||
|
static {
|
||||||
|
// check that the extension's policy works.
|
||||||
|
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
|
||||||
|
System.getSecurityManager().checkPrintJobAccess();
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String name() {
|
public String name() {
|
||||||
return "custom realm example";
|
return "custom realm example";
|
||||||
|
@ -25,13 +38,18 @@ public class ExampleRealmExtension extends XPackExtension {
|
||||||
return "a very basic implementation of a custom realm to validate it works";
|
return "a very basic implementation of a custom realm to validate it works";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onModule(AuthenticationModule authenticationModule) {
|
@Override
|
||||||
authenticationModule.addCustomRealm(CustomRealm.TYPE, CustomRealmFactory.class);
|
public Map<String, Realm.Factory> getRealms() {
|
||||||
authenticationModule.setAuthenticationFailureHandler(CustomAuthenticationFailureHandler.class);
|
return Collections.singletonMap(CustomRealm.TYPE, CustomRealm::new);
|
||||||
// check that the extension's policy works.
|
}
|
||||||
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
|
|
||||||
System.getSecurityManager().checkPrintJobAccess();
|
@Override
|
||||||
return null;
|
public AuthenticationFailureHandler getAuthenticationFailureHandler() {
|
||||||
});
|
return new CustomAuthenticationFailureHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> getRestHeaders() {
|
||||||
|
return Arrays.asList(CustomRealm.USER_HEADER, CustomRealm.PW_HEADER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,12 +13,12 @@ import org.elasticsearch.xpack.security.authc.RealmConfig;
|
||||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||||
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
|
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
|
||||||
|
|
||||||
public class CustomRealm extends Realm<UsernamePasswordToken> {
|
public class CustomRealm extends Realm {
|
||||||
|
|
||||||
public static final String TYPE = "custom";
|
public static final String TYPE = "custom";
|
||||||
|
|
||||||
static final String USER_HEADER = "User";
|
public static final String USER_HEADER = "User";
|
||||||
static final String PW_HEADER = "Password";
|
public static final String PW_HEADER = "Password";
|
||||||
|
|
||||||
static final String KNOWN_USER = "custom_user";
|
static final String KNOWN_USER = "custom_user";
|
||||||
static final String KNOWN_PW = "changeme";
|
static final String KNOWN_PW = "changeme";
|
||||||
|
@ -46,7 +46,8 @@ public class CustomRealm extends Realm<UsernamePasswordToken> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User authenticate(UsernamePasswordToken token) {
|
public User authenticate(AuthenticationToken authToken) {
|
||||||
|
UsernamePasswordToken token = (UsernamePasswordToken)authToken;
|
||||||
final String actualUser = token.principal();
|
final String actualUser = token.principal();
|
||||||
if (KNOWN_USER.equals(actualUser) && SecuredString.constantTimeEquals(token.credentials(), KNOWN_PW)) {
|
if (KNOWN_USER.equals(actualUser) && SecuredString.constantTimeEquals(token.credentials(), KNOWN_PW)) {
|
||||||
return new User(actualUser, ROLES);
|
return new User(actualUser, ROLES);
|
||||||
|
|
|
@ -1,30 +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.example.realm;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.rest.RestController;
|
|
||||||
import org.elasticsearch.xpack.security.authc.Realm;
|
|
||||||
import org.elasticsearch.xpack.security.authc.RealmConfig;
|
|
||||||
|
|
||||||
public class CustomRealmFactory extends Realm.Factory<CustomRealm> {
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public CustomRealmFactory(RestController controller) {
|
|
||||||
super(CustomRealm.TYPE, false);
|
|
||||||
controller.registerRelevantHeaders(CustomRealm.USER_HEADER, CustomRealm.PW_HEADER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CustomRealm create(RealmConfig config) {
|
|
||||||
return new CustomRealm(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CustomRealm createDefault(String name) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -20,7 +20,9 @@ import org.elasticsearch.env.Environment;
|
||||||
import org.elasticsearch.plugins.Plugin;
|
import org.elasticsearch.plugins.Plugin;
|
||||||
import org.elasticsearch.test.ESIntegTestCase;
|
import org.elasticsearch.test.ESIntegTestCase;
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
import org.elasticsearch.xpack.XPackPlugin;
|
||||||
|
import org.elasticsearch.xpack.XPackTransportClient;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -58,11 +60,10 @@ public class CustomRealmIT extends ESIntegTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testHttpAuthentication() throws Exception {
|
public void testHttpAuthentication() throws Exception {
|
||||||
try (Response response = getRestClient().performRequest("GET", "/",
|
Response response = getRestClient().performRequest("GET", "/",
|
||||||
new BasicHeader(CustomRealm.USER_HEADER, CustomRealm.KNOWN_USER),
|
new BasicHeader(CustomRealm.USER_HEADER, CustomRealm.KNOWN_USER),
|
||||||
new BasicHeader(CustomRealm.PW_HEADER, CustomRealm.KNOWN_PW))) {
|
new BasicHeader(CustomRealm.PW_HEADER, CustomRealm.KNOWN_PW));
|
||||||
assertThat(response.getStatusLine().getStatusCode(), is(200));
|
assertThat(response.getStatusLine().getStatusCode(), is(200));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testTransportClient() throws Exception {
|
public void testTransportClient() throws Exception {
|
||||||
|
@ -78,7 +79,7 @@ public class CustomRealmIT extends ESIntegTestCase {
|
||||||
.put(ThreadContext.PREFIX + "." + CustomRealm.USER_HEADER, CustomRealm.KNOWN_USER)
|
.put(ThreadContext.PREFIX + "." + CustomRealm.USER_HEADER, CustomRealm.KNOWN_USER)
|
||||||
.put(ThreadContext.PREFIX + "." + CustomRealm.PW_HEADER, CustomRealm.KNOWN_PW)
|
.put(ThreadContext.PREFIX + "." + CustomRealm.PW_HEADER, CustomRealm.KNOWN_PW)
|
||||||
.build();
|
.build();
|
||||||
try (TransportClient client = TransportClient.builder().settings(settings).addPlugin(XPackPlugin.class).build()) {
|
try (TransportClient client = new XPackTransportClient(settings)) {
|
||||||
client.addTransportAddress(publishAddress);
|
client.addTransportAddress(publishAddress);
|
||||||
ClusterHealthResponse response = client.admin().cluster().prepareHealth().execute().actionGet();
|
ClusterHealthResponse response = client.admin().cluster().prepareHealth().execute().actionGet();
|
||||||
assertThat(response.isTimedOut(), is(false));
|
assertThat(response.isTimedOut(), is(false));
|
||||||
|
@ -98,7 +99,7 @@ public class CustomRealmIT extends ESIntegTestCase {
|
||||||
.put(ThreadContext.PREFIX + "." + CustomRealm.USER_HEADER, CustomRealm.KNOWN_USER + randomAsciiOfLength(1))
|
.put(ThreadContext.PREFIX + "." + CustomRealm.USER_HEADER, CustomRealm.KNOWN_USER + randomAsciiOfLength(1))
|
||||||
.put(ThreadContext.PREFIX + "." + CustomRealm.PW_HEADER, CustomRealm.KNOWN_PW)
|
.put(ThreadContext.PREFIX + "." + CustomRealm.PW_HEADER, CustomRealm.KNOWN_PW)
|
||||||
.build();
|
.build();
|
||||||
try (TransportClient client = TransportClient.builder().addPlugin(XPackPlugin.class).settings(settings).build()) {
|
try (TransportClient client = new XPackTransportClient(settings)) {
|
||||||
client.addTransportAddress(publishAddress);
|
client.addTransportAddress(publishAddress);
|
||||||
client.admin().cluster().prepareHealth().execute().actionGet();
|
client.admin().cluster().prepareHealth().execute().actionGet();
|
||||||
fail("authentication failure should have resulted in a NoNodesAvailableException");
|
fail("authentication failure should have resulted in a NoNodesAvailableException");
|
||||||
|
|
|
@ -7,7 +7,7 @@ dependencies {
|
||||||
integTest {
|
integTest {
|
||||||
cluster {
|
cluster {
|
||||||
setting 'script.inline', 'true'
|
setting 'script.inline', 'true'
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
extraConfigFile 'x-pack/roles.yml', 'roles.yml'
|
extraConfigFile 'x-pack/roles.yml', 'roles.yml'
|
||||||
[
|
[
|
||||||
test_admin: 'superuser',
|
test_admin: 'superuser',
|
||||||
|
|
|
@ -118,6 +118,13 @@ public class MigrateToolIT extends MigrateToolTestCase {
|
||||||
String token = basicAuthHeaderValue("bob", new SecuredString("changeme".toCharArray()));
|
String token = basicAuthHeaderValue("bob", new SecuredString("changeme".toCharArray()));
|
||||||
// Create "index1" index and try to search from it as "bob"
|
// Create "index1" index and try to search from it as "bob"
|
||||||
client.filterWithHeader(Collections.singletonMap("Authorization", token)).admin().indices().prepareCreate("index1").get();
|
client.filterWithHeader(Collections.singletonMap("Authorization", token)).admin().indices().prepareCreate("index1").get();
|
||||||
|
// Wait for the index to be ready so it doesn't fail if no shards are initialized
|
||||||
|
client.admin().cluster().health(Requests.clusterHealthRequest("index1")
|
||||||
|
.timeout(TimeValue.timeValueSeconds(30))
|
||||||
|
.waitForYellowStatus()
|
||||||
|
.waitForEvents(Priority.LANGUID)
|
||||||
|
.waitForRelocatingShards(0))
|
||||||
|
.actionGet();
|
||||||
SearchResponse searchResp = client.filterWithHeader(Collections.singletonMap("Authorization", token)).prepareSearch("index1").get();
|
SearchResponse searchResp = client.filterWithHeader(Collections.singletonMap("Authorization", token)).prepareSearch("index1").get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,8 @@ import org.elasticsearch.common.logging.ESLoggerFactory;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
||||||
import org.elasticsearch.common.transport.TransportAddress;
|
import org.elasticsearch.common.transport.TransportAddress;
|
||||||
import org.elasticsearch.node.internal.InternalSettingsPreparer;
|
import org.elasticsearch.test.ESIntegTestCase;
|
||||||
import org.elasticsearch.xpack.security.Security;
|
import org.elasticsearch.xpack.XPackTransportClient;
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -25,10 +24,8 @@ import org.junit.BeforeClass;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import static com.carrotsearch.randomizedtesting.RandomizedTest.randomAsciiOfLength;
|
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,6 +42,7 @@ import static org.hamcrest.Matchers.notNullValue;
|
||||||
* your test.
|
* your test.
|
||||||
*/
|
*/
|
||||||
@LuceneTestCase.SuppressSysoutChecks(bugUrl = "we log a lot on purpose")
|
@LuceneTestCase.SuppressSysoutChecks(bugUrl = "we log a lot on purpose")
|
||||||
|
@ESIntegTestCase.SuppressLocalMode
|
||||||
public abstract class MigrateToolTestCase extends LuceneTestCase {
|
public abstract class MigrateToolTestCase extends LuceneTestCase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,13 +75,9 @@ public abstract class MigrateToolTestCase extends LuceneTestCase {
|
||||||
.put("client.transport.ignore_cluster_name", true)
|
.put("client.transport.ignore_cluster_name", true)
|
||||||
.put("path.home", tempDir)
|
.put("path.home", tempDir)
|
||||||
.put(Security.USER_SETTING.getKey(), "transport_user:changeme")
|
.put(Security.USER_SETTING.getKey(), "transport_user:changeme")
|
||||||
.put("node.mode", "network") // we require network here!
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
TransportClient.Builder transportClientBuilder = TransportClient.builder()
|
TransportClient client = new XPackTransportClient(clientSettings).addTransportAddresses(transportAddresses);
|
||||||
.addPlugin(XPackPlugin.class)
|
|
||||||
.settings(clientSettings);
|
|
||||||
TransportClient client = transportClientBuilder.build().addTransportAddresses(transportAddresses);
|
|
||||||
|
|
||||||
logger.info("--> Elasticsearch Java TransportClient started");
|
logger.info("--> Elasticsearch Java TransportClient started");
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ integTest {
|
||||||
dependsOn copyGraphRestTests
|
dependsOn copyGraphRestTests
|
||||||
|
|
||||||
cluster {
|
cluster {
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
extraConfigFile 'x-pack/roles.yml', 'roles.yml'
|
extraConfigFile 'x-pack/roles.yml', 'roles.yml'
|
||||||
setupCommand 'setupTestAdminUser',
|
setupCommand 'setupTestAdminUser',
|
||||||
'bin/x-pack/users', 'useradd', 'test_admin', '-p', 'changeme', '-r', 'superuser'
|
'bin/x-pack/users', 'useradd', 'test_admin', '-p', 'changeme', '-r', 'superuser'
|
||||||
|
|
|
@ -7,31 +7,31 @@ package org.elasticsearch.smoketest;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
import com.carrotsearch.randomizedtesting.annotations.Name;
|
||||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||||
|
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
|
||||||
import org.elasticsearch.test.rest.RestTestCandidate;
|
|
||||||
import org.elasticsearch.test.rest.parser.RestTestParseException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||||
|
|
||||||
|
|
||||||
public class GraphWithSecurityIT extends ESRestTestCase {
|
public class GraphWithSecurityIT extends ESClientYamlSuiteTestCase {
|
||||||
|
|
||||||
private static final String TEST_ADMIN_USERNAME = "test_admin";
|
private static final String TEST_ADMIN_USERNAME = "test_admin";
|
||||||
private static final String TEST_ADMIN_PASSWORD = "changeme";
|
private static final String TEST_ADMIN_PASSWORD = "changeme";
|
||||||
|
|
||||||
public GraphWithSecurityIT(@Name("yaml") RestTestCandidate testCandidate) {
|
public GraphWithSecurityIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
||||||
super(testCandidate);
|
super(testCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersFactory
|
@ParametersFactory
|
||||||
public static Iterable<Object[]> parameters() throws IOException, RestTestParseException {
|
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||||
return ESRestTestCase.createParameters(0, 1);
|
return ESClientYamlSuiteTestCase.createParameters(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String[] getCredentials() {
|
protected String[] getCredentials() {
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
package org.elasticsearch.smoketest;
|
package org.elasticsearch.smoketest;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
import com.carrotsearch.randomizedtesting.annotations.Name;
|
||||||
import org.elasticsearch.test.rest.RestTestCandidate;
|
|
||||||
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -14,14 +15,14 @@ import static org.hamcrest.Matchers.containsString;
|
||||||
|
|
||||||
public class GraphWithSecurityInsufficientRoleIT extends GraphWithSecurityIT {
|
public class GraphWithSecurityInsufficientRoleIT extends GraphWithSecurityIT {
|
||||||
|
|
||||||
public GraphWithSecurityInsufficientRoleIT(@Name("yaml") RestTestCandidate testCandidate) {
|
public GraphWithSecurityInsufficientRoleIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
||||||
super(testCandidate);
|
super(testCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void test() throws IOException {
|
public void test() throws IOException {
|
||||||
try {
|
try {
|
||||||
super.test();
|
super.test();
|
||||||
fail();
|
fail("should have failed because of missing role");
|
||||||
} catch(AssertionError ae) {
|
} catch(AssertionError ae) {
|
||||||
assertThat(ae.getMessage(), containsString("action [indices:data/read/xpack/graph/explore"));
|
assertThat(ae.getMessage(), containsString("action [indices:data/read/xpack/graph/explore"));
|
||||||
assertThat(ae.getMessage(), containsString("returned [403 Forbidden]"));
|
assertThat(ae.getMessage(), containsString("returned [403 Forbidden]"));
|
||||||
|
|
|
@ -17,7 +17,7 @@ subprojects {
|
||||||
|
|
||||||
cluster {
|
cluster {
|
||||||
systemProperty 'es.logger.level', 'TRACE'
|
systemProperty 'es.logger.level', 'TRACE'
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
setting 'xpack.monitoring.collection.interval', '3s'
|
setting 'xpack.monitoring.collection.interval', '3s'
|
||||||
extraConfigFile 'x-pack/roles.yml', '../roles.yml'
|
extraConfigFile 'x-pack/roles.yml', '../roles.yml'
|
||||||
setupCommand 'setupTestAdminUser',
|
setupCommand 'setupTestAdminUser',
|
||||||
|
|
|
@ -7,27 +7,28 @@ package org.elasticsearch.smoketest;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
import com.carrotsearch.randomizedtesting.annotations.Name;
|
||||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||||
|
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
|
||||||
import org.elasticsearch.test.rest.RestTestCandidate;
|
|
||||||
import org.elasticsearch.test.rest.parser.RestTestParseException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
|
||||||
public class MonitoringWithSecurityInsufficientRoleIT extends ESRestTestCase {
|
public class SmokeTestMonitoringWithSecurityClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
||||||
|
|
||||||
public MonitoringWithSecurityInsufficientRoleIT(@Name("yaml") RestTestCandidate testCandidate) {
|
public SmokeTestMonitoringWithSecurityClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
||||||
super(testCandidate);
|
super(testCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersFactory
|
@ParametersFactory
|
||||||
public static Iterable<Object[]> parameters() throws IOException, RestTestParseException {
|
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||||
return ESRestTestCase.createParameters(0, 1);
|
return ESClientYamlSuiteTestCase.createParameters(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -7,26 +7,27 @@ package org.elasticsearch.smoketest;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
import com.carrotsearch.randomizedtesting.annotations.Name;
|
||||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||||
|
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
|
||||||
import org.elasticsearch.test.rest.RestTestCandidate;
|
|
||||||
import org.elasticsearch.test.rest.parser.RestTestParseException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||||
|
|
||||||
public class MonitoringWithSecurityIT extends ESRestTestCase {
|
public class SmokeTestMonitoringWithSecurityClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
||||||
|
|
||||||
public MonitoringWithSecurityIT(@Name("yaml") RestTestCandidate testCandidate) {
|
public SmokeTestMonitoringWithSecurityClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
||||||
super(testCandidate);
|
super(testCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersFactory
|
@ParametersFactory
|
||||||
public static Iterable<Object[]> parameters() throws IOException, RestTestParseException {
|
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||||
return ESRestTestCase.createParameters(0, 1);
|
return ESClientYamlSuiteTestCase.createParameters(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -147,7 +147,7 @@ processTestResources.dependsOn(
|
||||||
ext.pluginsCount = 1 // we install xpack explicitly
|
ext.pluginsCount = 1 // we install xpack explicitly
|
||||||
project.rootProject.subprojects.findAll { it.path.startsWith(':plugins:') }.each { subproj ->
|
project.rootProject.subprojects.findAll { it.path.startsWith(':plugins:') }.each { subproj ->
|
||||||
// need to get a non-decorated project object, so must re-lookup the project by path
|
// need to get a non-decorated project object, so must re-lookup the project by path
|
||||||
integTest.cluster.plugin(subproj.name, project(subproj.path))
|
integTest.cluster.plugin(subproj.path)
|
||||||
pluginsCount += 1
|
pluginsCount += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ integTest {
|
||||||
setting 'xpack.security.ssl.keystore.path', nodeKeystore.name
|
setting 'xpack.security.ssl.keystore.path', nodeKeystore.name
|
||||||
setting 'xpack.security.ssl.keystore.password', 'keypass'
|
setting 'xpack.security.ssl.keystore.password', 'keypass'
|
||||||
|
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
|
|
||||||
// copy keystores into config/
|
// copy keystores into config/
|
||||||
extraConfigFile nodeKeystore.name, nodeKeystore
|
extraConfigFile nodeKeystore.name, nodeKeystore
|
||||||
|
|
|
@ -9,11 +9,12 @@ import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.action.admin.cluster.node.info.NodeInfo;
|
import org.elasticsearch.action.admin.cluster.node.info.NodeInfo;
|
||||||
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesResponse;
|
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesResponse;
|
||||||
import org.elasticsearch.common.io.PathUtils;
|
import org.elasticsearch.common.io.PathUtils;
|
||||||
|
import org.elasticsearch.common.network.NetworkModule;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
||||||
import org.elasticsearch.plugins.Plugin;
|
import org.elasticsearch.plugins.Plugin;
|
||||||
import org.elasticsearch.xpack.security.Security;
|
import org.elasticsearch.xpack.security.Security;
|
||||||
import org.elasticsearch.xpack.security.transport.netty.SecurityNettyTransport;
|
import org.elasticsearch.xpack.security.transport.netty3.SecurityNetty3Transport;
|
||||||
import org.elasticsearch.test.ESIntegTestCase;
|
import org.elasticsearch.test.ESIntegTestCase;
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
import org.elasticsearch.xpack.XPackPlugin;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
@ -49,7 +50,6 @@ public class SmokeTestMonitoringWithSecurityIT extends ESIntegTestCase {
|
||||||
private static final String USER = "test_user";
|
private static final String USER = "test_user";
|
||||||
private static final String PASS = "changeme";
|
private static final String PASS = "changeme";
|
||||||
private static final String KEYSTORE_PASS = "keypass";
|
private static final String KEYSTORE_PASS = "keypass";
|
||||||
|
|
||||||
private static final String MONITORING_PATTERN = ".monitoring-*";
|
private static final String MONITORING_PATTERN = ".monitoring-*";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -61,9 +61,10 @@ public class SmokeTestMonitoringWithSecurityIT extends ESIntegTestCase {
|
||||||
protected Settings externalClusterClientSettings() {
|
protected Settings externalClusterClientSettings() {
|
||||||
return Settings.builder()
|
return Settings.builder()
|
||||||
.put(Security.USER_SETTING.getKey(), USER + ":" + PASS)
|
.put(Security.USER_SETTING.getKey(), USER + ":" + PASS)
|
||||||
.put(SecurityNettyTransport.SSL_SETTING.getKey(), true)
|
.put(SecurityNetty3Transport.SSL_SETTING.getKey(), true)
|
||||||
.put("xpack.security.ssl.keystore.path", clientKeyStore)
|
.put("xpack.security.ssl.keystore.path", clientKeyStore)
|
||||||
.put("xpack.security.ssl.keystore.password", KEYSTORE_PASS)
|
.put("xpack.security.ssl.keystore.password", KEYSTORE_PASS)
|
||||||
|
.put(NetworkModule.TRANSPORT_TYPE_KEY, Security.NAME)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,15 +7,16 @@ package org.elasticsearch.smoketest;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
import com.carrotsearch.randomizedtesting.annotations.Name;
|
||||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.common.io.PathUtils;
|
import org.elasticsearch.common.io.PathUtils;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
import org.elasticsearch.test.rest.ESRestTestCase;
|
||||||
import org.elasticsearch.test.rest.RestTestCandidate;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
import org.elasticsearch.test.rest.client.RestTestClient;
|
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||||
import org.elasticsearch.test.rest.parser.RestTestParseException;
|
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||||
|
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
|
@ -26,19 +27,19 @@ import java.nio.file.Path;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||||
|
|
||||||
public class SmokeTestPluginsSslIT extends ESRestTestCase {
|
public class SmokeTestPluginsSslClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
||||||
|
|
||||||
private static final String USER = "test_user";
|
private static final String USER = "test_user";
|
||||||
private static final String PASS = "changeme";
|
private static final String PASS = "changeme";
|
||||||
private static final String KEYSTORE_PASS = "keypass";
|
private static final String KEYSTORE_PASS = "keypass";
|
||||||
|
|
||||||
public SmokeTestPluginsSslIT(@Name("yaml") RestTestCandidate testCandidate) {
|
public SmokeTestPluginsSslClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
||||||
super(testCandidate);
|
super(testCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersFactory
|
@ParametersFactory
|
||||||
public static Iterable<Object[]> parameters() throws IOException, RestTestParseException {
|
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||||
return ESRestTestCase.createParameters(0, 1);
|
return ESClientYamlSuiteTestCase.createParameters(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Path keyStore;
|
static Path keyStore;
|
||||||
|
@ -46,7 +47,7 @@ public class SmokeTestPluginsSslIT extends ESRestTestCase {
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void getKeyStore() {
|
public static void getKeyStore() {
|
||||||
try {
|
try {
|
||||||
keyStore = PathUtils.get(SmokeTestPluginsSslIT.class.getResource("/test-node.jks").toURI());
|
keyStore = PathUtils.get(SmokeTestPluginsSslClientYamlTestSuiteIT.class.getResource("/test-node.jks").toURI());
|
||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
throw new ElasticsearchException("exception while reading the store", e);
|
throw new ElasticsearchException("exception while reading the store", e);
|
||||||
}
|
}
|
||||||
|
@ -65,9 +66,13 @@ public class SmokeTestPluginsSslIT extends ESRestTestCase {
|
||||||
String token = basicAuthHeaderValue(USER, new SecuredString(PASS.toCharArray()));
|
String token = basicAuthHeaderValue(USER, new SecuredString(PASS.toCharArray()));
|
||||||
return Settings.builder()
|
return Settings.builder()
|
||||||
.put(ThreadContext.PREFIX + ".Authorization", token)
|
.put(ThreadContext.PREFIX + ".Authorization", token)
|
||||||
.put(RestTestClient.PROTOCOL, "https")
|
.put(ESRestTestCase.TRUSTSTORE_PATH, keyStore)
|
||||||
.put(RestTestClient.TRUSTSTORE_PATH, keyStore)
|
.put(ESRestTestCase.TRUSTSTORE_PASSWORD, KEYSTORE_PASS)
|
||||||
.put(RestTestClient.TRUSTSTORE_PASSWORD, KEYSTORE_PASS)
|
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getProtocol() {
|
||||||
|
return "https";
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -9,13 +9,13 @@ dependencies {
|
||||||
ext.pluginsCount = 1 // we install xpack explicitly
|
ext.pluginsCount = 1 // we install xpack explicitly
|
||||||
project.rootProject.subprojects.findAll { it.path.startsWith(':plugins:') }.each { subproj ->
|
project.rootProject.subprojects.findAll { it.path.startsWith(':plugins:') }.each { subproj ->
|
||||||
// need to get a non-decorated project object, so must re-lookup the project by path
|
// need to get a non-decorated project object, so must re-lookup the project by path
|
||||||
integTest.cluster.plugin(subproj.name, project(subproj.path))
|
integTest.cluster.plugin(subproj.path)
|
||||||
pluginsCount += 1
|
pluginsCount += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
integTest {
|
integTest {
|
||||||
cluster {
|
cluster {
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
|
|
||||||
setupCommand 'setupDummyUser',
|
setupCommand 'setupDummyUser',
|
||||||
'bin/x-pack/users', 'useradd', 'test_user', '-p', 'changeme', '-r', 'superuser'
|
'bin/x-pack/users', 'useradd', 'test_user', '-p', 'changeme', '-r', 'superuser'
|
||||||
|
|
|
@ -7,29 +7,30 @@ package org.elasticsearch.smoketest;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
import com.carrotsearch.randomizedtesting.annotations.Name;
|
||||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||||
|
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
|
||||||
import org.elasticsearch.test.rest.RestTestCandidate;
|
|
||||||
import org.elasticsearch.test.rest.parser.RestTestParseException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||||
|
|
||||||
public class SmokeTestPluginsIT extends ESRestTestCase {
|
public class XSmokeTestPluginsClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
||||||
|
|
||||||
private static final String USER = "test_user";
|
private static final String USER = "test_user";
|
||||||
private static final String PASS = "changeme";
|
private static final String PASS = "changeme";
|
||||||
|
|
||||||
public SmokeTestPluginsIT(@Name("yaml") RestTestCandidate testCandidate) {
|
public XSmokeTestPluginsClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
||||||
super(testCandidate);
|
super(testCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersFactory
|
@ParametersFactory
|
||||||
public static Iterable<Object[]> parameters() throws IOException, RestTestParseException {
|
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||||
return ESRestTestCase.createParameters(0, 1);
|
return ESClientYamlSuiteTestCase.createParameters(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -0,0 +1,27 @@
|
||||||
|
apply plugin: 'elasticsearch.rest-test'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testCompile project(path: ':x-plugins:elasticsearch:x-pack', configuration: 'runtime')
|
||||||
|
testCompile project(path: ':modules:lang-mustache', configuration: 'runtime')
|
||||||
|
}
|
||||||
|
|
||||||
|
integTest {
|
||||||
|
cluster {
|
||||||
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
|
setting 'xpack.watcher.enabled', 'false'
|
||||||
|
setting 'xpack.monitoring.enabled', 'false'
|
||||||
|
setting 'path.scripts', "${project.buildDir}/resources/test/templates"
|
||||||
|
setupCommand 'setupDummyUser',
|
||||||
|
'bin/x-pack/users', 'useradd', 'test_admin', '-p', 'changeme', '-r', 'superuser'
|
||||||
|
waitCondition = { node, ant ->
|
||||||
|
File tmpFile = new File(node.cwd, 'wait.success')
|
||||||
|
ant.get(src: "http://${node.httpUri()}",
|
||||||
|
dest: tmpFile.toString(),
|
||||||
|
username: 'test_admin',
|
||||||
|
password: 'changeme',
|
||||||
|
ignoreerrors: true,
|
||||||
|
retries: 10)
|
||||||
|
return tmpFile.exists()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* 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.smoketest;
|
||||||
|
|
||||||
|
import com.carrotsearch.randomizedtesting.annotations.Name;
|
||||||
|
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||||
|
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||||
|
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||||
|
|
||||||
|
public class SmokeTestSecurityWithMustacheClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
||||||
|
|
||||||
|
private static final String BASIC_AUTH_VALUE = basicAuthHeaderValue("test_admin", new SecuredString("changeme".toCharArray()));
|
||||||
|
|
||||||
|
public SmokeTestSecurityWithMustacheClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
||||||
|
super(testCandidate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParametersFactory
|
||||||
|
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||||
|
return ESClientYamlSuiteTestCase.createParameters(0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Settings restClientSettings() {
|
||||||
|
return Settings.builder()
|
||||||
|
.put(ThreadContext.PREFIX + ".Authorization", BASIC_AUTH_VALUE)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,191 @@
|
||||||
|
---
|
||||||
|
setup:
|
||||||
|
- skip:
|
||||||
|
features: headers
|
||||||
|
|
||||||
|
- do:
|
||||||
|
cluster.health:
|
||||||
|
wait_for_status: yellow
|
||||||
|
|
||||||
|
- do:
|
||||||
|
xpack.security.put_user:
|
||||||
|
username: "inline_template_user"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"password": "changeme",
|
||||||
|
"roles" : [ "inline_template_role" ]
|
||||||
|
}
|
||||||
|
- do:
|
||||||
|
xpack.security.put_user:
|
||||||
|
username: "stored_template_user"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"password": "changeme",
|
||||||
|
"roles" : [ "stored_template_role" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
xpack.security.put_user:
|
||||||
|
username: "file_template_user"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"password": "changeme",
|
||||||
|
"roles" : [ "file_template_role" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
xpack.security.put_role:
|
||||||
|
name: "inline_template_role"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"indices": [
|
||||||
|
{
|
||||||
|
"names": "foobar",
|
||||||
|
"privileges": ["all"],
|
||||||
|
"query" : {
|
||||||
|
"template" : {
|
||||||
|
"inline" : {
|
||||||
|
"term" : { "username" : "{{_user.username}}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
xpack.security.put_role:
|
||||||
|
name: "stored_template_role"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"indices": [
|
||||||
|
{
|
||||||
|
"names": "foobar",
|
||||||
|
"privileges": ["all"],
|
||||||
|
"query" : {
|
||||||
|
"template" : {
|
||||||
|
"id" : "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
xpack.security.put_role:
|
||||||
|
name: "file_template_role"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"indices": [
|
||||||
|
{
|
||||||
|
"names": "foobar",
|
||||||
|
"privileges": ["all"],
|
||||||
|
"query" : {
|
||||||
|
"template" : {
|
||||||
|
"file" : "query"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
put_template:
|
||||||
|
id: "1"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"term" : {
|
||||||
|
"username" : "{{_user.username}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
index:
|
||||||
|
index: foobar
|
||||||
|
type: type
|
||||||
|
id: 1
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"username": "inline_template_user"
|
||||||
|
}
|
||||||
|
- do:
|
||||||
|
index:
|
||||||
|
index: foobar
|
||||||
|
type: type
|
||||||
|
id: 2
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"username": "stored_template_user"
|
||||||
|
}
|
||||||
|
- do:
|
||||||
|
index:
|
||||||
|
index: foobar
|
||||||
|
type: type
|
||||||
|
id: 3
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"username": "file_template_user"
|
||||||
|
}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.refresh: {}
|
||||||
|
|
||||||
|
---
|
||||||
|
teardown:
|
||||||
|
- do:
|
||||||
|
xpack.security.delete_user:
|
||||||
|
username: "inline_template_user"
|
||||||
|
ignore: 404
|
||||||
|
- do:
|
||||||
|
xpack.security.delete_user:
|
||||||
|
username: "stored_template_user"
|
||||||
|
ignore: 404
|
||||||
|
- do:
|
||||||
|
xpack.security.delete_user:
|
||||||
|
username: "file_template_user"
|
||||||
|
ignore: 404
|
||||||
|
- do:
|
||||||
|
xpack.security.delete_role:
|
||||||
|
name: "inline_template_role"
|
||||||
|
ignore: 404
|
||||||
|
- do:
|
||||||
|
xpack.security.delete_role:
|
||||||
|
name: "stored_template_role"
|
||||||
|
ignore: 404
|
||||||
|
- do:
|
||||||
|
xpack.security.delete_role:
|
||||||
|
name: "file_template_role"
|
||||||
|
ignore: 404
|
||||||
|
|
||||||
|
---
|
||||||
|
"Test inline template":
|
||||||
|
- do:
|
||||||
|
headers:
|
||||||
|
Authorization: "Basic aW5saW5lX3RlbXBsYXRlX3VzZXI6Y2hhbmdlbWU="
|
||||||
|
search:
|
||||||
|
index: foobar
|
||||||
|
body: { "query" : { "match_all" : {} } }
|
||||||
|
- match: { hits.total: 1}
|
||||||
|
- match: { hits.hits.0._source.username: inline_template_user}
|
||||||
|
|
||||||
|
---
|
||||||
|
"Test stored template":
|
||||||
|
- do:
|
||||||
|
headers:
|
||||||
|
Authorization: "Basic c3RvcmVkX3RlbXBsYXRlX3VzZXI6Y2hhbmdlbWU="
|
||||||
|
search:
|
||||||
|
index: foobar
|
||||||
|
body: { "query" : { "match_all" : {} } }
|
||||||
|
- match: { hits.total: 1}
|
||||||
|
- match: { hits.hits.0._source.username: stored_template_user}
|
||||||
|
|
||||||
|
---
|
||||||
|
"Test file template":
|
||||||
|
- do:
|
||||||
|
headers:
|
||||||
|
Authorization: "Basic ZmlsZV90ZW1wbGF0ZV91c2VyOmNoYW5nZW1l"
|
||||||
|
search:
|
||||||
|
index: foobar
|
||||||
|
body: { "query" : { "match_all" : {} } }
|
||||||
|
- match: { hits.total: 1}
|
||||||
|
- match: { hits.hits.0._source.username: file_template_user}
|
|
@ -0,0 +1,198 @@
|
||||||
|
---
|
||||||
|
setup:
|
||||||
|
- skip:
|
||||||
|
features: headers
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.create:
|
||||||
|
index: shared_logs
|
||||||
|
|
||||||
|
- do:
|
||||||
|
cluster.health:
|
||||||
|
wait_for_status: yellow
|
||||||
|
- do:
|
||||||
|
ingest.put_pipeline:
|
||||||
|
id: "my_pipeline"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"processors": [
|
||||||
|
{
|
||||||
|
"set_security_user" : {
|
||||||
|
"field" : "user"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
- do:
|
||||||
|
xpack.security.put_user:
|
||||||
|
username: "joe"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"password": "changeme",
|
||||||
|
"roles" : [ "small_companies_role" ],
|
||||||
|
"metadata" : {
|
||||||
|
"customer_id" : "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- do:
|
||||||
|
xpack.security.put_user:
|
||||||
|
username: "john"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"password": "changeme",
|
||||||
|
"roles" : [ "small_companies_role" ],
|
||||||
|
"metadata" : {
|
||||||
|
"customer_id" : "2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
teardown:
|
||||||
|
- do:
|
||||||
|
xpack.security.delete_user:
|
||||||
|
username: "joe"
|
||||||
|
ignore: 404
|
||||||
|
- do:
|
||||||
|
xpack.security.delete_user:
|
||||||
|
username: "john"
|
||||||
|
ignore: 404
|
||||||
|
- do:
|
||||||
|
xpack.security.delete_role:
|
||||||
|
name: "small_companies_role"
|
||||||
|
ignore: 404
|
||||||
|
|
||||||
|
---
|
||||||
|
"Test shared index seperating user by using DLS role query with user's username":
|
||||||
|
- do:
|
||||||
|
xpack.security.put_role:
|
||||||
|
name: "small_companies_role"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"indices": [
|
||||||
|
{
|
||||||
|
"names": "shared_logs",
|
||||||
|
"privileges": ["read", "create"],
|
||||||
|
"query" : {
|
||||||
|
"template" : {
|
||||||
|
"inline" : {
|
||||||
|
"term" : { "user.username" : "{{_user.username}}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
headers:
|
||||||
|
Authorization: "Basic am9lOmNoYW5nZW1l"
|
||||||
|
index:
|
||||||
|
index: shared_logs
|
||||||
|
type: type
|
||||||
|
pipeline: "my_pipeline"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"log": "Joe's first log entry"
|
||||||
|
}
|
||||||
|
- do:
|
||||||
|
headers:
|
||||||
|
Authorization: "Basic am9objpjaGFuZ2VtZQ=="
|
||||||
|
index:
|
||||||
|
index: shared_logs
|
||||||
|
type: type
|
||||||
|
pipeline: "my_pipeline"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"log": "John's first log entry"
|
||||||
|
}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.refresh: {}
|
||||||
|
|
||||||
|
# Joe searches:
|
||||||
|
- do:
|
||||||
|
headers:
|
||||||
|
Authorization: "Basic am9lOmNoYW5nZW1l"
|
||||||
|
search:
|
||||||
|
index: shared_logs
|
||||||
|
body: { "query" : { "match_all" : {} } }
|
||||||
|
- match: { hits.total: 1}
|
||||||
|
- match: { hits.hits.0._source.user.username: joe}
|
||||||
|
|
||||||
|
# John searches:
|
||||||
|
- do:
|
||||||
|
headers:
|
||||||
|
Authorization: "Basic am9objpjaGFuZ2VtZQ=="
|
||||||
|
search:
|
||||||
|
index: shared_logs
|
||||||
|
body: { "query" : { "match_all" : {} } }
|
||||||
|
- match: { hits.total: 1}
|
||||||
|
- match: { hits.hits.0._source.user.username: john}
|
||||||
|
|
||||||
|
---
|
||||||
|
"Test shared index seperating user by using DLS role query with user's metadata":
|
||||||
|
- do:
|
||||||
|
xpack.security.put_role:
|
||||||
|
name: "small_companies_role"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"indices": [
|
||||||
|
{
|
||||||
|
"names": "shared_logs",
|
||||||
|
"privileges": ["read", "create"],
|
||||||
|
"query" : {
|
||||||
|
"template" : {
|
||||||
|
"inline" : {
|
||||||
|
"term" : { "user.metadata.customer_id" : "{{_user.metadata.customer_id}}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
headers:
|
||||||
|
Authorization: "Basic am9lOmNoYW5nZW1l"
|
||||||
|
index:
|
||||||
|
index: shared_logs
|
||||||
|
type: type
|
||||||
|
pipeline: "my_pipeline"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"log": "Joe's first log entry"
|
||||||
|
}
|
||||||
|
- do:
|
||||||
|
headers:
|
||||||
|
Authorization: "Basic am9objpjaGFuZ2VtZQ=="
|
||||||
|
index:
|
||||||
|
index: shared_logs
|
||||||
|
type: type
|
||||||
|
pipeline: "my_pipeline"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"log": "John's first log entry"
|
||||||
|
}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.refresh: {}
|
||||||
|
|
||||||
|
# Joe searches:
|
||||||
|
- do:
|
||||||
|
headers:
|
||||||
|
Authorization: "Basic am9lOmNoYW5nZW1l"
|
||||||
|
search:
|
||||||
|
index: shared_logs
|
||||||
|
body: { "query" : { "match_all" : {} } }
|
||||||
|
- match: { hits.total: 1}
|
||||||
|
- match: { hits.hits.0._source.user.username: joe}
|
||||||
|
|
||||||
|
# John searches:
|
||||||
|
- do:
|
||||||
|
headers:
|
||||||
|
Authorization: "Basic am9objpjaGFuZ2VtZQ=="
|
||||||
|
search:
|
||||||
|
index: shared_logs
|
||||||
|
body: { "query" : { "match_all" : {} } }
|
||||||
|
- match: { hits.total: 1}
|
||||||
|
- match: { hits.hits.0._source.user.username: john}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"term" : {
|
||||||
|
"username" : "{{_user.username}}"
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ dependencies {
|
||||||
|
|
||||||
integTest {
|
integTest {
|
||||||
cluster {
|
cluster {
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
setting 'script.inline', 'true'
|
setting 'script.inline', 'true'
|
||||||
setting 'xpack.security.enabled', 'false'
|
setting 'xpack.security.enabled', 'false'
|
||||||
setting 'xpack.monitoring.enabled', 'false'
|
setting 'xpack.monitoring.enabled', 'false'
|
||||||
|
|
|
@ -7,9 +7,10 @@ package org.elasticsearch.smoketest;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
import com.carrotsearch.randomizedtesting.annotations.Name;
|
||||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
|
||||||
import org.elasticsearch.test.rest.RestTestCandidate;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
import org.elasticsearch.test.rest.parser.RestTestParseException;
|
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||||
|
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
|
@ -18,15 +19,15 @@ import java.io.IOException;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static java.util.Collections.emptyMap;
|
import static java.util.Collections.emptyMap;
|
||||||
|
|
||||||
public abstract class WatcherRestTestCase extends ESRestTestCase {
|
public abstract class WatcherRestTestCase extends ESClientYamlSuiteTestCase {
|
||||||
|
|
||||||
public WatcherRestTestCase(@Name("yaml") RestTestCandidate testCandidate) {
|
public WatcherRestTestCase(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
||||||
super(testCandidate);
|
super(testCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersFactory
|
@ParametersFactory
|
||||||
public static Iterable<Object[]> parameters() throws IOException, RestTestParseException {
|
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||||
return ESRestTestCase.createParameters(0, 1);
|
return ESClientYamlSuiteTestCase.createParameters(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
|
|
@ -5,12 +5,12 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.smoketest;
|
package org.elasticsearch.smoketest;
|
||||||
|
|
||||||
import org.elasticsearch.test.rest.RestTestCandidate;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
|
|
||||||
/** Runs rest tests against external cluster */
|
/** Runs rest tests against external cluster */
|
||||||
public class WatcherWithGroovyIT extends WatcherRestTestCase {
|
public class WatcherWithGroovyIT extends WatcherRestTestCase {
|
||||||
|
|
||||||
public WatcherWithGroovyIT(RestTestCandidate testCandidate) {
|
public WatcherWithGroovyIT(ClientYamlTestCandidate testCandidate) {
|
||||||
super(testCandidate);
|
super(testCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,238 @@
|
||||||
|
---
|
||||||
|
"Test simple input to index action":
|
||||||
|
- do:
|
||||||
|
xpack.watcher.put_watch:
|
||||||
|
id: my_watch
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"trigger" : { "schedule" : { "cron" : "0/1 * * * * ? 2020" } },
|
||||||
|
"input" : { "simple" : { "foo": "bar" } },
|
||||||
|
"actions" : {
|
||||||
|
"index_action" : {
|
||||||
|
"index" : {
|
||||||
|
"index" : "idx",
|
||||||
|
"doc_type" : "type",
|
||||||
|
"execution_time_field" : "@timestamp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- match: { _id: "my_watch" }
|
||||||
|
|
||||||
|
|
||||||
|
- do:
|
||||||
|
xpack.watcher.execute_watch:
|
||||||
|
id: "my_watch"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"trigger_data" : {
|
||||||
|
"triggered_time" : "2016-07-07T09:00:00Z",
|
||||||
|
"scheduled_time" : "2016-07-07T09:00:00Z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- match: { "watch_record.state": "executed" }
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.refresh: {}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: idx
|
||||||
|
type: type
|
||||||
|
|
||||||
|
- match: { hits.total: 1 }
|
||||||
|
- match: { hits.hits.0._source.foo: bar }
|
||||||
|
- gte: { hits.hits.0._source.@timestamp: '2016-07-08' }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Test simple input with document field":
|
||||||
|
|
||||||
|
- do:
|
||||||
|
xpack.watcher.put_watch:
|
||||||
|
id: my_watch
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"trigger" : { "schedule" : { "cron" : "0/1 * * * * ? 2020" } },
|
||||||
|
"input" : { "simple" : { "foo": "bar" } },
|
||||||
|
"actions" : {
|
||||||
|
"index_action" : {
|
||||||
|
"transform" : { "script" : { "inline": "return [ '_doc' : ctx.payload ]" } },
|
||||||
|
"index" : {
|
||||||
|
"index" : "idx",
|
||||||
|
"doc_type" : "type",
|
||||||
|
"execution_time_field" : "@timestamp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- match: { _id: "my_watch" }
|
||||||
|
|
||||||
|
|
||||||
|
- do:
|
||||||
|
xpack.watcher.execute_watch:
|
||||||
|
id: "my_watch"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"trigger_data" : {
|
||||||
|
"triggered_time" : "2016-07-07T09:00:00Z",
|
||||||
|
"scheduled_time" : "2016-07-07T09:00:00Z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- match: { "watch_record.state": "executed" }
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.refresh: {}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: idx
|
||||||
|
type: type
|
||||||
|
|
||||||
|
- match: { hits.total: 1 }
|
||||||
|
- match: { hits.hits.0._source.foo: bar }
|
||||||
|
- gte: { hits.hits.0._source.@timestamp: '2016-07-08"' }
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
"Test simple input with wrong document results in error":
|
||||||
|
|
||||||
|
- do:
|
||||||
|
xpack.watcher.put_watch:
|
||||||
|
id: my_watch
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"trigger" : { "schedule" : { "cron" : "0/1 * * * * ? 2020" } },
|
||||||
|
"input" : { "simple" : { "foo": "bar" } },
|
||||||
|
"actions" : {
|
||||||
|
"index_action" : {
|
||||||
|
"transform" : { "script" : { "inline": "return [ '_doc' : 1 ]" } },
|
||||||
|
"index" : {
|
||||||
|
"index" : "idx",
|
||||||
|
"doc_type" : "type",
|
||||||
|
"execution_time_field" : "@timestamp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- match: { _id: "my_watch" }
|
||||||
|
|
||||||
|
|
||||||
|
- do:
|
||||||
|
xpack.watcher.execute_watch:
|
||||||
|
id: "my_watch"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"record_execution" : true,
|
||||||
|
"trigger_data" : {
|
||||||
|
"triggered_time" : "2016-07-07T09:00:00Z",
|
||||||
|
"scheduled_time" : "2016-07-07T09:00:00Z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- match: { "watch_record.state": "executed" }
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.refresh: {}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.exists:
|
||||||
|
index: idx
|
||||||
|
|
||||||
|
- is_false: ''
|
||||||
|
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: .watcher-history-*
|
||||||
|
type: watch_record
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"query" : {
|
||||||
|
"match" : {
|
||||||
|
"result.actions.status": "failure"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- match: { hits.total: 1 }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Test search input to index action with aggs":
|
||||||
|
|
||||||
|
- do:
|
||||||
|
bulk:
|
||||||
|
refresh: true
|
||||||
|
body:
|
||||||
|
- '{"index": {"_index": "idx", "_type": "type", "_id": "1"}}'
|
||||||
|
- '{"@timestamp": "2016-07-07" }'
|
||||||
|
- '{"index": {"_index": "idx", "_type": "type", "_id": "2"}}'
|
||||||
|
- '{"@timestamp": "2016-07-08" }'
|
||||||
|
- '{"index": {"_index": "idx", "_type": "type", "_id": "3"}}'
|
||||||
|
- '{"@timestamp": "2016-07-09" }'
|
||||||
|
|
||||||
|
- do:
|
||||||
|
xpack.watcher.put_watch:
|
||||||
|
id: my_watch
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"trigger" : { "schedule" : { "cron" : "0/1 * * * * ? 2020" } },
|
||||||
|
"input" : {
|
||||||
|
"search" : {
|
||||||
|
"request": {
|
||||||
|
"indices" : [ "idx" ],
|
||||||
|
"types" : [ "type" ],
|
||||||
|
"body" : {
|
||||||
|
"aggs" : {
|
||||||
|
"trend" : {
|
||||||
|
"date_histogram" : {
|
||||||
|
"field" : "@timestamp",
|
||||||
|
"interval" : "day"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"actions" : {
|
||||||
|
"index_action" : {
|
||||||
|
"transform" : { "script" : { "inline": "return [ '_doc' : ctx.payload.aggregations.trend.buckets]" } },
|
||||||
|
"index" : {
|
||||||
|
"index" : "idx",
|
||||||
|
"doc_type" : "bucket",
|
||||||
|
"execution_time_field" : "@timestamp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- match: { _id: "my_watch" }
|
||||||
|
|
||||||
|
|
||||||
|
- do:
|
||||||
|
xpack.watcher.execute_watch:
|
||||||
|
id: "my_watch"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"trigger_data" : {
|
||||||
|
"triggered_time" : "2016-07-07T09:00:00Z",
|
||||||
|
"scheduled_time" : "2016-07-07T09:00:00Z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- match: { "watch_record.state": "executed" }
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.refresh: {}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: idx
|
||||||
|
type: bucket
|
||||||
|
|
||||||
|
- match: { hits.total: 3 }
|
||||||
|
|
|
@ -7,7 +7,7 @@ dependencies {
|
||||||
|
|
||||||
integTest {
|
integTest {
|
||||||
cluster {
|
cluster {
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
setting 'xpack.security.enabled', 'false'
|
setting 'xpack.security.enabled', 'false'
|
||||||
setting 'xpack.monitoring.enabled', 'false'
|
setting 'xpack.monitoring.enabled', 'false'
|
||||||
setting 'http.port', '9400'
|
setting 'http.port', '9400'
|
||||||
|
|
|
@ -7,9 +7,10 @@ package org.elasticsearch.smoketest;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
import com.carrotsearch.randomizedtesting.annotations.Name;
|
||||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
|
||||||
import org.elasticsearch.test.rest.RestTestCandidate;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
import org.elasticsearch.test.rest.parser.RestTestParseException;
|
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||||
|
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
|
@ -18,15 +19,15 @@ import java.io.IOException;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static java.util.Collections.emptyMap;
|
import static java.util.Collections.emptyMap;
|
||||||
|
|
||||||
public abstract class WatcherRestTestCase extends ESRestTestCase {
|
public abstract class SmokeTestWatchesWithMustacheClientYamlTestSuiteTestCase extends ESClientYamlSuiteTestCase {
|
||||||
|
|
||||||
public WatcherRestTestCase(@Name("yaml") RestTestCandidate testCandidate) {
|
public SmokeTestWatchesWithMustacheClientYamlTestSuiteTestCase(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
||||||
super(testCandidate);
|
super(testCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersFactory
|
@ParametersFactory
|
||||||
public static Iterable<Object[]> parameters() throws IOException, RestTestParseException {
|
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||||
return ESRestTestCase.createParameters(0, 1);
|
return ESClientYamlSuiteTestCase.createParameters(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
|
@ -6,37 +6,31 @@
|
||||||
package org.elasticsearch.smoketest;
|
package org.elasticsearch.smoketest;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.io.JsonStringEncoder;
|
import com.fasterxml.jackson.core.io.JsonStringEncoder;
|
||||||
import org.elasticsearch.cluster.ClusterName;
|
|
||||||
import org.elasticsearch.cluster.ClusterState;
|
|
||||||
import org.elasticsearch.cluster.service.ClusterService;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentType;
|
import org.elasticsearch.common.xcontent.XContentType;
|
||||||
import org.elasticsearch.env.Environment;
|
import org.elasticsearch.env.Environment;
|
||||||
import org.elasticsearch.script.ScriptContextRegistry;
|
import org.elasticsearch.script.ScriptContextRegistry;
|
||||||
import org.elasticsearch.script.ScriptEngineRegistry;
|
import org.elasticsearch.script.ScriptEngineRegistry;
|
||||||
import org.elasticsearch.script.ScriptEngineService;
|
|
||||||
import org.elasticsearch.script.ScriptService;
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.script.ScriptSettings;
|
import org.elasticsearch.script.ScriptSettings;
|
||||||
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.watcher.ResourceWatcherService;
|
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||||
import org.elasticsearch.xpack.common.ScriptServiceProxy;
|
|
||||||
import org.elasticsearch.xpack.common.text.DefaultTextTemplateEngine;
|
import org.elasticsearch.xpack.common.text.DefaultTextTemplateEngine;
|
||||||
import org.elasticsearch.xpack.common.text.TextTemplate;
|
import org.elasticsearch.xpack.common.text.TextTemplate;
|
||||||
import org.elasticsearch.xpack.common.text.TextTemplateEngine;
|
import org.elasticsearch.xpack.common.text.TextTemplateEngine;
|
||||||
|
import org.elasticsearch.xpack.watcher.support.WatcherScript;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
|
@ -50,7 +44,7 @@ public class WatcherTemplateTests extends ESTestCase {
|
||||||
Settings setting = Settings.builder().put(ScriptService.SCRIPT_AUTO_RELOAD_ENABLED_SETTING, true).build();
|
Settings setting = Settings.builder().put(ScriptService.SCRIPT_AUTO_RELOAD_ENABLED_SETTING, true).build();
|
||||||
Environment environment = Mockito.mock(Environment.class);
|
Environment environment = Mockito.mock(Environment.class);
|
||||||
ResourceWatcherService resourceWatcherService = Mockito.mock(ResourceWatcherService.class);
|
ResourceWatcherService resourceWatcherService = Mockito.mock(ResourceWatcherService.class);
|
||||||
ScriptContextRegistry registry = new ScriptContextRegistry(Collections.singletonList(ScriptServiceProxy.INSTANCE));
|
ScriptContextRegistry registry = new ScriptContextRegistry(Collections.singletonList(WatcherScript.CTX_PLUGIN));
|
||||||
|
|
||||||
ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry(
|
ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry(
|
||||||
Collections.singleton(new MustacheScriptEngineService(setting))
|
Collections.singleton(new MustacheScriptEngineService(setting))
|
||||||
|
@ -58,7 +52,7 @@ public class WatcherTemplateTests extends ESTestCase {
|
||||||
ScriptSettings scriptSettings = new ScriptSettings(scriptEngineRegistry, registry);
|
ScriptSettings scriptSettings = new ScriptSettings(scriptEngineRegistry, registry);
|
||||||
ScriptService scriptService = new ScriptService(setting, environment, resourceWatcherService, scriptEngineRegistry,
|
ScriptService scriptService = new ScriptService(setting, environment, resourceWatcherService, scriptEngineRegistry,
|
||||||
registry, scriptSettings);
|
registry, scriptSettings);
|
||||||
engine = new DefaultTextTemplateEngine(Settings.EMPTY, ScriptServiceProxy.of(scriptService));
|
engine = new DefaultTextTemplateEngine(Settings.EMPTY, scriptService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testEscaping() throws Exception {
|
public void testEscaping() throws Exception {
|
||||||
|
|
|
@ -7,22 +7,23 @@ package org.elasticsearch.smoketest;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
import com.carrotsearch.randomizedtesting.annotations.Name;
|
||||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
|
||||||
import org.elasticsearch.test.rest.RestTestCandidate;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
import org.elasticsearch.test.rest.parser.RestTestParseException;
|
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||||
|
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/** Runs rest tests against external cluster */
|
/** Runs rest tests against external cluster */
|
||||||
public class WatcherWithMustacheIT extends WatcherRestTestCase {
|
public class WatcherWithMustacheIT extends SmokeTestWatchesWithMustacheClientYamlTestSuiteTestCase {
|
||||||
|
|
||||||
public WatcherWithMustacheIT(@Name("yaml") RestTestCandidate testCandidate) {
|
public WatcherWithMustacheIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
||||||
super(testCandidate);
|
super(testCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersFactory
|
@ParametersFactory
|
||||||
public static Iterable<Object[]> parameters() throws IOException, RestTestParseException {
|
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||||
return ESRestTestCase.createParameters(0, 1);
|
return ESClientYamlSuiteTestCase.createParameters(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ dependencies {
|
||||||
|
|
||||||
integTest {
|
integTest {
|
||||||
cluster {
|
cluster {
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
setting 'script.inline', 'true'
|
setting 'script.inline', 'true'
|
||||||
setting 'xpack.security.enabled', 'false'
|
setting 'xpack.security.enabled', 'false'
|
||||||
setting 'xpack.monitoring.enabled', 'false'
|
setting 'xpack.monitoring.enabled', 'false'
|
||||||
|
|
|
@ -7,9 +7,10 @@ package org.elasticsearch.smoketest;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
import com.carrotsearch.randomizedtesting.annotations.Name;
|
||||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
|
||||||
import org.elasticsearch.test.rest.RestTestCandidate;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
import org.elasticsearch.test.rest.parser.RestTestParseException;
|
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||||
|
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
|
@ -18,15 +19,15 @@ import java.io.IOException;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static java.util.Collections.emptyMap;
|
import static java.util.Collections.emptyMap;
|
||||||
|
|
||||||
public abstract class WatcherRestTestCase extends ESRestTestCase {
|
public abstract class WatcherRestTestCase extends ESClientYamlSuiteTestCase {
|
||||||
|
|
||||||
public WatcherRestTestCase(@Name("yaml") RestTestCandidate testCandidate) {
|
public WatcherRestTestCase(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
||||||
super(testCandidate);
|
super(testCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersFactory
|
@ParametersFactory
|
||||||
public static Iterable<Object[]> parameters() throws IOException, RestTestParseException {
|
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||||
return ESRestTestCase.createParameters(0, 1);
|
return ESClientYamlSuiteTestCase.createParameters(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
|
|
@ -5,12 +5,12 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.smoketest;
|
package org.elasticsearch.smoketest;
|
||||||
|
|
||||||
import org.elasticsearch.test.rest.RestTestCandidate;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
|
|
||||||
/** Runs rest tests against external cluster */
|
/** Runs rest tests against external cluster */
|
||||||
public class WatcherWithPainlessIT extends WatcherRestTestCase {
|
public class WatcherWithPainlessIT extends WatcherRestTestCase {
|
||||||
|
|
||||||
public WatcherWithPainlessIT(RestTestCandidate testCandidate) {
|
public WatcherWithPainlessIT(ClientYamlTestCandidate testCandidate) {
|
||||||
super(testCandidate);
|
super(testCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ integTest {
|
||||||
'getting_started/10_monitor_cluster_health/Getting started - Monitor cluster health'].join(',')
|
'getting_started/10_monitor_cluster_health/Getting started - Monitor cluster health'].join(',')
|
||||||
|
|
||||||
cluster {
|
cluster {
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
extraConfigFile 'x-pack/roles.yml', 'roles.yml'
|
extraConfigFile 'x-pack/roles.yml', 'roles.yml'
|
||||||
setupCommand 'setupTestAdminUser',
|
setupCommand 'setupTestAdminUser',
|
||||||
'bin/x-pack/users', 'useradd', 'test_admin', '-p', 'changeme', '-r', 'superuser'
|
'bin/x-pack/users', 'useradd', 'test_admin', '-p', 'changeme', '-r', 'superuser'
|
||||||
|
|
|
@ -7,36 +7,35 @@ package org.elasticsearch.smoketest;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
import com.carrotsearch.randomizedtesting.annotations.Name;
|
||||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||||
|
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
|
||||||
import org.elasticsearch.test.rest.RestTestCandidate;
|
|
||||||
import org.elasticsearch.test.rest.parser.RestTestParseException;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static java.util.Collections.emptyMap;
|
import static java.util.Collections.emptyMap;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||||
|
|
||||||
|
|
||||||
public class WatcherWithSecurityIT extends ESRestTestCase {
|
public class SmokeTestWatcherWithSecurityClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
||||||
|
|
||||||
private static final String TEST_ADMIN_USERNAME = "test_admin";
|
private static final String TEST_ADMIN_USERNAME = "test_admin";
|
||||||
private static final String TEST_ADMIN_PASSWORD = "changeme";
|
private static final String TEST_ADMIN_PASSWORD = "changeme";
|
||||||
|
|
||||||
public WatcherWithSecurityIT(@Name("yaml") RestTestCandidate testCandidate) {
|
public SmokeTestWatcherWithSecurityClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
||||||
super(testCandidate);
|
super(testCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersFactory
|
@ParametersFactory
|
||||||
public static Iterable<Object[]> parameters() throws IOException, RestTestParseException {
|
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||||
return ESRestTestCase.createParameters(0, 1);
|
return ESClientYamlSuiteTestCase.createParameters(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
|
@ -0,0 +1,14 @@
|
||||||
|
apply plugin: 'elasticsearch.rest-test'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testCompile project(path: ':x-plugins:elasticsearch:x-pack', configuration: 'runtime')
|
||||||
|
}
|
||||||
|
|
||||||
|
integTest {
|
||||||
|
cluster {
|
||||||
|
plugin ':x-plugins:elasticsearch:x-pack'
|
||||||
|
setting 'xpack.security.enabled', 'false'
|
||||||
|
setting 'xpack.monitoring.enabled', 'false'
|
||||||
|
setting 'http.port', '9400'
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* 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.smoketest;
|
||||||
|
|
||||||
|
import com.carrotsearch.randomizedtesting.annotations.Name;
|
||||||
|
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
|
|
||||||
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
|
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||||
|
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyList;
|
||||||
|
import static java.util.Collections.emptyMap;
|
||||||
|
|
||||||
|
/** Runs rest tests against external cluster */
|
||||||
|
public class SmokeTestWatcherClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
||||||
|
|
||||||
|
public SmokeTestWatcherClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
||||||
|
super(testCandidate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParametersFactory
|
||||||
|
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||||
|
return ESClientYamlSuiteTestCase.createParameters(0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void startWatcher() throws Exception {
|
||||||
|
getAdminExecutionContext().callApi("xpack.watcher.start", emptyMap(), emptyList(), emptyMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void stopWatcher() throws Exception {
|
||||||
|
getAdminExecutionContext().callApi("xpack.watcher.stop", emptyMap(), emptyList(), emptyMap());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,6 @@
|
||||||
|
# This test has been moved out of the regular tests as it requires Elasticsearch to run on port 9400
|
||||||
|
# That is a no-go for the clients testing, who could start Elasticsearch on arbitrary ports
|
||||||
|
#
|
||||||
---
|
---
|
||||||
setup:
|
setup:
|
||||||
- do:
|
- do:
|
|
@ -21,14 +21,20 @@ ext.compactProfile = 'full'
|
||||||
|
|
||||||
dependencyLicenses.enabled = false
|
dependencyLicenses.enabled = false
|
||||||
|
|
||||||
|
licenseHeaders {
|
||||||
|
approvedLicenses << 'BCrypt (BSD-like)'
|
||||||
|
additionalLicense 'BCRYP', 'BCrypt (BSD-like)', 'Copyright (c) 2006 Damien Miller <djm@mindrot.org>'
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// license deps
|
// license deps
|
||||||
compile project(':x-plugins:elasticsearch:license:base')
|
compile project(':x-plugins:elasticsearch:license:base')
|
||||||
testCompile project(':x-plugins:elasticsearch:license:licensor')
|
testCompile project(':x-plugins:elasticsearch:license:licensor')
|
||||||
|
|
||||||
// security deps
|
// security deps
|
||||||
|
compile project(path: ':modules:transport-netty3', configuration: 'runtime')
|
||||||
compile 'dk.brics.automaton:automaton:1.11-8'
|
compile 'dk.brics.automaton:automaton:1.11-8'
|
||||||
compile 'com.unboundid:unboundid-ldapsdk:2.3.8'
|
compile 'com.unboundid:unboundid-ldapsdk:3.1.1'
|
||||||
compile 'org.bouncycastle:bcprov-jdk15on:1.54'
|
compile 'org.bouncycastle:bcprov-jdk15on:1.54'
|
||||||
compile 'org.bouncycastle:bcpkix-jdk15on:1.54'
|
compile 'org.bouncycastle:bcpkix-jdk15on:1.54'
|
||||||
testCompile 'com.google.jimfs:jimfs:1.1'
|
testCompile 'com.google.jimfs:jimfs:1.1'
|
||||||
|
@ -231,13 +237,6 @@ thirdPartyAudit.excludes = [
|
||||||
'javax.activation.UnsupportedDataTypeException'
|
'javax.activation.UnsupportedDataTypeException'
|
||||||
]
|
]
|
||||||
|
|
||||||
// someone figure out what the x-plugins logic should be
|
|
||||||
licenseHeaders.enabled = false
|
|
||||||
|
|
||||||
forbiddenApisMain {
|
|
||||||
signaturesURLs += [file('signatures.txt').toURI().toURL()]
|
|
||||||
}
|
|
||||||
|
|
||||||
modifyPom { MavenPom pom ->
|
modifyPom { MavenPom pom ->
|
||||||
pom.withXml { XmlProvider xml ->
|
pom.withXml { XmlProvider xml ->
|
||||||
// first find if we have dependencies at all, and grab the node
|
// first find if we have dependencies at all, and grab the node
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.elasticsearch.action.ActionRequest;
|
||||||
import org.elasticsearch.action.ActionResponse;
|
import org.elasticsearch.action.ActionResponse;
|
||||||
import org.elasticsearch.common.component.LifecycleComponent;
|
import org.elasticsearch.common.component.LifecycleComponent;
|
||||||
import org.elasticsearch.common.inject.Module;
|
import org.elasticsearch.common.inject.Module;
|
||||||
|
import org.elasticsearch.common.inject.util.Providers;
|
||||||
import org.elasticsearch.common.settings.Setting;
|
import org.elasticsearch.common.settings.Setting;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.plugins.ActionPlugin;
|
import org.elasticsearch.plugins.ActionPlugin;
|
||||||
|
@ -43,15 +44,9 @@ public class Graph extends Plugin implements ActionPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Module> createGuiceModules() {
|
public Collection<Module> createGuiceModules() {
|
||||||
return Collections.singletonList(new GraphModule(enabled, transportClientMode));
|
return Collections.singletonList(b -> {
|
||||||
}
|
XPackPlugin.bindFeatureSet(b, GraphFeatureSet.class);
|
||||||
|
});
|
||||||
@Override
|
|
||||||
public Collection<Class<? extends LifecycleComponent>> getGuiceServiceClasses() {
|
|
||||||
if (enabled == false|| transportClientMode) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
return Collections.singletonList(GraphLicensee.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -10,6 +10,7 @@ import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.license.XPackLicenseState;
|
||||||
import org.elasticsearch.xpack.XPackFeatureSet;
|
import org.elasticsearch.xpack.XPackFeatureSet;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -20,12 +21,12 @@ import java.io.IOException;
|
||||||
public class GraphFeatureSet implements XPackFeatureSet {
|
public class GraphFeatureSet implements XPackFeatureSet {
|
||||||
|
|
||||||
private final boolean enabled;
|
private final boolean enabled;
|
||||||
private final GraphLicensee licensee;
|
private final XPackLicenseState licenseState;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public GraphFeatureSet(Settings settings, @Nullable GraphLicensee licensee, NamedWriteableRegistry namedWriteableRegistry) {
|
public GraphFeatureSet(Settings settings, @Nullable XPackLicenseState licenseState, NamedWriteableRegistry namedWriteableRegistry) {
|
||||||
this.enabled = Graph.enabled(settings);
|
this.enabled = Graph.enabled(settings);
|
||||||
this.licensee = licensee;
|
this.licenseState = licenseState;
|
||||||
namedWriteableRegistry.register(Usage.class, Usage.writeableName(Graph.NAME), Usage::new);
|
namedWriteableRegistry.register(Usage.class, Usage.writeableName(Graph.NAME), Usage::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ public class GraphFeatureSet implements XPackFeatureSet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean available() {
|
public boolean available() {
|
||||||
return licensee != null && licensee.isAvailable();
|
return licenseState != null && licenseState.isGraphAllowed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,71 +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.graph;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.license.core.License;
|
|
||||||
import org.elasticsearch.license.core.License.OperationMode;
|
|
||||||
import org.elasticsearch.license.plugin.core.AbstractLicenseeComponent;
|
|
||||||
import org.elasticsearch.license.plugin.core.LicenseState;
|
|
||||||
import org.elasticsearch.license.plugin.core.LicenseeRegistry;
|
|
||||||
|
|
||||||
public class GraphLicensee extends AbstractLicenseeComponent<GraphLicensee> {
|
|
||||||
|
|
||||||
public static final String ID = Graph.NAME;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public GraphLicensee(Settings settings, LicenseeRegistry clientService) {
|
|
||||||
super(settings, ID, clientService);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] expirationMessages() {
|
|
||||||
return new String[] {
|
|
||||||
"Graph explore APIs are disabled"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] acknowledgmentMessages(License currentLicense, License newLicense) {
|
|
||||||
switch (newLicense.operationMode()) {
|
|
||||||
case BASIC:
|
|
||||||
case STANDARD:
|
|
||||||
case GOLD:
|
|
||||||
if (currentLicense != null) {
|
|
||||||
switch (currentLicense.operationMode()) {
|
|
||||||
case TRIAL:
|
|
||||||
case PLATINUM:
|
|
||||||
return new String[] { "Graph will be disabled" };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return Strings.EMPTY_ARRAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if Graph Exploration should be enabled.
|
|
||||||
* <p>
|
|
||||||
* Exploration is only disabled when the license has expired or if the mode is not:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@link OperationMode#PLATINUM}</li>
|
|
||||||
* <li>{@link OperationMode#TRIAL}</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @return {@code true} as long as the license is valid. Otherwise {@code false}.
|
|
||||||
*/
|
|
||||||
public boolean isAvailable() {
|
|
||||||
// status is volatile
|
|
||||||
Status localStatus = status;
|
|
||||||
OperationMode operationMode = localStatus.getMode();
|
|
||||||
|
|
||||||
boolean licensed = operationMode == OperationMode.TRIAL || operationMode == OperationMode.PLATINUM;
|
|
||||||
|
|
||||||
return licensed && localStatus.getLicenseState() != LicenseState.DISABLED;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +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.graph;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
|
||||||
import org.elasticsearch.common.inject.util.Providers;
|
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class GraphModule extends AbstractModule {
|
|
||||||
|
|
||||||
private final boolean enabled;
|
|
||||||
private final boolean transportClientNode;
|
|
||||||
|
|
||||||
public GraphModule(boolean enabled, boolean transportClientNode) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
this.transportClientNode = transportClientNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure() {
|
|
||||||
XPackPlugin.bindFeatureSet(binder(), GraphFeatureSet.class);
|
|
||||||
if (enabled && transportClientNode == false) {
|
|
||||||
bind(GraphLicensee.class).asEagerSingleton();
|
|
||||||
} else {
|
|
||||||
bind(GraphLicensee.class).toProvider(Providers.of(null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -23,7 +23,8 @@ import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.common.util.CollectionUtils;
|
import org.elasticsearch.common.util.CollectionUtils;
|
||||||
import org.elasticsearch.index.query.BoolQueryBuilder;
|
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||||
import org.elasticsearch.index.query.QueryBuilders;
|
import org.elasticsearch.index.query.QueryBuilders;
|
||||||
import org.elasticsearch.license.plugin.core.LicenseUtils;
|
import org.elasticsearch.license.LicenseUtils;
|
||||||
|
import org.elasticsearch.license.XPackLicenseState;
|
||||||
import org.elasticsearch.search.aggregations.AggregationBuilders;
|
import org.elasticsearch.search.aggregations.AggregationBuilders;
|
||||||
import org.elasticsearch.search.aggregations.AggregationBuilder;
|
import org.elasticsearch.search.aggregations.AggregationBuilder;
|
||||||
import org.elasticsearch.search.aggregations.bucket.sampler.DiversifiedAggregationBuilder;
|
import org.elasticsearch.search.aggregations.bucket.sampler.DiversifiedAggregationBuilder;
|
||||||
|
@ -37,7 +38,7 @@ import org.elasticsearch.search.aggregations.bucket.terms.support.IncludeExclude
|
||||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
import org.elasticsearch.xpack.graph.GraphLicensee;
|
import org.elasticsearch.xpack.graph.Graph;
|
||||||
import org.elasticsearch.xpack.graph.action.Connection.ConnectionId;
|
import org.elasticsearch.xpack.graph.action.Connection.ConnectionId;
|
||||||
import org.elasticsearch.xpack.graph.action.GraphExploreRequest.TermBoost;
|
import org.elasticsearch.xpack.graph.action.GraphExploreRequest.TermBoost;
|
||||||
import org.elasticsearch.xpack.graph.action.Vertex.VertexId;
|
import org.elasticsearch.xpack.graph.action.Vertex.VertexId;
|
||||||
|
@ -58,7 +59,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
public class TransportGraphExploreAction extends HandledTransportAction<GraphExploreRequest, GraphExploreResponse> {
|
public class TransportGraphExploreAction extends HandledTransportAction<GraphExploreRequest, GraphExploreResponse> {
|
||||||
|
|
||||||
private final TransportSearchAction searchAction;
|
private final TransportSearchAction searchAction;
|
||||||
protected final GraphLicensee licensee;
|
protected final XPackLicenseState licenseState;
|
||||||
|
|
||||||
static class VertexPriorityQueue extends PriorityQueue<Vertex> {
|
static class VertexPriorityQueue extends PriorityQueue<Vertex> {
|
||||||
|
|
||||||
|
@ -76,19 +77,19 @@ public class TransportGraphExploreAction extends HandledTransportAction<GraphExp
|
||||||
@Inject
|
@Inject
|
||||||
public TransportGraphExploreAction(Settings settings, ThreadPool threadPool, TransportSearchAction transportSearchAction,
|
public TransportGraphExploreAction(Settings settings, ThreadPool threadPool, TransportSearchAction transportSearchAction,
|
||||||
TransportService transportService, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver,
|
TransportService transportService, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver,
|
||||||
GraphLicensee licensee) {
|
XPackLicenseState licenseState) {
|
||||||
super(settings, GraphExploreAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver,
|
super(settings, GraphExploreAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver,
|
||||||
GraphExploreRequest::new);
|
GraphExploreRequest::new);
|
||||||
this.searchAction = transportSearchAction;
|
this.searchAction = transportSearchAction;
|
||||||
this.licensee = licensee;
|
this.licenseState = licenseState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doExecute(GraphExploreRequest request, ActionListener<GraphExploreResponse> listener) {
|
protected void doExecute(GraphExploreRequest request, ActionListener<GraphExploreResponse> listener) {
|
||||||
if (licensee.isAvailable()) {
|
if (licenseState.isGraphAllowed()) {
|
||||||
new AsyncGraphAction(request, listener).start();
|
new AsyncGraphAction(request, listener).start();
|
||||||
} else {
|
} else {
|
||||||
listener.onFailure(LicenseUtils.newComplianceException(GraphLicensee.ID));
|
listener.onFailure(LicenseUtils.newComplianceException(Graph.NAME));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,8 @@ package org.elasticsearch.xpack.graph;
|
||||||
|
|
||||||
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.license.XPackLicenseState;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.xpack.graph.GraphFeatureSet;
|
|
||||||
import org.elasticsearch.xpack.graph.GraphLicensee;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
import static org.hamcrest.core.Is.is;
|
import static org.hamcrest.core.Is.is;
|
||||||
|
@ -24,24 +23,24 @@ import static org.mockito.Mockito.when;
|
||||||
*/
|
*/
|
||||||
public class GraphFeatureSetTests extends ESTestCase {
|
public class GraphFeatureSetTests extends ESTestCase {
|
||||||
|
|
||||||
private GraphLicensee licensee;
|
private XPackLicenseState licenseState;
|
||||||
private NamedWriteableRegistry namedWriteableRegistry;
|
private NamedWriteableRegistry namedWriteableRegistry;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void init() throws Exception {
|
public void init() throws Exception {
|
||||||
licensee = mock(GraphLicensee.class);
|
licenseState = mock(XPackLicenseState.class);
|
||||||
namedWriteableRegistry = mock(NamedWriteableRegistry.class);
|
namedWriteableRegistry = mock(NamedWriteableRegistry.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWritableRegistration() throws Exception {
|
public void testWritableRegistration() throws Exception {
|
||||||
new GraphFeatureSet(Settings.EMPTY, licensee, namedWriteableRegistry);
|
new GraphFeatureSet(Settings.EMPTY, licenseState, namedWriteableRegistry);
|
||||||
verify(namedWriteableRegistry).register(eq(GraphFeatureSet.Usage.class), eq("xpack.usage.graph"), anyObject());
|
verify(namedWriteableRegistry).register(eq(GraphFeatureSet.Usage.class), eq("xpack.usage.graph"), anyObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAvailable() throws Exception {
|
public void testAvailable() throws Exception {
|
||||||
GraphFeatureSet featureSet = new GraphFeatureSet(Settings.EMPTY, licensee, namedWriteableRegistry);
|
GraphFeatureSet featureSet = new GraphFeatureSet(Settings.EMPTY, licenseState, namedWriteableRegistry);
|
||||||
boolean available = randomBoolean();
|
boolean available = randomBoolean();
|
||||||
when(licensee.isAvailable()).thenReturn(available);
|
when(licenseState.isGraphAllowed()).thenReturn(available);
|
||||||
assertThat(featureSet.available(), is(available));
|
assertThat(featureSet.available(), is(available));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +54,7 @@ public class GraphFeatureSetTests extends ESTestCase {
|
||||||
} else {
|
} else {
|
||||||
settings.put("xpack.graph.enabled", enabled);
|
settings.put("xpack.graph.enabled", enabled);
|
||||||
}
|
}
|
||||||
GraphFeatureSet featureSet = new GraphFeatureSet(settings.build(), licensee, namedWriteableRegistry);
|
GraphFeatureSet featureSet = new GraphFeatureSet(settings.build(), licenseState, namedWriteableRegistry);
|
||||||
assertThat(featureSet.enabled(), is(enabled));
|
assertThat(featureSet.enabled(), is(enabled));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,135 +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.graph.license;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.license.core.License.OperationMode;
|
|
||||||
import org.elasticsearch.license.plugin.core.AbstractLicenseeTestCase;
|
|
||||||
import org.elasticsearch.xpack.graph.GraphLicensee;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
|
|
||||||
public class LicenseTests extends AbstractLicenseeTestCase {
|
|
||||||
|
|
||||||
private SimpleLicenseeRegistry licenseeRegistry = new SimpleLicenseeRegistry();
|
|
||||||
|
|
||||||
public void testPlatinumTrialLicenseCanDoEverything() throws Exception {
|
|
||||||
licenseeRegistry.setOperationMode(randomTrialOrPlatinumMode());
|
|
||||||
GraphLicensee graphLicensee = new GraphLicensee(Settings.EMPTY, licenseeRegistry);
|
|
||||||
licenseeRegistry.register(graphLicensee);
|
|
||||||
|
|
||||||
assertLicensePlatinumTrialBehaviour(graphLicensee);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testBasicLicenseIsDisabled() throws Exception {
|
|
||||||
licenseeRegistry.setOperationMode(OperationMode.BASIC);
|
|
||||||
GraphLicensee graphLicensee = new GraphLicensee(Settings.EMPTY, licenseeRegistry);
|
|
||||||
licenseeRegistry.register(graphLicensee);
|
|
||||||
|
|
||||||
assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testStandardLicenseIsDisabled() throws Exception {
|
|
||||||
licenseeRegistry.setOperationMode(OperationMode.STANDARD);
|
|
||||||
GraphLicensee graphLicensee = new GraphLicensee(Settings.EMPTY, licenseeRegistry);
|
|
||||||
licenseeRegistry.register(graphLicensee);
|
|
||||||
|
|
||||||
assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testNoLicenseDoesNotWork() {
|
|
||||||
licenseeRegistry.setOperationMode(OperationMode.BASIC);
|
|
||||||
GraphLicensee graphLicensee = new GraphLicensee(Settings.EMPTY, licenseeRegistry);
|
|
||||||
licenseeRegistry.register(graphLicensee);
|
|
||||||
licenseeRegistry.disable();
|
|
||||||
|
|
||||||
assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testExpiredPlatinumTrialLicenseIsRestricted() throws Exception {
|
|
||||||
licenseeRegistry.setOperationMode(randomTrialOrPlatinumMode());
|
|
||||||
GraphLicensee graphLicensee = new GraphLicensee(Settings.EMPTY, licenseeRegistry);
|
|
||||||
licenseeRegistry.register(graphLicensee);
|
|
||||||
licenseeRegistry.disable();
|
|
||||||
|
|
||||||
assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testUpgradingFromBasicLicenseWorks() {
|
|
||||||
licenseeRegistry.setOperationMode(OperationMode.BASIC);
|
|
||||||
GraphLicensee graphLicensee = new GraphLicensee(Settings.EMPTY, licenseeRegistry);
|
|
||||||
licenseeRegistry.register(graphLicensee);
|
|
||||||
|
|
||||||
assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee);
|
|
||||||
|
|
||||||
licenseeRegistry.setOperationMode(randomTrialOrPlatinumMode());
|
|
||||||
assertLicensePlatinumTrialBehaviour(graphLicensee);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDowngradingToBasicLicenseWorks() {
|
|
||||||
licenseeRegistry.setOperationMode(randomTrialOrPlatinumMode());
|
|
||||||
GraphLicensee graphLicensee = new GraphLicensee(Settings.EMPTY, licenseeRegistry);
|
|
||||||
licenseeRegistry.register(graphLicensee);
|
|
||||||
|
|
||||||
assertLicensePlatinumTrialBehaviour(graphLicensee);
|
|
||||||
|
|
||||||
licenseeRegistry.setOperationMode(OperationMode.BASIC);
|
|
||||||
assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testUpgradingFromStandardLicenseWorks() {
|
|
||||||
licenseeRegistry.setOperationMode(OperationMode.STANDARD);
|
|
||||||
GraphLicensee graphLicensee = new GraphLicensee(Settings.EMPTY, licenseeRegistry);
|
|
||||||
licenseeRegistry.register(graphLicensee);
|
|
||||||
|
|
||||||
assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee);
|
|
||||||
|
|
||||||
licenseeRegistry.setOperationMode(randomTrialOrPlatinumMode());
|
|
||||||
assertLicensePlatinumTrialBehaviour(graphLicensee);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDowngradingToStandardLicenseWorks() {
|
|
||||||
licenseeRegistry.setOperationMode(randomTrialOrPlatinumMode());
|
|
||||||
GraphLicensee graphLicensee = new GraphLicensee(Settings.EMPTY, licenseeRegistry);
|
|
||||||
licenseeRegistry.register(graphLicensee);
|
|
||||||
|
|
||||||
assertLicensePlatinumTrialBehaviour(graphLicensee);
|
|
||||||
|
|
||||||
licenseeRegistry.setOperationMode(OperationMode.STANDARD);
|
|
||||||
assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDowngradingToGoldLicenseWorks() {
|
|
||||||
licenseeRegistry.setOperationMode(randomTrialOrPlatinumMode());
|
|
||||||
GraphLicensee graphLicensee = new GraphLicensee(Settings.EMPTY, licenseeRegistry);
|
|
||||||
licenseeRegistry.register(graphLicensee);
|
|
||||||
|
|
||||||
assertLicensePlatinumTrialBehaviour(graphLicensee);
|
|
||||||
|
|
||||||
licenseeRegistry.setOperationMode(OperationMode.GOLD);
|
|
||||||
assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testUpgradingExpiredLicenseWorks() {
|
|
||||||
licenseeRegistry.setOperationMode(randomTrialOrPlatinumMode());
|
|
||||||
GraphLicensee graphLicensee = new GraphLicensee(Settings.EMPTY, licenseeRegistry);
|
|
||||||
licenseeRegistry.register(graphLicensee);
|
|
||||||
licenseeRegistry.disable();
|
|
||||||
|
|
||||||
assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee);
|
|
||||||
|
|
||||||
licenseeRegistry.setOperationMode(randomTrialOrPlatinumMode());
|
|
||||||
assertLicensePlatinumTrialBehaviour(graphLicensee);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertLicensePlatinumTrialBehaviour(GraphLicensee graphLicensee) {
|
|
||||||
assertThat("Expected graph exploration to be allowed", graphLicensee.isAvailable(), is(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(GraphLicensee graphLicensee) {
|
|
||||||
assertThat("Expected graph exploration not to be allowed", graphLicensee.isAvailable(), is(false));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.action.Action;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.ActionRequestValidationException;
|
||||||
import org.elasticsearch.action.support.master.AcknowledgedRequest;
|
import org.elasticsearch.action.support.master.AcknowledgedRequest;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.action.support.master.AcknowledgedRequestBuilder;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.action.support.master.AcknowledgedResponse;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.logging.LoggerMessageFormat;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
|
@ -12,7 +12,7 @@ import org.elasticsearch.xpack.scheduler.SchedulerEngine;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public abstract class ExpirationCallback {
|
abstract class ExpirationCallback {
|
||||||
|
|
||||||
static final String EXPIRATION_JOB_PREFIX = ".license_expiration_job_";
|
static final String EXPIRATION_JOB_PREFIX = ".license_expiration_job_";
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.action.Action;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.ActionRequestValidationException;
|
||||||
import org.elasticsearch.action.support.master.MasterNodeReadRequest;
|
import org.elasticsearch.action.support.master.MasterNodeReadRequest;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.action.support.master.MasterNodeReadOperationRequestBuilder;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.action.ActionResponse;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.ElasticsearchException;
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
|
@ -18,18 +18,18 @@ import org.elasticsearch.cluster.metadata.MetaData;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.component.AbstractLifecycleComponent;
|
import org.elasticsearch.common.component.AbstractLifecycleComponent;
|
||||||
import org.elasticsearch.common.component.Lifecycle;
|
import org.elasticsearch.common.component.Lifecycle;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
|
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
|
||||||
import org.elasticsearch.common.joda.Joda;
|
import org.elasticsearch.common.joda.Joda;
|
||||||
import org.elasticsearch.common.logging.LoggerMessageFormat;
|
import org.elasticsearch.common.logging.LoggerMessageFormat;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
|
import org.elasticsearch.env.Environment;
|
||||||
import org.elasticsearch.gateway.GatewayService;
|
import org.elasticsearch.gateway.GatewayService;
|
||||||
import org.elasticsearch.license.core.License;
|
import org.elasticsearch.license.core.License;
|
||||||
import org.elasticsearch.license.core.LicenseVerifier;
|
import org.elasticsearch.license.core.LicenseVerifier;
|
||||||
import org.elasticsearch.license.plugin.action.delete.DeleteLicenseRequest;
|
import org.elasticsearch.license.core.OperationModeFileWatcher;
|
||||||
import org.elasticsearch.license.plugin.action.put.PutLicenseRequest;
|
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||||
import org.elasticsearch.license.plugin.action.put.PutLicenseResponse;
|
import org.elasticsearch.xpack.XPackPlugin;
|
||||||
import org.elasticsearch.xpack.scheduler.SchedulerEngine;
|
import org.elasticsearch.xpack.scheduler.SchedulerEngine;
|
||||||
import org.elasticsearch.xpack.support.clock.Clock;
|
import org.elasticsearch.xpack.support.clock.Clock;
|
||||||
|
|
||||||
|
@ -40,41 +40,29 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service responsible for managing {@link LicensesMetaData}
|
* Service responsible for managing {@link LicensesMetaData}.
|
||||||
* Interfaces through which this is exposed are:
|
|
||||||
* - LicensesManagerService - responsible for managing signed and one-time-trial licenses
|
|
||||||
* - LicensesClientService - responsible for listener registration of consumer plugin(s)
|
|
||||||
* <p>
|
* <p>
|
||||||
* Registration Scheme:
|
* On the master node, the service handles updating the cluster state when a new license is registered.
|
||||||
* <p>
|
* It also listens on all nodes for cluster state updates, and updates {@link XPackLicenseState} when
|
||||||
* A consumer plugin is registered with {@link LicenseeRegistry#register(Licensee)}
|
* the license changes are detected in the cluster state.
|
||||||
* This method can be called at any time during the life-cycle of the consumer plugin.
|
|
||||||
* If the listener can not be registered immediately, it is queued up and registered on the first clusterChanged event with
|
|
||||||
* no {@link org.elasticsearch.gateway.GatewayService#STATE_NOT_RECOVERED_BLOCK} block
|
|
||||||
* Upon successful registration, the listeners are notified appropriately using the notification scheme
|
|
||||||
* <p>
|
|
||||||
* Notification Scheme:
|
|
||||||
* <p>
|
|
||||||
* All registered listeners are notified of the current license upon registration or when a new license is installed in the cluster state.
|
|
||||||
* When a new license is notified as enabled to the registered listener, a notification is scheduled at the time of license expiry.
|
|
||||||
* Registered listeners are notified using {@link #onUpdate(LicensesMetaData)}
|
|
||||||
*/
|
*/
|
||||||
public class LicensesService extends AbstractLifecycleComponent implements ClusterStateListener, LicensesManagerService,
|
public class LicenseService extends AbstractLifecycleComponent implements ClusterStateListener, SchedulerEngine.Listener {
|
||||||
LicenseeRegistry, SchedulerEngine.Listener {
|
|
||||||
|
|
||||||
// pkg private for tests
|
// pkg private for tests
|
||||||
static final TimeValue TRIAL_LICENSE_DURATION = TimeValue.timeValueHours(30 * 24);
|
static final TimeValue TRIAL_LICENSE_DURATION = TimeValue.timeValueHours(30 * 24);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Duration of grace period after a license has expired
|
||||||
|
*/
|
||||||
|
static final TimeValue GRACE_PERIOD_DURATION = days(7);
|
||||||
|
|
||||||
private final ClusterService clusterService;
|
private final ClusterService clusterService;
|
||||||
|
|
||||||
/**
|
/** The xpack feature state to update when license changes are made. */
|
||||||
* Currently active consumers to notify to
|
private final XPackLicenseState licenseState;
|
||||||
*/
|
|
||||||
private final List<InternalLicensee> registeredLicensees = new CopyOnWriteArrayList<>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently active license
|
* Currently active license
|
||||||
|
@ -83,6 +71,11 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||||
private SchedulerEngine scheduler;
|
private SchedulerEngine scheduler;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File watcher for operation mode changes
|
||||||
|
*/
|
||||||
|
private final OperationModeFileWatcher operationModeFileWatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callbacks to notify relative to license expiry
|
* Callbacks to notify relative to license expiry
|
||||||
*/
|
*/
|
||||||
|
@ -93,125 +86,78 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||||
*/
|
*/
|
||||||
private int trialLicenseMaxNodes = 1000;
|
private int trialLicenseMaxNodes = 1000;
|
||||||
|
|
||||||
/**
|
public static final String LICENSE_JOB = "licenseJob";
|
||||||
* Duration of grace period after a license has expired
|
|
||||||
*/
|
|
||||||
public static final TimeValue GRACE_PERIOD_DURATION = days(7);
|
|
||||||
|
|
||||||
private static final String LICENSE_JOB = "licenseJob";
|
|
||||||
|
|
||||||
private static final FormatDateTimeFormatter DATE_FORMATTER = Joda.forPattern("EEEE, MMMMM dd, yyyy", Locale.ROOT);
|
private static final FormatDateTimeFormatter DATE_FORMATTER = Joda.forPattern("EEEE, MMMMM dd, yyyy", Locale.ROOT);
|
||||||
|
|
||||||
private static final String ACKNOWLEDGEMENT_HEADER = "This license update requires acknowledgement. To acknowledge the license, " +
|
private static final String ACKNOWLEDGEMENT_HEADER = "This license update requires acknowledgement. To acknowledge the license, " +
|
||||||
"please read the following messages and update the license again, this time with the \"acknowledge=true\" parameter:";
|
"please read the following messages and update the license again, this time with the \"acknowledge=true\" parameter:";
|
||||||
|
|
||||||
@Inject
|
public LicenseService(Settings settings, ClusterService clusterService, Clock clock, Environment env,
|
||||||
public LicensesService(Settings settings, ClusterService clusterService, Clock clock) {
|
ResourceWatcherService resourceWatcherService, XPackLicenseState licenseState) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.clusterService = clusterService;
|
this.clusterService = clusterService;
|
||||||
populateExpirationCallbacks();
|
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.scheduler = new SchedulerEngine(clock);
|
this.scheduler = new SchedulerEngine(clock);
|
||||||
|
this.licenseState = licenseState;
|
||||||
|
this.operationModeFileWatcher = new OperationModeFileWatcher(resourceWatcherService,
|
||||||
|
XPackPlugin.resolveConfigFile(env, "license_mode"), logger, () -> updateLicenseState(getLicense()));
|
||||||
this.scheduler.register(this);
|
this.scheduler.register(this);
|
||||||
|
populateExpirationCallbacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logExpirationWarning(long expirationMillis, boolean expired) {
|
||||||
|
String expiredMsg = expired ? "will expire" : "expired";
|
||||||
|
String general = LoggerMessageFormat.format(null, "\n" +
|
||||||
|
"#\n" +
|
||||||
|
"# License [{}] on [{}]. If you have a new license, please update it.\n" +
|
||||||
|
"# Otherwise, please reach out to your support contact.\n" +
|
||||||
|
"# ", expiredMsg, DATE_FORMATTER.printer().print(expirationMillis));
|
||||||
|
if (expired) {
|
||||||
|
general = general.toUpperCase(Locale.ROOT);
|
||||||
|
}
|
||||||
|
StringBuilder builder = new StringBuilder(general);
|
||||||
|
builder.append(System.lineSeparator());
|
||||||
|
if (expired) {
|
||||||
|
builder.append("# COMMERCIAL PLUGINS OPERATING WITH REDUCED FUNCTIONALITY");
|
||||||
|
} else {
|
||||||
|
builder.append("# Commercial plugins operate with reduced functionality on license expiration:");
|
||||||
|
}
|
||||||
|
XPackLicenseState.EXPIRATION_MESSAGES.forEach((feature, messages) -> {
|
||||||
|
if (messages.length > 0) {
|
||||||
|
builder.append(System.lineSeparator());
|
||||||
|
builder.append("# - ");
|
||||||
|
builder.append(feature);
|
||||||
|
for (String message : messages) {
|
||||||
|
builder.append(System.lineSeparator());
|
||||||
|
builder.append("# - ");
|
||||||
|
builder.append(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
logger.warn("{}", builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateExpirationCallbacks() {
|
private void populateExpirationCallbacks() {
|
||||||
expirationCallbacks.add(new ExpirationCallback.Pre(days(7), days(25), days(1)) {
|
expirationCallbacks.add(new ExpirationCallback.Pre(days(7), days(25), days(1)) {
|
||||||
@Override
|
@Override
|
||||||
public void on(License license) {
|
public void on(License license) {
|
||||||
String general = LoggerMessageFormat.format(null, "\n" +
|
logExpirationWarning(license.expiryDate(), false);
|
||||||
"#\n" +
|
}
|
||||||
"# License will expire on [{}]. If you have a new license, please update it.\n" +
|
});
|
||||||
"# Otherwise, please reach out to your support contact.\n" +
|
|
||||||
"# ", DATE_FORMATTER.printer().print(license.expiryDate()));
|
|
||||||
if (!registeredLicensees.isEmpty()) {
|
|
||||||
StringBuilder builder = new StringBuilder(general);
|
|
||||||
builder.append(System.lineSeparator());
|
|
||||||
builder.append("# Commercial plugins operate with reduced functionality on license " +
|
|
||||||
"expiration:");
|
|
||||||
for (InternalLicensee licensee : registeredLicensees) {
|
|
||||||
if (licensee.expirationMessages().length > 0) {
|
|
||||||
builder.append(System.lineSeparator());
|
|
||||||
builder.append("# - ");
|
|
||||||
builder.append(licensee.id());
|
|
||||||
for (String message : licensee.expirationMessages()) {
|
|
||||||
builder.append(System.lineSeparator());
|
|
||||||
builder.append("# - ");
|
|
||||||
builder.append(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logger.warn("{}", builder);
|
|
||||||
} else {
|
|
||||||
logger.warn("{}", general);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
expirationCallbacks.add(new ExpirationCallback.Pre(days(0), days(7), TimeValue.timeValueMinutes(10)) {
|
expirationCallbacks.add(new ExpirationCallback.Pre(days(0), days(7), TimeValue.timeValueMinutes(10)) {
|
||||||
@Override
|
@Override
|
||||||
public void on(License license) {
|
public void on(License license) {
|
||||||
String general = LoggerMessageFormat.format(null, "\n" +
|
logExpirationWarning(license.expiryDate(), false);
|
||||||
"#\n" +
|
}
|
||||||
"# License will expire on [{}]. If you have a new license, please update it.\n" +
|
});
|
||||||
"# Otherwise, please reach out to your support contact.\n" +
|
|
||||||
"# ", DATE_FORMATTER.printer().print(license.expiryDate()));
|
|
||||||
if (!registeredLicensees.isEmpty()) {
|
|
||||||
StringBuilder builder = new StringBuilder(general);
|
|
||||||
builder.append(System.lineSeparator());
|
|
||||||
builder.append("# Commercial plugins operate with reduced functionality on license " +
|
|
||||||
"expiration:");
|
|
||||||
for (InternalLicensee licensee : registeredLicensees) {
|
|
||||||
if (licensee.expirationMessages().length > 0) {
|
|
||||||
builder.append(System.lineSeparator());
|
|
||||||
builder.append("# - ");
|
|
||||||
builder.append(licensee.id());
|
|
||||||
for (String message : licensee.expirationMessages()) {
|
|
||||||
builder.append(System.lineSeparator());
|
|
||||||
builder.append("# - ");
|
|
||||||
builder.append(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logger.warn("{}", builder.toString());
|
|
||||||
} else {
|
|
||||||
logger.warn("{}", general);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
expirationCallbacks.add(new ExpirationCallback.Post(days(0), null, TimeValue.timeValueMinutes(10)) {
|
expirationCallbacks.add(new ExpirationCallback.Post(days(0), null, TimeValue.timeValueMinutes(10)) {
|
||||||
@Override
|
@Override
|
||||||
public void on(License license) {
|
public void on(License license) {
|
||||||
// logged when grace period begins
|
// logged when grace period begins
|
||||||
String general = LoggerMessageFormat.format(null, "\n" +
|
logExpirationWarning(license.expiryDate(), true);
|
||||||
"#\n" +
|
}
|
||||||
"# LICENSE EXPIRED ON [{}]. IF YOU HAVE A NEW LICENSE, PLEASE\n" +
|
});
|
||||||
"# UPDATE IT. OTHERWISE, PLEASE REACH OUT TO YOUR SUPPORT CONTACT.\n" +
|
|
||||||
"# ", DATE_FORMATTER.printer().print(license.expiryDate()));
|
|
||||||
if (!registeredLicensees.isEmpty()) {
|
|
||||||
StringBuilder builder = new StringBuilder(general);
|
|
||||||
builder.append(System.lineSeparator());
|
|
||||||
builder.append("# COMMERCIAL PLUGINS OPERATING WITH REDUCED FUNCTIONALITY");
|
|
||||||
for (InternalLicensee licensee : registeredLicensees) {
|
|
||||||
if (licensee.expirationMessages().length > 0) {
|
|
||||||
builder.append(System.lineSeparator());
|
|
||||||
builder.append("# - ");
|
|
||||||
builder.append(licensee.id());
|
|
||||||
for (String message : licensee.expirationMessages()) {
|
|
||||||
builder.append(System.lineSeparator());
|
|
||||||
builder.append("# - ");
|
|
||||||
builder.append(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logger.warn("{}", builder.toString());
|
|
||||||
} else {
|
|
||||||
logger.warn("{}", general);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -227,22 +173,23 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||||
listener.onResponse(new PutLicenseResponse(true, LicensesStatus.EXPIRED));
|
listener.onResponse(new PutLicenseResponse(true, LicensesStatus.EXPIRED));
|
||||||
} else {
|
} else {
|
||||||
if (!request.acknowledged()) {
|
if (!request.acknowledged()) {
|
||||||
|
// TODO: ack messages should be generated on the master, since another node's cluster state may be behind...
|
||||||
final License currentLicense = getLicense();
|
final License currentLicense = getLicense();
|
||||||
if (currentLicense != null) {
|
if (currentLicense != null) {
|
||||||
Map<String, String[]> acknowledgeMessages = new HashMap<>(registeredLicensees.size() + 1);
|
Map<String, String[]> acknowledgeMessages = new HashMap<>();
|
||||||
if (!License.isAutoGeneratedLicense(currentLicense.signature()) // current license is not auto-generated
|
if (!License.isAutoGeneratedLicense(currentLicense.signature()) // current license is not auto-generated
|
||||||
&& currentLicense.issueDate() > newLicense.issueDate()) { // and has a later issue date
|
&& currentLicense.issueDate() > newLicense.issueDate()) { // and has a later issue date
|
||||||
acknowledgeMessages.put("license",
|
acknowledgeMessages.put("license", new String[]{
|
||||||
new String[]{"The new license is older than the currently installed license. Are you sure you want to " +
|
"The new license is older than the currently installed license. " +
|
||||||
"override the current license?"});
|
"Are you sure you want to override the current license?"});
|
||||||
}
|
}
|
||||||
for (InternalLicensee licensee : registeredLicensees) {
|
XPackLicenseState.ACKNOWLEDGMENT_MESSAGES.forEach((feature, ackMessages) -> {
|
||||||
String[] listenerAcknowledgeMessages = licensee.acknowledgmentMessages(currentLicense, newLicense);
|
String[] messages = ackMessages.apply(currentLicense.operationMode(), newLicense.operationMode());
|
||||||
if (listenerAcknowledgeMessages.length > 0) {
|
if (messages.length > 0) {
|
||||||
acknowledgeMessages.put(licensee.id(), listenerAcknowledgeMessages);
|
acknowledgeMessages.put(feature, messages);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
if (!acknowledgeMessages.isEmpty()) {
|
if (acknowledgeMessages.isEmpty() == false) {
|
||||||
// needs acknowledgement
|
// needs acknowledgement
|
||||||
listener.onResponse(new PutLicenseResponse(false, LicensesStatus.VALID, ACKNOWLEDGEMENT_HEADER,
|
listener.onResponse(new PutLicenseResponse(false, LicensesStatus.VALID, ACKNOWLEDGEMENT_HEADER,
|
||||||
acknowledgeMessages));
|
acknowledgeMessages));
|
||||||
|
@ -278,7 +225,7 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||||
if (licensesMetaData != null) {
|
if (licensesMetaData != null) {
|
||||||
final License license = licensesMetaData.getLicense();
|
final License license = licensesMetaData.getLicense();
|
||||||
if (event.getJobName().equals(LICENSE_JOB)) {
|
if (event.getJobName().equals(LICENSE_JOB)) {
|
||||||
notifyLicensees(license);
|
updateLicenseState(license);
|
||||||
} else if (event.getJobName().startsWith(ExpirationCallback.EXPIRATION_JOB_PREFIX)) {
|
} else if (event.getJobName().startsWith(ExpirationCallback.EXPIRATION_JOB_PREFIX)) {
|
||||||
expirationCallbacks.stream()
|
expirationCallbacks.stream()
|
||||||
.filter(expirationCallback -> expirationCallback.getId().equals(event.getJobName()))
|
.filter(expirationCallback -> expirationCallback.getId().equals(event.getJobName()))
|
||||||
|
@ -313,17 +260,6 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public LicenseState licenseState() {
|
|
||||||
if (registeredLicensees.size() > 0) {
|
|
||||||
return registeredLicensees.get(0).currentLicenseState;
|
|
||||||
} else {
|
|
||||||
final License license = getLicense(clusterService.state().metaData().custom(LicensesMetaData.TYPE));
|
|
||||||
return getLicenseState(license, clock.millis());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public License getLicense() {
|
public License getLicense() {
|
||||||
final License license = getLicense(clusterService.state().metaData().custom(LicensesMetaData.TYPE));
|
final License license = getLicense(clusterService.state().metaData().custom(LicensesMetaData.TYPE));
|
||||||
return license == LicensesMetaData.LICENSE_TOMBSTONE ? null : license;
|
return license == LicensesMetaData.LICENSE_TOMBSTONE ? null : license;
|
||||||
|
@ -377,15 +313,25 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||||
protected void doStart() throws ElasticsearchException {
|
protected void doStart() throws ElasticsearchException {
|
||||||
clusterService.add(this);
|
clusterService.add(this);
|
||||||
scheduler.start(Collections.emptyList());
|
scheduler.start(Collections.emptyList());
|
||||||
|
logger.debug("initializing license state");
|
||||||
|
final ClusterState clusterState = clusterService.state();
|
||||||
|
if (clusterService.lifecycleState() == Lifecycle.State.STARTED
|
||||||
|
&& clusterState.blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK) == false
|
||||||
|
&& clusterState.nodes().getMasterNode() != null) {
|
||||||
|
final LicensesMetaData currentMetaData = clusterState.metaData().custom(LicensesMetaData.TYPE);
|
||||||
|
if (clusterState.getNodes().isLocalNodeElectedMaster() &&
|
||||||
|
(currentMetaData == null || currentMetaData.getLicense() == null)) {
|
||||||
|
// triggers a cluster changed event
|
||||||
|
// eventually notifying the current licensee
|
||||||
|
registerTrialLicense();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doStop() throws ElasticsearchException {
|
protected void doStop() throws ElasticsearchException {
|
||||||
clusterService.remove(this);
|
clusterService.remove(this);
|
||||||
scheduler.stop();
|
scheduler.stop();
|
||||||
// clear all handlers
|
|
||||||
registeredLicensees.clear();
|
|
||||||
|
|
||||||
// clear current license
|
// clear current license
|
||||||
currentLicense.set(null);
|
currentLicense.set(null);
|
||||||
}
|
}
|
||||||
|
@ -430,54 +376,30 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyLicensees(final License license) {
|
protected void updateLicenseState(final License license) {
|
||||||
if (license == LicensesMetaData.LICENSE_TOMBSTONE) {
|
if (license == LicensesMetaData.LICENSE_TOMBSTONE) {
|
||||||
// implies license has been explicitly deleted
|
// implies license has been explicitly deleted
|
||||||
// update licensee states
|
licenseState.update(License.OperationMode.MISSING, false);
|
||||||
registeredLicensees.forEach(InternalLicensee::onRemove);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (license != null) {
|
if (license != null) {
|
||||||
logger.debug("notifying [{}] listeners", registeredLicensees.size());
|
long time = clock.millis();
|
||||||
switch (getLicenseState(license, clock.millis())) {
|
boolean active = time >= license.issueDate() &&
|
||||||
case ENABLED:
|
time < license.expiryDate() + GRACE_PERIOD_DURATION.getMillis();
|
||||||
for (InternalLicensee licensee : registeredLicensees) {
|
licenseState.update(license.operationMode(), active);
|
||||||
licensee.onChange(license, LicenseState.ENABLED);
|
|
||||||
}
|
if (active) {
|
||||||
|
if (time < license.expiryDate()) {
|
||||||
logger.debug("license [{}] - valid", license.uid());
|
logger.debug("license [{}] - valid", license.uid());
|
||||||
break;
|
} else {
|
||||||
case GRACE_PERIOD:
|
|
||||||
for (InternalLicensee licensee : registeredLicensees) {
|
|
||||||
licensee.onChange(license, LicenseState.GRACE_PERIOD);
|
|
||||||
}
|
|
||||||
logger.warn("license [{}] - grace", license.uid());
|
logger.warn("license [{}] - grace", license.uid());
|
||||||
break;
|
}
|
||||||
case DISABLED:
|
} else {
|
||||||
for (InternalLicensee licensee : registeredLicensees) {
|
logger.warn("license [{}] - expired", license.uid());
|
||||||
licensee.onChange(license, LicenseState.DISABLED);
|
|
||||||
}
|
|
||||||
logger.warn("license [{}] - expired", license.uid());
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static LicenseState getLicenseState(final License license, long time) {
|
|
||||||
if (license == null) {
|
|
||||||
return LicenseState.DISABLED;
|
|
||||||
}
|
|
||||||
if (license.issueDate() > time) {
|
|
||||||
return LicenseState.DISABLED;
|
|
||||||
}
|
|
||||||
if (license.expiryDate() > time) {
|
|
||||||
return LicenseState.ENABLED;
|
|
||||||
}
|
|
||||||
if ((license.expiryDate() + GRACE_PERIOD_DURATION.getMillis()) > time) {
|
|
||||||
return LicenseState.GRACE_PERIOD;
|
|
||||||
}
|
|
||||||
return LicenseState.DISABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies registered licensees of license state change and/or new active license
|
* Notifies registered licensees of license state change and/or new active license
|
||||||
* based on the license in <code>currentLicensesMetaData</code>.
|
* based on the license in <code>currentLicensesMetaData</code>.
|
||||||
|
@ -489,42 +411,42 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||||
// license can be null if the trial license is yet to be auto-generated
|
// license can be null if the trial license is yet to be auto-generated
|
||||||
// in this case, it is a no-op
|
// in this case, it is a no-op
|
||||||
if (license != null) {
|
if (license != null) {
|
||||||
notifyLicensees(license);
|
final License previousLicense = currentLicense.get();
|
||||||
if (license.equals(currentLicense.get()) == false) {
|
if (license.equals(previousLicense) == false) {
|
||||||
currentLicense.set(license);
|
currentLicense.set(license);
|
||||||
scheduler.add(new SchedulerEngine.Job(LICENSE_JOB, new LicenseSchedule(license)));
|
license.setOperationModeFileWatcher(operationModeFileWatcher);
|
||||||
|
scheduler.add(new SchedulerEngine.Job(LICENSE_JOB, nextLicenseCheck(license)));
|
||||||
for (ExpirationCallback expirationCallback : expirationCallbacks) {
|
for (ExpirationCallback expirationCallback : expirationCallbacks) {
|
||||||
scheduler.add(new SchedulerEngine.Job(expirationCallback.getId(),
|
scheduler.add(new SchedulerEngine.Job(expirationCallback.getId(),
|
||||||
(startTime, now) ->
|
(startTime, now) ->
|
||||||
expirationCallback.nextScheduledTimeForExpiry(license.expiryDate(), startTime, now)));
|
expirationCallback.nextScheduledTimeForExpiry(license.expiryDate(), startTime, now)));
|
||||||
}
|
}
|
||||||
|
if (previousLicense != null) {
|
||||||
|
// remove operationModeFileWatcher to gc the old license object
|
||||||
|
previousLicense.removeOperationModeFileWatcher();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
updateLicenseState(license);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// pkg private for tests
|
||||||
public void register(Licensee licensee) {
|
static SchedulerEngine.Schedule nextLicenseCheck(License license) {
|
||||||
for (final InternalLicensee existingLicensee : registeredLicensees) {
|
return (startTime, time) -> {
|
||||||
if (existingLicensee.id().equals(licensee.id())) {
|
if (time < license.issueDate()) {
|
||||||
throw new IllegalStateException("listener: [" + licensee.id() + "] has been already registered");
|
// when we encounter a license with a future issue date
|
||||||
|
// which can happen with autogenerated license,
|
||||||
|
// we want to schedule a notification on the license issue date
|
||||||
|
// so the license is notificed once it is valid
|
||||||
|
// see https://github.com/elastic/x-plugins/issues/983
|
||||||
|
return license.issueDate();
|
||||||
|
} else if (time < license.expiryDate()) {
|
||||||
|
return license.expiryDate();
|
||||||
|
} else if (time < license.expiryDate() + GRACE_PERIOD_DURATION.getMillis()) {
|
||||||
|
return license.expiryDate() + GRACE_PERIOD_DURATION.getMillis();
|
||||||
}
|
}
|
||||||
}
|
return -1; // license is expired, no need to check again
|
||||||
logger.debug("registering licensee [{}]", licensee.id());
|
};
|
||||||
registeredLicensees.add(new InternalLicensee(licensee));
|
|
||||||
final ClusterState clusterState = clusterService.state();
|
|
||||||
if (clusterService.lifecycleState() == Lifecycle.State.STARTED
|
|
||||||
&& clusterState.blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK) == false
|
|
||||||
&& clusterState.nodes().getMasterNode() != null) {
|
|
||||||
final LicensesMetaData currentMetaData = clusterState.metaData().custom(LicensesMetaData.TYPE);
|
|
||||||
if (clusterState.getNodes().isLocalNodeElectedMaster() &&
|
|
||||||
(currentMetaData == null || currentMetaData.getLicense() == null)) {
|
|
||||||
// triggers a cluster changed event
|
|
||||||
// eventually notifying the current licensee
|
|
||||||
registerTrialLicense();
|
|
||||||
} else if (lifecycleState() == Lifecycle.State.STARTED) {
|
|
||||||
notifyLicensees(currentMetaData.getLicense());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
License getLicense(final LicensesMetaData metaData) {
|
License getLicense(final LicensesMetaData metaData) {
|
||||||
|
@ -532,7 +454,7 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||||
License license = metaData.getLicense();
|
License license = metaData.getLicense();
|
||||||
if (license == LicensesMetaData.LICENSE_TOMBSTONE) {
|
if (license == LicensesMetaData.LICENSE_TOMBSTONE) {
|
||||||
return license;
|
return license;
|
||||||
} else {
|
} else if (license != null) {
|
||||||
boolean autoGeneratedLicense = License.isAutoGeneratedLicense(license.signature());
|
boolean autoGeneratedLicense = License.isAutoGeneratedLicense(license.signature());
|
||||||
if ((autoGeneratedLicense && TrialLicense.verify(license))
|
if ((autoGeneratedLicense && TrialLicense.verify(license))
|
||||||
|| (!autoGeneratedLicense && LicenseVerifier.verifyLicense(license))) {
|
|| (!autoGeneratedLicense && LicenseVerifier.verifyLicense(license))) {
|
||||||
|
@ -542,58 +464,4 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores acknowledgement, expiration and license notification callbacks
|
|
||||||
* for a registered listener
|
|
||||||
*/
|
|
||||||
private class InternalLicensee {
|
|
||||||
volatile License currentLicense = null;
|
|
||||||
volatile LicenseState currentLicenseState = LicenseState.DISABLED;
|
|
||||||
private final Licensee licensee;
|
|
||||||
|
|
||||||
private InternalLicensee(Licensee licensee) {
|
|
||||||
this.licensee = licensee;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "(listener: " + licensee.id() + ", state: " + currentLicenseState.name() + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String id() {
|
|
||||||
return licensee.id();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] expirationMessages() {
|
|
||||||
return licensee.expirationMessages();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] acknowledgmentMessages(License currentLicense, License newLicense) {
|
|
||||||
return licensee.acknowledgmentMessages(currentLicense, newLicense);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onChange(License license, LicenseState state) {
|
|
||||||
synchronized (this) {
|
|
||||||
if (currentLicense == null // not yet initialized
|
|
||||||
|| !currentLicense.equals(license) // current license has changed
|
|
||||||
|| currentLicenseState != state) { // same license but state has changed
|
|
||||||
logger.debug("licensee [{}] notified", licensee.id());
|
|
||||||
licensee.onChange(new Licensee.Status(license.operationMode(), state));
|
|
||||||
currentLicense = license;
|
|
||||||
currentLicenseState = state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onRemove() {
|
|
||||||
synchronized (this) {
|
|
||||||
if (currentLicense != null || currentLicenseState != LicenseState.DISABLED) {
|
|
||||||
currentLicense = null;
|
|
||||||
currentLicenseState = LicenseState.DISABLED;
|
|
||||||
licensee.onChange(Licensee.Status.MISSING);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.ElasticsearchSecurityException;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.apache.lucene.util.CollectionUtil;
|
import org.apache.lucene.util.CollectionUtil;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
|
@ -32,7 +32,7 @@ import static org.elasticsearch.license.core.CryptUtils.encrypt;
|
||||||
/**
|
/**
|
||||||
* Contains metadata about registered licenses
|
* Contains metadata about registered licenses
|
||||||
*/
|
*/
|
||||||
public class LicensesMetaData extends AbstractDiffable<MetaData.Custom> implements MetaData.Custom {
|
class LicensesMetaData extends AbstractDiffable<MetaData.Custom> implements MetaData.Custom {
|
||||||
|
|
||||||
public static final String TYPE = "licenses";
|
public static final String TYPE = "licenses";
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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 {
|
public enum LicensesStatus {
|
||||||
VALID((byte) 0),
|
VALID((byte) 0),
|
|
@ -3,37 +3,26 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.ActionRequest;
|
|
||||||
import org.elasticsearch.action.ActionResponse;
|
|
||||||
import org.elasticsearch.cluster.metadata.MetaData;
|
|
||||||
import org.elasticsearch.common.component.LifecycleComponent;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.inject.Module;
|
|
||||||
import org.elasticsearch.common.settings.Setting;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
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.LicenseeRegistry;
|
|
||||||
import org.elasticsearch.license.plugin.core.LicensesManagerService;
|
|
||||||
import org.elasticsearch.license.plugin.core.LicensesMetaData;
|
|
||||||
import org.elasticsearch.license.plugin.core.LicensesService;
|
|
||||||
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 java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.ActionRequest;
|
||||||
|
import org.elasticsearch.action.ActionResponse;
|
||||||
|
import org.elasticsearch.cluster.metadata.MetaData;
|
||||||
|
import org.elasticsearch.cluster.service.ClusterService;
|
||||||
|
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.plugins.ActionPlugin;
|
||||||
|
import org.elasticsearch.rest.RestHandler;
|
||||||
|
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||||
|
import org.elasticsearch.xpack.support.clock.Clock;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static org.elasticsearch.xpack.XPackPlugin.isTribeNode;
|
import static org.elasticsearch.xpack.XPackPlugin.isTribeNode;
|
||||||
import static org.elasticsearch.xpack.XPackPlugin.transportClientMode;
|
import static org.elasticsearch.xpack.XPackPlugin.transportClientMode;
|
||||||
|
@ -42,7 +31,8 @@ import static org.elasticsearch.xpack.XPackPlugin.transportClientMode;
|
||||||
public class Licensing implements ActionPlugin {
|
public class Licensing implements ActionPlugin {
|
||||||
|
|
||||||
public static final String NAME = "license";
|
public static final String NAME = "license";
|
||||||
private final boolean isTransportClient;
|
protected final Settings settings;
|
||||||
|
protected final boolean isTransportClient;
|
||||||
private final boolean isTribeNode;
|
private final boolean isTribeNode;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -50,10 +40,15 @@ public class Licensing implements ActionPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Licensing(Settings settings) {
|
public Licensing(Settings settings) {
|
||||||
|
this.settings = settings;
|
||||||
isTransportClient = transportClientMode(settings);
|
isTransportClient = transportClientMode(settings);
|
||||||
isTribeNode = isTribeNode(settings);
|
isTribeNode = isTribeNode(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collection<Module> nodeModules() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ActionHandler<? extends ActionRequest<?>, ? extends ActionResponse>> getActions() {
|
public List<ActionHandler<? extends ActionRequest<?>, ? extends ActionResponse>> getActions() {
|
||||||
if (isTribeNode) {
|
if (isTribeNode) {
|
||||||
|
@ -74,22 +69,12 @@ public class Licensing implements ActionPlugin {
|
||||||
RestDeleteLicenseAction.class);
|
RestDeleteLicenseAction.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Class<? extends LifecycleComponent>> nodeServices() {
|
public Collection<Object> createComponents(ClusterService clusterService, Clock clock, Environment environment,
|
||||||
if (isTransportClient == false && isTribeNode == false) {
|
ResourceWatcherService resourceWatcherService,
|
||||||
return Collections.<Class<? extends LifecycleComponent>>singletonList(LicensesService.class);
|
XPackLicenseState licenseState) {
|
||||||
}
|
LicenseService licenseService = new LicenseService(settings, clusterService, clock,
|
||||||
return Collections.emptyList();
|
environment, resourceWatcherService, licenseState);
|
||||||
}
|
return Arrays.asList(licenseService, licenseState);
|
||||||
|
|
||||||
public Collection<Module> nodeModules() {
|
|
||||||
if (isTransportClient == false && isTribeNode == false) {
|
|
||||||
return Collections.singletonList(b -> {
|
|
||||||
b.bind(LicensesService.class).asEagerSingleton();
|
|
||||||
b.bind(LicenseeRegistry.class).to(LicensesService.class);
|
|
||||||
b.bind(LicensesManagerService.class).to(LicensesService.class);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Setting<?>> getSettings() {
|
public List<Setting<?>> getSettings() {
|
|
@ -3,23 +3,11 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.action.ActionListener;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
||||||
import org.elasticsearch.license.core.License;
|
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.action.Action;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.ActionRequestValidationException;
|
||||||
import org.elasticsearch.action.ValidateActions;
|
import org.elasticsearch.action.ValidateActions;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.action.support.master.AcknowledgedRequestBuilder;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.action.support.master.AcknowledgedResponse;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
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.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
import org.elasticsearch.license.plugin.core.LicensesStatus;
|
import org.elasticsearch.license.LicensesStatus;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* 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.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.rest.RestChannel;
|
||||||
|
import org.elasticsearch.rest.RestController;
|
||||||
|
import org.elasticsearch.rest.RestRequest;
|
||||||
|
import org.elasticsearch.rest.action.support.AcknowledgedRestListener;
|
||||||
|
import org.elasticsearch.xpack.XPackClient;
|
||||||
|
import org.elasticsearch.xpack.rest.XPackRestHandler;
|
||||||
|
|
||||||
|
import static org.elasticsearch.rest.RestRequest.Method.DELETE;
|
||||||
|
|
||||||
|
public class RestDeleteLicenseAction extends XPackRestHandler {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public RestDeleteLicenseAction(Settings settings, RestController controller) {
|
||||||
|
super(settings);
|
||||||
|
// @deprecated Remove deprecations in 6.0
|
||||||
|
controller.registerWithDeprecatedHandler(DELETE, URI_BASE + "/license", this,
|
||||||
|
DELETE, "/_license", deprecationLogger);
|
||||||
|
|
||||||
|
// Remove _licenses support entirely in 6.0
|
||||||
|
controller.registerAsDeprecatedHandler(DELETE, "/_licenses", this,
|
||||||
|
"[DELETE /_licenses] is deprecated! Use " +
|
||||||
|
"[DELETE /_xpack/license] instead.",
|
||||||
|
deprecationLogger);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleRequest(final RestRequest request, final RestChannel channel, final XPackClient client) {
|
||||||
|
client.es().admin().cluster().execute(DeleteLicenseAction.INSTANCE,
|
||||||
|
new DeleteLicenseRequest(),
|
||||||
|
new AcknowledgedRestListener<>(channel));
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,24 +3,21 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.client.node.NodeClient;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.license.core.License;
|
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.BaseRestHandler;
|
|
||||||
import org.elasticsearch.rest.BytesRestResponse;
|
import org.elasticsearch.rest.BytesRestResponse;
|
||||||
import org.elasticsearch.rest.RestChannel;
|
import org.elasticsearch.rest.RestChannel;
|
||||||
import org.elasticsearch.rest.RestController;
|
import org.elasticsearch.rest.RestController;
|
||||||
import org.elasticsearch.rest.RestRequest;
|
import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.rest.RestResponse;
|
import org.elasticsearch.rest.RestResponse;
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
||||||
|
import org.elasticsearch.xpack.XPackClient;
|
||||||
|
import org.elasticsearch.xpack.rest.XPackRestHandler;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -29,12 +26,20 @@ import static org.elasticsearch.rest.RestRequest.Method.GET;
|
||||||
import static org.elasticsearch.rest.RestStatus.NOT_FOUND;
|
import static org.elasticsearch.rest.RestStatus.NOT_FOUND;
|
||||||
import static org.elasticsearch.rest.RestStatus.OK;
|
import static org.elasticsearch.rest.RestStatus.OK;
|
||||||
|
|
||||||
public class RestGetLicenseAction extends BaseRestHandler {
|
public class RestGetLicenseAction extends XPackRestHandler {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RestGetLicenseAction(Settings settings, RestController controller) {
|
public RestGetLicenseAction(Settings settings, RestController controller) {
|
||||||
super(settings);
|
super(settings);
|
||||||
controller.registerHandler(GET, "/_xpack/license", this);
|
// @deprecated Remove deprecations in 6.0
|
||||||
|
controller.registerWithDeprecatedHandler(GET, URI_BASE + "/license", this,
|
||||||
|
GET, "/_license", deprecationLogger);
|
||||||
|
|
||||||
|
// Remove _licenses support entirely in 6.0
|
||||||
|
controller.registerAsDeprecatedHandler(GET, "/_licenses", this,
|
||||||
|
"[GET /_licenses] is deprecated! Use " +
|
||||||
|
"[GET /_xpack/license] instead.",
|
||||||
|
deprecationLogger);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,14 +49,14 @@ public class RestGetLicenseAction extends BaseRestHandler {
|
||||||
* The licenses are sorted by latest issue_date
|
* The licenses are sorted by latest issue_date
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void handleRequest(final RestRequest request, final RestChannel channel, final NodeClient client) {
|
public void handleRequest(final RestRequest request, final RestChannel channel, final XPackClient client) {
|
||||||
final Map<String, String> overrideParams = new HashMap<>(2);
|
final Map<String, String> overrideParams = new HashMap<>(2);
|
||||||
overrideParams.put(License.REST_VIEW_MODE, "true");
|
overrideParams.put(License.REST_VIEW_MODE, "true");
|
||||||
overrideParams.put(License.LICENSE_VERSION_MODE, String.valueOf(License.VERSION_CURRENT));
|
overrideParams.put(License.LICENSE_VERSION_MODE, String.valueOf(License.VERSION_CURRENT));
|
||||||
final ToXContent.Params params = new ToXContent.DelegatingMapParams(overrideParams, request);
|
final ToXContent.Params params = new ToXContent.DelegatingMapParams(overrideParams, request);
|
||||||
GetLicenseRequest getLicenseRequest = new GetLicenseRequest();
|
GetLicenseRequest getLicenseRequest = new GetLicenseRequest();
|
||||||
getLicenseRequest.local(request.paramAsBoolean("local", getLicenseRequest.local()));
|
getLicenseRequest.local(request.paramAsBoolean("local", getLicenseRequest.local()));
|
||||||
client.admin().cluster().execute(GetLicenseAction.INSTANCE, getLicenseRequest,
|
client.es().admin().cluster().execute(GetLicenseAction.INSTANCE, getLicenseRequest,
|
||||||
new RestBuilderListener<GetLicenseResponse>(channel) {
|
new RestBuilderListener<GetLicenseResponse>(channel) {
|
||||||
@Override
|
@Override
|
||||||
public RestResponse buildResponse(GetLicenseResponse response, XContentBuilder builder) throws Exception {
|
public RestResponse buildResponse(GetLicenseResponse response, XContentBuilder builder) throws Exception {
|
|
@ -3,17 +3,12 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.client.node.NodeClient;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
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.BaseRestHandler;
|
|
||||||
import org.elasticsearch.rest.BytesRestResponse;
|
import org.elasticsearch.rest.BytesRestResponse;
|
||||||
import org.elasticsearch.rest.RestChannel;
|
import org.elasticsearch.rest.RestChannel;
|
||||||
import org.elasticsearch.rest.RestController;
|
import org.elasticsearch.rest.RestController;
|
||||||
|
@ -21,25 +16,40 @@ import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.rest.RestResponse;
|
import org.elasticsearch.rest.RestResponse;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
||||||
|
import org.elasticsearch.xpack.XPackClient;
|
||||||
|
import org.elasticsearch.xpack.rest.XPackRestHandler;
|
||||||
|
|
||||||
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
||||||
import static org.elasticsearch.rest.RestRequest.Method.PUT;
|
import static org.elasticsearch.rest.RestRequest.Method.PUT;
|
||||||
|
|
||||||
public class RestPutLicenseAction extends BaseRestHandler {
|
public class RestPutLicenseAction extends XPackRestHandler {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RestPutLicenseAction(Settings settings, RestController controller) {
|
public RestPutLicenseAction(Settings settings, RestController controller) {
|
||||||
super(settings);
|
super(settings);
|
||||||
controller.registerHandler(PUT, "/_xpack/license", this);
|
// @deprecated Remove deprecations in 6.0
|
||||||
controller.registerHandler(POST, "/_xpack/license", this);
|
controller.registerWithDeprecatedHandler(POST, URI_BASE + "/license", this,
|
||||||
|
POST, "/_license", deprecationLogger);
|
||||||
|
controller.registerWithDeprecatedHandler(PUT, URI_BASE + "/license", this,
|
||||||
|
PUT, "/_license", deprecationLogger);
|
||||||
|
|
||||||
|
// Remove _licenses support entirely in 6.0
|
||||||
|
controller.registerAsDeprecatedHandler(POST, "/_licenses", this,
|
||||||
|
"[POST /_licenses] is deprecated! Use " +
|
||||||
|
"[POST /_xpack/license] instead.",
|
||||||
|
deprecationLogger);
|
||||||
|
controller.registerAsDeprecatedHandler(PUT, "/_licenses", this,
|
||||||
|
"[PUT /_licenses] is deprecated! Use " +
|
||||||
|
"[PUT /_xpack/license] instead.",
|
||||||
|
deprecationLogger);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRequest(final RestRequest request, final RestChannel channel, final NodeClient client) {
|
public void handleRequest(final RestRequest request, final RestChannel channel, final XPackClient client) {
|
||||||
PutLicenseRequest putLicenseRequest = new PutLicenseRequest();
|
PutLicenseRequest putLicenseRequest = new PutLicenseRequest();
|
||||||
putLicenseRequest.license(request.content().utf8ToString());
|
putLicenseRequest.license(request.content().utf8ToString());
|
||||||
putLicenseRequest.acknowledge(request.paramAsBoolean("acknowledge", false));
|
putLicenseRequest.acknowledge(request.paramAsBoolean("acknowledge", false));
|
||||||
client.admin().cluster().execute(PutLicenseAction.INSTANCE, putLicenseRequest,
|
client.es().admin().cluster().execute(PutLicenseAction.INSTANCE, putLicenseRequest,
|
||||||
new RestBuilderListener<PutLicenseResponse>(channel) {
|
new RestBuilderListener<PutLicenseResponse>(channel) {
|
||||||
@Override
|
@Override
|
||||||
public RestResponse buildResponse(PutLicenseResponse response, XContentBuilder builder) throws Exception {
|
public RestResponse buildResponse(PutLicenseResponse response, XContentBuilder builder) throws Exception {
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.ElasticsearchException;
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
|
@ -17,21 +17,20 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel;
|
||||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.license.plugin.core.LicensesService;
|
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
public class TransportDeleteLicenseAction extends TransportMasterNodeAction<DeleteLicenseRequest, DeleteLicenseResponse> {
|
public class TransportDeleteLicenseAction extends TransportMasterNodeAction<DeleteLicenseRequest, DeleteLicenseResponse> {
|
||||||
|
|
||||||
private final LicensesService licensesService;
|
private final LicenseService licenseService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TransportDeleteLicenseAction(Settings settings, TransportService transportService, ClusterService clusterService,
|
public TransportDeleteLicenseAction(Settings settings, TransportService transportService, ClusterService clusterService,
|
||||||
LicensesService licensesService, ThreadPool threadPool, ActionFilters actionFilters,
|
LicenseService licenseService, ThreadPool threadPool, ActionFilters actionFilters,
|
||||||
IndexNameExpressionResolver indexNameExpressionResolver) {
|
IndexNameExpressionResolver indexNameExpressionResolver) {
|
||||||
super(settings, DeleteLicenseAction.NAME, transportService, clusterService, threadPool, actionFilters,
|
super(settings, DeleteLicenseAction.NAME, transportService, clusterService, threadPool, actionFilters,
|
||||||
indexNameExpressionResolver, DeleteLicenseRequest::new);
|
indexNameExpressionResolver, DeleteLicenseRequest::new);
|
||||||
this.licensesService = licensesService;
|
this.licenseService = licenseService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,7 +51,7 @@ public class TransportDeleteLicenseAction extends TransportMasterNodeAction<Dele
|
||||||
@Override
|
@Override
|
||||||
protected void masterOperation(final DeleteLicenseRequest request, ClusterState state, final ActionListener<DeleteLicenseResponse>
|
protected void masterOperation(final DeleteLicenseRequest request, ClusterState state, final ActionListener<DeleteLicenseResponse>
|
||||||
listener) throws ElasticsearchException {
|
listener) throws ElasticsearchException {
|
||||||
licensesService.removeLicense(request, new ActionListener<ClusterStateUpdateResponse>() {
|
licenseService.removeLicense(request, new ActionListener<ClusterStateUpdateResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(ClusterStateUpdateResponse clusterStateUpdateResponse) {
|
public void onResponse(ClusterStateUpdateResponse clusterStateUpdateResponse) {
|
||||||
listener.onResponse(new DeleteLicenseResponse(clusterStateUpdateResponse.isAcknowledged()));
|
listener.onResponse(new DeleteLicenseResponse(clusterStateUpdateResponse.isAcknowledged()));
|
|
@ -3,34 +3,33 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.ElasticsearchException;
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.action.support.ActionFilters;
|
import org.elasticsearch.action.support.ActionFilters;
|
||||||
import org.elasticsearch.action.support.master.TransportMasterNodeReadAction;
|
import org.elasticsearch.action.support.master.TransportMasterNodeReadAction;
|
||||||
import org.elasticsearch.cluster.service.ClusterService;
|
|
||||||
import org.elasticsearch.cluster.ClusterState;
|
import org.elasticsearch.cluster.ClusterState;
|
||||||
import org.elasticsearch.cluster.block.ClusterBlockException;
|
import org.elasticsearch.cluster.block.ClusterBlockException;
|
||||||
import org.elasticsearch.cluster.block.ClusterBlockLevel;
|
import org.elasticsearch.cluster.block.ClusterBlockLevel;
|
||||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||||
|
import org.elasticsearch.cluster.service.ClusterService;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.license.plugin.core.LicensesManagerService;
|
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
public class TransportGetLicenseAction extends TransportMasterNodeReadAction<GetLicenseRequest, GetLicenseResponse> {
|
public class TransportGetLicenseAction extends TransportMasterNodeReadAction<GetLicenseRequest, GetLicenseResponse> {
|
||||||
|
|
||||||
private final LicensesManagerService licensesManagerService;
|
private final LicenseService licenseService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TransportGetLicenseAction(Settings settings, TransportService transportService, ClusterService clusterService,
|
public TransportGetLicenseAction(Settings settings, TransportService transportService, ClusterService clusterService,
|
||||||
LicensesManagerService licensesManagerService, ThreadPool threadPool, ActionFilters actionFilters,
|
LicenseService licenseService, ThreadPool threadPool, ActionFilters actionFilters,
|
||||||
IndexNameExpressionResolver indexNameExpressionResolver) {
|
IndexNameExpressionResolver indexNameExpressionResolver) {
|
||||||
super(settings, GetLicenseAction.NAME, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver,
|
super(settings, GetLicenseAction.NAME, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver,
|
||||||
GetLicenseRequest::new);
|
GetLicenseRequest::new);
|
||||||
this.licensesManagerService = licensesManagerService;
|
this.licenseService = licenseService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,6 +50,6 @@ public class TransportGetLicenseAction extends TransportMasterNodeReadAction<Get
|
||||||
@Override
|
@Override
|
||||||
protected void masterOperation(final GetLicenseRequest request, ClusterState state, final ActionListener<GetLicenseResponse>
|
protected void masterOperation(final GetLicenseRequest request, ClusterState state, final ActionListener<GetLicenseResponse>
|
||||||
listener) throws ElasticsearchException {
|
listener) throws ElasticsearchException {
|
||||||
listener.onResponse(new GetLicenseResponse(licensesManagerService.getLicense()));
|
listener.onResponse(new GetLicenseResponse(licenseService.getLicense()));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.ElasticsearchException;
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
|
@ -16,21 +16,20 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel;
|
||||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.license.plugin.core.LicensesService;
|
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
public class TransportPutLicenseAction extends TransportMasterNodeAction<PutLicenseRequest, PutLicenseResponse> {
|
public class TransportPutLicenseAction extends TransportMasterNodeAction<PutLicenseRequest, PutLicenseResponse> {
|
||||||
|
|
||||||
private final LicensesService licensesService;
|
private final LicenseService licenseService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TransportPutLicenseAction(Settings settings, TransportService transportService, ClusterService clusterService,
|
public TransportPutLicenseAction(Settings settings, TransportService transportService, ClusterService clusterService,
|
||||||
LicensesService licensesService, ThreadPool threadPool, ActionFilters actionFilters,
|
LicenseService licenseService, ThreadPool threadPool, ActionFilters actionFilters,
|
||||||
IndexNameExpressionResolver indexNameExpressionResolver) {
|
IndexNameExpressionResolver indexNameExpressionResolver) {
|
||||||
super(settings, PutLicenseAction.NAME, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver,
|
super(settings, PutLicenseAction.NAME, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver,
|
||||||
PutLicenseRequest::new);
|
PutLicenseRequest::new);
|
||||||
this.licensesService = licensesService;
|
this.licenseService = licenseService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,7 +50,7 @@ public class TransportPutLicenseAction extends TransportMasterNodeAction<PutLice
|
||||||
@Override
|
@Override
|
||||||
protected void masterOperation(final PutLicenseRequest request, ClusterState state, final ActionListener<PutLicenseResponse>
|
protected void masterOperation(final PutLicenseRequest request, ClusterState state, final ActionListener<PutLicenseResponse>
|
||||||
listener) throws ElasticsearchException {
|
listener) throws ElasticsearchException {
|
||||||
licensesService.registerLicense(request, listener);
|
licenseService.registerLicense(request, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with 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.bytes.BytesReference;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
|
@ -21,7 +21,7 @@ import java.util.Collections;
|
||||||
import static org.elasticsearch.license.core.CryptUtils.decrypt;
|
import static org.elasticsearch.license.core.CryptUtils.decrypt;
|
||||||
import static org.elasticsearch.license.core.CryptUtils.encrypt;
|
import static org.elasticsearch.license.core.CryptUtils.encrypt;
|
||||||
|
|
||||||
public class TrialLicense {
|
class TrialLicense {
|
||||||
|
|
||||||
public static License create(License.Builder specBuilder) {
|
public static License create(License.Builder specBuilder) {
|
||||||
License spec = specBuilder
|
License spec = specBuilder
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue