tests pass; second iterations; still a lot of TODOs
Original commit: elastic/x-pack-elasticsearch@0e1e409c6f
This commit is contained in:
parent
593b8ca18f
commit
319dc9c88b
178
pom.xml
178
pom.xml
|
@ -48,6 +48,68 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- compile deps -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.lucene</groupId>
|
||||||
|
<artifactId>lucene-core</artifactId>
|
||||||
|
<version>${lucene.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.lucene</groupId>
|
||||||
|
<artifactId>lucene-analyzers-common</artifactId>
|
||||||
|
<version>${lucene.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.lucene</groupId>
|
||||||
|
<artifactId>lucene-queries</artifactId>
|
||||||
|
<version>${lucene.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>jakarta-regexp</groupId>
|
||||||
|
<artifactId>jakarta-regexp</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.lucene</groupId>
|
||||||
|
<artifactId>lucene-memory</artifactId>
|
||||||
|
<version>${lucene.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.lucene</groupId>
|
||||||
|
<artifactId>lucene-highlighter</artifactId>
|
||||||
|
<version>${lucene.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.lucene</groupId>
|
||||||
|
<artifactId>lucene-queryparser</artifactId>
|
||||||
|
<version>${lucene.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>jakarta-regexp</groupId>
|
||||||
|
<artifactId>jakarta-regexp</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.lucene</groupId>
|
||||||
|
<artifactId>lucene-suggest</artifactId>
|
||||||
|
<version>${lucene.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.lucene</groupId>
|
||||||
|
<artifactId>lucene-join</artifactId>
|
||||||
|
<version>${lucene.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- actual deps -->
|
<!-- actual deps -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.nicholaswilliams.java.licensing</groupId>
|
<groupId>net.nicholaswilliams.java.licensing</groupId>
|
||||||
|
@ -165,122 +227,6 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>com.carrotsearch.randomizedtesting</groupId>
|
|
||||||
<artifactId>junit4-maven-plugin</artifactId>
|
|
||||||
<version>2.1.2</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>tests</id>
|
|
||||||
<phase>test</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>junit4</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<heartbeat>20</heartbeat>
|
|
||||||
<jvmOutputAction>pipe,warn</jvmOutputAction>
|
|
||||||
<leaveTemporary>true</leaveTemporary>
|
|
||||||
<listeners>
|
|
||||||
<report-ant-xml mavenExtensions="true"
|
|
||||||
dir="${project.build.directory}/surefire-reports"/>
|
|
||||||
<report-text
|
|
||||||
showThrowable="true"
|
|
||||||
showStackTraces="true"
|
|
||||||
showOutput="${tests.output}"
|
|
||||||
showStatusOk="false"
|
|
||||||
showStatusError="true"
|
|
||||||
showStatusFailure="true"
|
|
||||||
showStatusIgnored="true"
|
|
||||||
showSuiteSummary="true"
|
|
||||||
timestamps="false"/>
|
|
||||||
<report-execution-times historyLength="20" file="${basedir}/${execution.hint.file}"/>
|
|
||||||
</listeners>
|
|
||||||
<assertions>
|
|
||||||
<enable/>
|
|
||||||
<disable package="${tests.assertion.disabled}"/>
|
|
||||||
<!-- pass org.elasticsearch to run without assertions -->
|
|
||||||
</assertions>
|
|
||||||
<parallelism>${tests.jvms}</parallelism>
|
|
||||||
<balancers>
|
|
||||||
<execution-times>
|
|
||||||
<fileset dir="${basedir}" includes="${execution.hint.file}"/>
|
|
||||||
</execution-times>
|
|
||||||
</balancers>
|
|
||||||
<includes>
|
|
||||||
<include>**/*Tests.class</include>
|
|
||||||
<include>**/*Test.class</include>
|
|
||||||
</includes>
|
|
||||||
<excludes>
|
|
||||||
<exclude>**/Abstract*.class</exclude>
|
|
||||||
<exclude>**/*StressTest.class</exclude>
|
|
||||||
</excludes>
|
|
||||||
<jvmArgs>
|
|
||||||
<param>-Xmx${tests.heap.size}</param>
|
|
||||||
<param>-Xms${tests.heap.size}</param>
|
|
||||||
<param>-Xss256k</param>
|
|
||||||
<param>-XX:MaxPermSize=128m</param>
|
|
||||||
<param>-XX:MaxDirectMemorySize=512m</param>
|
|
||||||
<param>-Des.logger.prefix=</param>
|
|
||||||
<param>-XX:+HeapDumpOnOutOfMemoryError</param>
|
|
||||||
<param>-XX:HeapDumpPath=${tests.heapdump.path}</param>
|
|
||||||
</jvmArgs>
|
|
||||||
<shuffleOnSlave>${tests.shuffle}</shuffleOnSlave>
|
|
||||||
<sysouts>${tests.verbose}</sysouts>
|
|
||||||
<seed>${tests.seed}</seed>
|
|
||||||
<haltOnFailure>${tests.failfast}</haltOnFailure>
|
|
||||||
<uniqueSuiteNames>false</uniqueSuiteNames>
|
|
||||||
<systemProperties>
|
|
||||||
<java.io.tmpdir>.</java.io.tmpdir>
|
|
||||||
<!-- we use '.' since this is different per JVM-->
|
|
||||||
<!-- RandomizedTesting library system properties -->
|
|
||||||
<tests.bwc>${tests.bwc}</tests.bwc>
|
|
||||||
<tests.bwc.path>${tests.bwc.path}</tests.bwc.path>
|
|
||||||
<tests.bwc.version>${tests.bwc.version}</tests.bwc.version>
|
|
||||||
<tests.jvm.argline>${tests.jvm.argline}</tests.jvm.argline>
|
|
||||||
<tests.processors>${tests.processors}</tests.processors>
|
|
||||||
<tests.appendseed>${tests.appendseed}</tests.appendseed>
|
|
||||||
<tests.iters>${tests.iters}</tests.iters>
|
|
||||||
<tests.maxfailures>${tests.maxfailures}</tests.maxfailures>
|
|
||||||
<tests.failfast>${tests.failfast}</tests.failfast>
|
|
||||||
<tests.class>${tests.class}</tests.class>
|
|
||||||
<tests.method>${tests.method}</tests.method>
|
|
||||||
<tests.nightly>${tests.nightly}</tests.nightly>
|
|
||||||
<tests.verbose>${tests.verbose}</tests.verbose>
|
|
||||||
<tests.badapples>${tests.badapples}</tests.badapples>
|
|
||||||
<tests.weekly>${tests.weekly}</tests.weekly>
|
|
||||||
<tests.slow>${tests.slow}</tests.slow>
|
|
||||||
<tests.awaitsfix>${tests.awaitsfix}</tests.awaitsfix>
|
|
||||||
<tests.slow>${tests.slow}</tests.slow>
|
|
||||||
<tests.timeoutSuite>${tests.timeoutSuite}</tests.timeoutSuite>
|
|
||||||
<tests.showSuccess>${tests.showSuccess}</tests.showSuccess>
|
|
||||||
<tests.integration>${tests.integration}</tests.integration>
|
|
||||||
<tests.client.ratio>${tests.client.ratio}</tests.client.ratio>
|
|
||||||
<tests.enable_mock_modules>${tests.enable_mock_modules}</tests.enable_mock_modules>
|
|
||||||
<tests.assertion.disabled>${tests.assertion.disabled}</tests.assertion.disabled>
|
|
||||||
<tests.rest>${tests.rest}</tests.rest>
|
|
||||||
<tests.rest.suite>${tests.rest.suite}</tests.rest.suite>
|
|
||||||
<tests.rest.blacklist>${tests.rest.blacklist}</tests.rest.blacklist>
|
|
||||||
<tests.rest.spec>${tests.rest.spec}</tests.rest.spec>
|
|
||||||
<tests.network>${tests.network}</tests.network>
|
|
||||||
<tests.cluster>${tests.cluster}</tests.cluster>
|
|
||||||
<tests.heap.size>${tests.heap.size}</tests.heap.size>
|
|
||||||
<tests.filter>${tests.filter}</tests.filter>
|
|
||||||
<tests.version>${project.version}</tests.version>
|
|
||||||
<es.node.local>${env.ES_TEST_LOCAL}</es.node.local>
|
|
||||||
<es.node.mode>${es.node.mode}</es.node.mode>
|
|
||||||
<es.logger.level>${es.logger.level}</es.logger.level>
|
|
||||||
<tests.security.manager>${tests.security.manager}</tests.security.manager>
|
|
||||||
<tests.compatibility>${tests.compatibility}</tests.compatibility>
|
|
||||||
<java.awt.headless>true</java.awt.headless>
|
|
||||||
<!-- everything below is for security manager / test.policy -->
|
|
||||||
<junit4.tempDir>${project.build.directory}</junit4.tempDir>
|
|
||||||
<java.security.policy>${basedir}/dev-tools/tests.policy</java.security.policy>
|
|
||||||
</systemProperties>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.license.plugin;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.inject.AbstractModule;
|
||||||
|
import org.elasticsearch.license.plugin.core.LicensesService;
|
||||||
|
|
||||||
|
public class LicenseModule extends AbstractModule {
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
//requestInjection(LicensesService.class);
|
||||||
|
bind(LicensesService.class).asEagerSingleton();
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,17 +6,24 @@
|
||||||
package org.elasticsearch.license.plugin;
|
package org.elasticsearch.license.plugin;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionModule;
|
import org.elasticsearch.action.ActionModule;
|
||||||
|
import org.elasticsearch.action.admin.cluster.ClusterAction;
|
||||||
import org.elasticsearch.cluster.metadata.MetaData;
|
import org.elasticsearch.cluster.metadata.MetaData;
|
||||||
|
import org.elasticsearch.common.collect.ImmutableSet;
|
||||||
|
import org.elasticsearch.common.component.LifecycleComponent;
|
||||||
|
import org.elasticsearch.common.inject.Module;
|
||||||
import org.elasticsearch.license.plugin.action.get.GetLicenseAction;
|
import org.elasticsearch.license.plugin.action.get.GetLicenseAction;
|
||||||
import org.elasticsearch.license.plugin.action.get.TransportGetLicenseAction;
|
import org.elasticsearch.license.plugin.action.get.TransportGetLicenseAction;
|
||||||
import org.elasticsearch.license.plugin.action.put.PutLicenseAction;
|
import org.elasticsearch.license.plugin.action.put.PutLicenseAction;
|
||||||
import org.elasticsearch.license.plugin.action.put.TransportPutLicenseAction;
|
import org.elasticsearch.license.plugin.action.put.TransportPutLicenseAction;
|
||||||
import org.elasticsearch.license.plugin.cluster.LicensesMetaData;
|
import org.elasticsearch.license.plugin.core.LicensesMetaData;
|
||||||
import org.elasticsearch.license.plugin.rest.RestGetLicenseAction;
|
import org.elasticsearch.license.plugin.rest.RestGetLicenseAction;
|
||||||
import org.elasticsearch.license.plugin.rest.RestPutLicenseAction;
|
import org.elasticsearch.license.plugin.rest.RestPutLicenseAction;
|
||||||
|
import org.elasticsearch.license.plugin.core.LicensesService;
|
||||||
import org.elasticsearch.plugins.AbstractPlugin;
|
import org.elasticsearch.plugins.AbstractPlugin;
|
||||||
import org.elasticsearch.rest.RestModule;
|
import org.elasticsearch.rest.RestModule;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
//TODO: plugin hooks
|
//TODO: plugin hooks
|
||||||
public class LicensePlugin extends AbstractPlugin {
|
public class LicensePlugin extends AbstractPlugin {
|
||||||
|
|
||||||
|
@ -44,6 +51,14 @@ public class LicensePlugin extends AbstractPlugin {
|
||||||
module.registerAction(PutLicenseAction.INSTANCE, TransportPutLicenseAction.class);
|
module.registerAction(PutLicenseAction.INSTANCE, TransportPutLicenseAction.class);
|
||||||
module.registerAction(GetLicenseAction.INSTANCE, TransportGetLicenseAction.class);
|
module.registerAction(GetLicenseAction.INSTANCE, TransportGetLicenseAction.class);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public Collection<Class<? extends LifecycleComponent>> services() {
|
||||||
|
return ImmutableSet.<Class<? extends LifecycleComponent>>of(LicensesService.class);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
@Override
|
||||||
|
public Collection<Class<? extends Module>> modules() {
|
||||||
|
return ImmutableSet.<Class<? extends Module>>of(LicenseModule.class);
|
||||||
|
} */
|
||||||
//TODO: module binding? (LicenseModule)
|
//TODO: module binding? (LicenseModule)
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,10 +46,10 @@ public class Utils {
|
||||||
public static Map<String, Object> licenseAsMap(ESLicense esLicense) {
|
public static Map<String, Object> licenseAsMap(ESLicense esLicense) {
|
||||||
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
|
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
|
||||||
builder.put(LicenseFields.UID, esLicense.uid());
|
builder.put(LicenseFields.UID, esLicense.uid());
|
||||||
builder.put(LicenseFields.TYPE, esLicense.type());
|
builder.put(LicenseFields.TYPE, esLicense.type().string());
|
||||||
builder.put(LicenseFields.SUBSCRIPTION_TYPE, esLicense.subscriptionType());
|
builder.put(LicenseFields.SUBSCRIPTION_TYPE, esLicense.subscriptionType().string());
|
||||||
builder.put(LicenseFields.ISSUE_DATE, esLicense.issueDate());
|
builder.put(LicenseFields.ISSUE_DATE, esLicense.issueDate());
|
||||||
builder.put(LicenseFields.FEATURE, esLicense.feature());
|
builder.put(LicenseFields.FEATURE, esLicense.feature().string());
|
||||||
builder.put(LicenseFields.EXPIRY_DATE, esLicense.expiryDate());
|
builder.put(LicenseFields.EXPIRY_DATE, esLicense.expiryDate());
|
||||||
builder.put(LicenseFields.MAX_NODES, esLicense.maxNodes());
|
builder.put(LicenseFields.MAX_NODES, esLicense.maxNodes());
|
||||||
builder.put(LicenseFields.ISSUED_TO, esLicense.issuedTo());
|
builder.put(LicenseFields.ISSUED_TO, esLicense.issuedTo());
|
||||||
|
@ -60,12 +60,12 @@ public class Utils {
|
||||||
public static ESLicense licenseFromMap(Map<String, Object> map) {
|
public static ESLicense licenseFromMap(Map<String, Object> map) {
|
||||||
return LicenseBuilders.licenseBuilder(false)
|
return LicenseBuilders.licenseBuilder(false)
|
||||||
.uid((String) map.get(LicenseFields.UID))
|
.uid((String) map.get(LicenseFields.UID))
|
||||||
.type((Type) map.get(LicenseFields.TYPE))
|
.type(Type.fromString((String) map.get(LicenseFields.TYPE)))
|
||||||
.subscriptionType((SubscriptionType) map.get(LicenseFields.SUBSCRIPTION_TYPE))
|
.subscriptionType(SubscriptionType.fromString((String) map.get(LicenseFields.SUBSCRIPTION_TYPE)))
|
||||||
.issueDate((Long) map.get(LicenseFields.ISSUE_DATE))
|
.issueDate((long) map.get(LicenseFields.ISSUE_DATE))
|
||||||
.feature((FeatureType) map.get(LicenseFields.FEATURE))
|
.feature(FeatureType.fromString((String) map.get(LicenseFields.FEATURE)))
|
||||||
.expiryDate((Long) map.get(LicenseFields.EXPIRY_DATE))
|
.expiryDate((long) map.get(LicenseFields.EXPIRY_DATE))
|
||||||
.maxNodes((Integer) map.get(LicenseFields.MAX_NODES))
|
.maxNodes((int) map.get(LicenseFields.MAX_NODES))
|
||||||
.issuedTo((String) map.get(LicenseFields.ISSUED_TO))
|
.issuedTo((String) map.get(LicenseFields.ISSUED_TO))
|
||||||
.signature((String) map.get(LicenseFields.SIGNATURE))
|
.signature((String) map.get(LicenseFields.SIGNATURE))
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.license.plugin.action.delete;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.admin.cluster.ClusterAction;
|
||||||
|
import org.elasticsearch.client.ClusterAdminClient;
|
||||||
|
|
||||||
|
public class DeleteLicenseAction extends ClusterAction<DeleteLicenseRequest, DeleteLicenseResponse, DeleteLicenseRequestBuilder> {
|
||||||
|
|
||||||
|
public static final DeleteLicenseAction INSTANCE = new DeleteLicenseAction();
|
||||||
|
public static final String NAME = "cluster:admin/license/delete";
|
||||||
|
|
||||||
|
private DeleteLicenseAction() {
|
||||||
|
super(NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DeleteLicenseResponse newResponse() {
|
||||||
|
return new DeleteLicenseResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DeleteLicenseRequestBuilder newRequestBuilder(ClusterAdminClient client) {
|
||||||
|
return new DeleteLicenseRequestBuilder(client);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.license.plugin.action.delete;
|
||||||
|
|
||||||
|
import org.elasticsearch.Version;
|
||||||
|
import org.elasticsearch.action.ActionRequestValidationException;
|
||||||
|
import org.elasticsearch.action.support.master.AcknowledgedRequest;
|
||||||
|
import org.elasticsearch.action.support.master.MasterNodeReadOperationRequest;
|
||||||
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
import org.elasticsearch.license.core.ESLicenses;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
||||||
|
public class DeleteLicenseRequest extends AcknowledgedRequest<DeleteLicenseRequest> {
|
||||||
|
|
||||||
|
private String[] features;
|
||||||
|
|
||||||
|
public DeleteLicenseRequest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeleteLicenseRequest(String... features) {
|
||||||
|
this.features = features;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void features(Set<String> features) {
|
||||||
|
this.features = features.toArray(new String[features.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> features() {
|
||||||
|
return new HashSet<>(Arrays.asList(features));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionRequestValidationException validate() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readFrom(StreamInput in) throws IOException {
|
||||||
|
super.readFrom(in);
|
||||||
|
features = in.readStringArray();
|
||||||
|
readTimeout(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
|
super.writeTo(out);
|
||||||
|
out.writeStringArray(features);
|
||||||
|
writeTimeout(out);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.license.plugin.action.delete;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.ActionListener;
|
||||||
|
import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder;
|
||||||
|
import org.elasticsearch.client.ClusterAdminClient;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class DeleteLicenseRequestBuilder extends AcknowledgedRequestBuilder<DeleteLicenseRequest, DeleteLicenseResponse, DeleteLicenseRequestBuilder, ClusterAdminClient> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new get licenses request builder
|
||||||
|
*
|
||||||
|
* @param clusterAdminClient cluster admin client
|
||||||
|
*/
|
||||||
|
public DeleteLicenseRequestBuilder(ClusterAdminClient clusterAdminClient) {
|
||||||
|
super(clusterAdminClient, new DeleteLicenseRequest());
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeleteLicenseRequestBuilder setFeatures(Set<String> features) {
|
||||||
|
request.features(features);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doExecute(ActionListener<DeleteLicenseResponse> listener) {
|
||||||
|
client.execute(DeleteLicenseAction.INSTANCE, request, listener);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.license.plugin.action.delete;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.support.master.AcknowledgedResponse;
|
||||||
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class DeleteLicenseResponse extends AcknowledgedResponse {
|
||||||
|
|
||||||
|
DeleteLicenseResponse() {
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteLicenseResponse(boolean acknowledged) {
|
||||||
|
super(acknowledged);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readFrom(StreamInput in) throws IOException {
|
||||||
|
super.readFrom(in);
|
||||||
|
readAcknowledged(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
|
super.writeTo(out);
|
||||||
|
writeAcknowledged(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.license.plugin.action.delete;
|
||||||
|
|
||||||
|
import org.elasticsearch.ElasticsearchException;
|
||||||
|
import org.elasticsearch.action.ActionListener;
|
||||||
|
import org.elasticsearch.action.support.ActionFilters;
|
||||||
|
import org.elasticsearch.action.support.master.TransportMasterNodeOperationAction;
|
||||||
|
import org.elasticsearch.cluster.ClusterService;
|
||||||
|
import org.elasticsearch.cluster.ClusterState;
|
||||||
|
import org.elasticsearch.cluster.ack.ClusterStateUpdateResponse;
|
||||||
|
import org.elasticsearch.cluster.block.ClusterBlockException;
|
||||||
|
import org.elasticsearch.cluster.block.ClusterBlockLevel;
|
||||||
|
import org.elasticsearch.cluster.metadata.MetaData;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.license.plugin.core.LicensesMetaData;
|
||||||
|
import org.elasticsearch.license.plugin.core.LicensesService;
|
||||||
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
|
public class TransportDeleteLicenseAction extends TransportMasterNodeOperationAction<DeleteLicenseRequest, DeleteLicenseResponse> {
|
||||||
|
|
||||||
|
private final LicensesService licensesService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public TransportDeleteLicenseAction(Settings settings, TransportService transportService, ClusterService clusterService, LicensesService licensesService,
|
||||||
|
ThreadPool threadPool, ActionFilters actionFilters) {
|
||||||
|
super(settings, DeleteLicenseAction.NAME, transportService, clusterService, threadPool, actionFilters);
|
||||||
|
this.licensesService = licensesService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String executor() {
|
||||||
|
return ThreadPool.Names.MANAGEMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DeleteLicenseRequest newRequest() {
|
||||||
|
return new DeleteLicenseRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DeleteLicenseResponse newResponse() {
|
||||||
|
return new DeleteLicenseResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ClusterBlockException checkBlock(DeleteLicenseRequest request, ClusterState state) {
|
||||||
|
//TODO: do the right checkBlock
|
||||||
|
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void masterOperation(final DeleteLicenseRequest request, ClusterState state, final ActionListener<DeleteLicenseResponse> listener) throws ElasticsearchException {
|
||||||
|
MetaData metaData = state.metaData();
|
||||||
|
LicensesMetaData licenses = metaData.custom(LicensesMetaData.TYPE);
|
||||||
|
//listener.onResponse(new DeleteLicenseResponse(licenses));
|
||||||
|
|
||||||
|
//TODO:: add features of the license to be deleted
|
||||||
|
licensesService.unregisteredLicenses("delete_licenses []", request, new ActionListener<ClusterStateUpdateResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(ClusterStateUpdateResponse clusterStateUpdateResponse) {
|
||||||
|
listener.onResponse(new DeleteLicenseResponse(clusterStateUpdateResponse.isAcknowledged()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Throwable e) {
|
||||||
|
listener.onFailure(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,6 @@ import org.elasticsearch.action.ActionResponse;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.license.core.ESLicenses;
|
import org.elasticsearch.license.core.ESLicenses;
|
||||||
import org.elasticsearch.license.plugin.cluster.LicensesMetaData;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,9 @@ 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.MetaData;
|
import org.elasticsearch.cluster.metadata.MetaData;
|
||||||
import org.elasticsearch.cluster.metadata.RepositoriesMetaData;
|
|
||||||
import org.elasticsearch.cluster.metadata.RepositoryMetaData;
|
|
||||||
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.cluster.LicensesMetaData;
|
import org.elasticsearch.license.plugin.core.LicensesMetaData;
|
||||||
import org.elasticsearch.repositories.RepositoryMissingException;
|
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ import org.elasticsearch.cluster.block.ClusterBlockException;
|
||||||
import org.elasticsearch.cluster.block.ClusterBlockLevel;
|
import org.elasticsearch.cluster.block.ClusterBlockLevel;
|
||||||
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.service.LicensesService;
|
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;
|
||||||
|
|
||||||
|
|
|
@ -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.cluster;
|
package org.elasticsearch.license.plugin.core;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
import org.elasticsearch.ElasticsearchParseException;
|
||||||
import org.elasticsearch.cluster.metadata.MetaData;
|
import org.elasticsearch.cluster.metadata.MetaData;
|
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.license.plugin.core;
|
||||||
|
|
||||||
|
import org.elasticsearch.ElasticsearchException;
|
||||||
|
import org.elasticsearch.action.ActionListener;
|
||||||
|
import org.elasticsearch.cluster.*;
|
||||||
|
import org.elasticsearch.cluster.ack.ClusterStateUpdateRequest;
|
||||||
|
import org.elasticsearch.cluster.ack.ClusterStateUpdateResponse;
|
||||||
|
import org.elasticsearch.cluster.metadata.MetaData;
|
||||||
|
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||||
|
import org.elasticsearch.common.component.AbstractLifecycleComponent;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.inject.Injector;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.license.core.LicenseBuilders;
|
||||||
|
import org.elasticsearch.license.plugin.action.delete.DeleteLicenseRequest;
|
||||||
|
import org.elasticsearch.license.plugin.action.put.PutLicenseRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service responsible for maintaining and providing access to licenses on nodes.
|
||||||
|
*
|
||||||
|
* TODO: Work in progress:
|
||||||
|
* - implement logic in clusterChanged
|
||||||
|
* - interface with LicenseManager
|
||||||
|
*/
|
||||||
|
public class LicensesService extends AbstractLifecycleComponent<LicensesService> implements ClusterStateListener {
|
||||||
|
|
||||||
|
private final Injector injector;
|
||||||
|
|
||||||
|
private final ClusterService clusterService;
|
||||||
|
|
||||||
|
//private volatile ESLicenses licenses = null;//ImmutableMap.of();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public LicensesService(Settings settings, ClusterService clusterService, Injector injector) {
|
||||||
|
super(settings);
|
||||||
|
this.injector = injector;
|
||||||
|
this.clusterService = clusterService;
|
||||||
|
// Doesn't make sense to maintain repositories on non-master and non-data nodes
|
||||||
|
// Nothing happens there anyway
|
||||||
|
if (DiscoveryNode.dataNode(settings) || DiscoveryNode.masterNode(settings)) {
|
||||||
|
clusterService.add(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers new licenses in the cluster
|
||||||
|
* <p/>
|
||||||
|
* This method can be only called on the master node. It tries to create a new licenses on the master
|
||||||
|
* and if it was successful it adds the license to cluster metadata.
|
||||||
|
*/
|
||||||
|
public void registerLicenses(final String source, final PutLicenseRequest request, final ActionListener<ClusterStateUpdateResponse> listener) {
|
||||||
|
final LicensesMetaData newLicenseMetaData = new LicensesMetaData(request.license());
|
||||||
|
//TODO: add a source field to request
|
||||||
|
clusterService.submitStateUpdateTask(source, new AckedClusterStateUpdateTask<ClusterStateUpdateResponse>(request, listener) {
|
||||||
|
@Override
|
||||||
|
protected ClusterStateUpdateResponse newResponse(boolean acknowledged) {
|
||||||
|
return new ClusterStateUpdateResponse(acknowledged);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClusterState execute(ClusterState currentState) throws Exception {
|
||||||
|
// TODO check if newLicenseMetaData actually needs a cluster update
|
||||||
|
MetaData metaData = currentState.metaData();
|
||||||
|
MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData());
|
||||||
|
LicensesMetaData currentLicenses = metaData.custom(LicensesMetaData.TYPE);
|
||||||
|
|
||||||
|
if (currentLicenses == null) {
|
||||||
|
// no licenses were registered
|
||||||
|
currentLicenses = newLicenseMetaData;
|
||||||
|
} else {
|
||||||
|
// merge previous license with new one
|
||||||
|
currentLicenses = new LicensesMetaData(LicenseBuilders.merge(currentLicenses, newLicenseMetaData));
|
||||||
|
}
|
||||||
|
mdBuilder.putCustom(LicensesMetaData.TYPE, currentLicenses);
|
||||||
|
return ClusterState.builder(currentState).metaData(mdBuilder).build();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
public void unregisteredLicenses(final String source, final DeleteLicenseRequest request, final ActionListener<ClusterStateUpdateResponse> listener) {
|
||||||
|
clusterService.submitStateUpdateTask(source, new AckedClusterStateUpdateTask<ClusterStateUpdateResponse>(request, listener) {
|
||||||
|
@Override
|
||||||
|
protected ClusterStateUpdateResponse newResponse(boolean acknowledged) {
|
||||||
|
return new ClusterStateUpdateResponse(acknowledged);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClusterState execute(ClusterState currentState) throws Exception {
|
||||||
|
// TODO check if newLicenseMetaData actually needs a cluster update
|
||||||
|
MetaData metaData = currentState.metaData();
|
||||||
|
MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData());
|
||||||
|
LicensesMetaData currentLicenses = metaData.custom(LicensesMetaData.TYPE);
|
||||||
|
|
||||||
|
//TODO: implement deletion
|
||||||
|
if (currentLicenses == null) {
|
||||||
|
// no licenses were registered
|
||||||
|
//currentLicenses = newLicenseMetaData;
|
||||||
|
} else {
|
||||||
|
// merge previous license with new one
|
||||||
|
//currentLicenses = new LicensesMetaData(LicenseBuilders.merge(currentLicenses, newLicenseMetaData));
|
||||||
|
}
|
||||||
|
mdBuilder.putCustom(LicensesMetaData.TYPE, currentLicenses);
|
||||||
|
return ClusterState.builder(currentState).metaData(mdBuilder).build();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doStart() throws ElasticsearchException {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doStop() throws ElasticsearchException {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doClose() throws ElasticsearchException {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clusterChanged(ClusterChangedEvent event) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.license.plugin.rest;
|
||||||
|
|
||||||
|
import org.elasticsearch.client.Client;
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.license.core.ESLicenses;
|
||||||
|
import org.elasticsearch.license.plugin.action.delete.DeleteLicenseAction;
|
||||||
|
import org.elasticsearch.license.plugin.action.delete.DeleteLicenseRequest;
|
||||||
|
import org.elasticsearch.license.plugin.action.delete.DeleteLicenseResponse;
|
||||||
|
import org.elasticsearch.license.plugin.action.delete.TransportDeleteLicenseAction;
|
||||||
|
import org.elasticsearch.license.plugin.action.put.PutLicenseRequest;
|
||||||
|
import org.elasticsearch.license.plugin.action.put.PutLicenseResponse;
|
||||||
|
import org.elasticsearch.license.plugin.action.put.TransportPutLicenseAction;
|
||||||
|
import org.elasticsearch.rest.BaseRestHandler;
|
||||||
|
import org.elasticsearch.rest.RestChannel;
|
||||||
|
import org.elasticsearch.rest.RestController;
|
||||||
|
import org.elasticsearch.rest.RestRequest;
|
||||||
|
import org.elasticsearch.rest.action.support.AcknowledgedRestListener;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.elasticsearch.license.core.ESLicenses.FeatureType;
|
||||||
|
import static org.elasticsearch.rest.RestRequest.Method.DELETE;
|
||||||
|
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
||||||
|
import static org.elasticsearch.rest.RestRequest.Method.PUT;
|
||||||
|
|
||||||
|
public class RestDeleteLicenseAction extends BaseRestHandler {
|
||||||
|
|
||||||
|
private final TransportDeleteLicenseAction transportDeleteLicenseAction;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public RestDeleteLicenseAction(Settings settings, RestController controller, Client client, TransportDeleteLicenseAction transportDeleteLicenseAction) {
|
||||||
|
super(settings, controller, client);
|
||||||
|
controller.registerHandler(DELETE, "/_cluster/license/", this);
|
||||||
|
controller.registerHandler(DELETE, "/_cluster/license/{features}", this);
|
||||||
|
this.transportDeleteLicenseAction = transportDeleteLicenseAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) {
|
||||||
|
final String[] features = Strings.splitStringByCommaToArray(request.param("features"));
|
||||||
|
|
||||||
|
DeleteLicenseRequest deleteLicenseRequest = new DeleteLicenseRequest(getFeaturesToDelete(features));
|
||||||
|
deleteLicenseRequest.listenerThreaded(false);
|
||||||
|
//deleteLicenseRequest.license(request.content().toUtf8());
|
||||||
|
transportDeleteLicenseAction.execute(deleteLicenseRequest, new AcknowledgedRestListener<DeleteLicenseResponse>(channel));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String[] getFeaturesToDelete(String[] features) {
|
||||||
|
Set<String> result = new HashSet<>();
|
||||||
|
for (String feature : features) {
|
||||||
|
if (feature.equalsIgnoreCase("_all")) {
|
||||||
|
for (FeatureType featureType : FeatureType.values()) {
|
||||||
|
result.add(featureType.string());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
result.add(FeatureType.fromString(feature).string());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toArray(new String[result.size()]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ import org.elasticsearch.license.core.ESLicenses;
|
||||||
import org.elasticsearch.license.plugin.action.get.GetLicenseAction;
|
import org.elasticsearch.license.plugin.action.get.GetLicenseAction;
|
||||||
import org.elasticsearch.license.plugin.action.get.GetLicenseRequest;
|
import org.elasticsearch.license.plugin.action.get.GetLicenseRequest;
|
||||||
import org.elasticsearch.license.plugin.action.get.GetLicenseResponse;
|
import org.elasticsearch.license.plugin.action.get.GetLicenseResponse;
|
||||||
|
import org.elasticsearch.license.plugin.action.get.TransportGetLicenseAction;
|
||||||
import org.elasticsearch.rest.*;
|
import org.elasticsearch.rest.*;
|
||||||
import org.elasticsearch.rest.action.support.AcknowledgedRestListener;
|
import org.elasticsearch.rest.action.support.AcknowledgedRestListener;
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
||||||
|
@ -27,17 +28,18 @@ import static org.elasticsearch.rest.RestStatus.OK;
|
||||||
|
|
||||||
public class RestGetLicenseAction extends BaseRestHandler {
|
public class RestGetLicenseAction extends BaseRestHandler {
|
||||||
|
|
||||||
|
private final TransportGetLicenseAction transportGetLicenseAction;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RestGetLicenseAction(Settings settings, RestController controller, Client client) {
|
public RestGetLicenseAction(Settings settings, RestController controller, Client client, TransportGetLicenseAction transportGetLicenseAction) {
|
||||||
super(settings, controller, client);
|
super(settings, controller, client);
|
||||||
controller.registerHandler(GET, "/_cluster/license", this);
|
controller.registerHandler(GET, "/_cluster/license", this);
|
||||||
|
this.transportGetLicenseAction = transportGetLicenseAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) {
|
public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) {
|
||||||
GetLicenseRequest getLicenseRequest = new GetLicenseRequest();
|
transportGetLicenseAction.execute(new GetLicenseRequest(), new RestBuilderListener<GetLicenseResponse>(channel) {
|
||||||
|
|
||||||
client.admin().cluster().execute(GetLicenseAction.INSTANCE, getLicenseRequest, new RestBuilderListener<GetLicenseResponse>(channel) {
|
|
||||||
@Override
|
@Override
|
||||||
public RestResponse buildResponse(GetLicenseResponse getLicenseResponse, XContentBuilder builder) throws Exception {
|
public RestResponse buildResponse(GetLicenseResponse getLicenseResponse, XContentBuilder builder) throws Exception {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
|
@ -50,5 +52,6 @@ public class RestGetLicenseAction extends BaseRestHandler {
|
||||||
return new BytesRestResponse(OK, builder);
|
return new BytesRestResponse(OK, builder);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
//client.admin().cluster().execute(GetLicenseAction.INSTANCE, getLicenseRequest, )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.license.plugin.action.put.PutLicenseAction;
|
import org.elasticsearch.license.plugin.action.put.PutLicenseAction;
|
||||||
import org.elasticsearch.license.plugin.action.put.PutLicenseRequest;
|
import org.elasticsearch.license.plugin.action.put.PutLicenseRequest;
|
||||||
import org.elasticsearch.license.plugin.action.put.PutLicenseResponse;
|
import org.elasticsearch.license.plugin.action.put.PutLicenseResponse;
|
||||||
|
import org.elasticsearch.license.plugin.action.put.TransportPutLicenseAction;
|
||||||
import org.elasticsearch.rest.BaseRestHandler;
|
import org.elasticsearch.rest.BaseRestHandler;
|
||||||
import org.elasticsearch.rest.RestChannel;
|
import org.elasticsearch.rest.RestChannel;
|
||||||
import org.elasticsearch.rest.RestController;
|
import org.elasticsearch.rest.RestController;
|
||||||
|
@ -22,11 +23,14 @@ import static org.elasticsearch.rest.RestRequest.Method.PUT;
|
||||||
|
|
||||||
public class RestPutLicenseAction extends BaseRestHandler {
|
public class RestPutLicenseAction extends BaseRestHandler {
|
||||||
|
|
||||||
|
private final TransportPutLicenseAction transportPutLicensesAction;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RestPutLicenseAction(Settings settings, RestController controller, Client client) {
|
public RestPutLicenseAction(Settings settings, RestController controller, Client client, TransportPutLicenseAction transportPutLicenseAction) {
|
||||||
super(settings, controller, client);
|
super(settings, controller, client);
|
||||||
controller.registerHandler(PUT, "/_cluster/license", this);
|
controller.registerHandler(PUT, "/_cluster/license", this);
|
||||||
controller.registerHandler(POST, "/_cluster/license", this);
|
controller.registerHandler(POST, "/_cluster/license", this);
|
||||||
|
this.transportPutLicensesAction = transportPutLicenseAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,6 +39,7 @@ public class RestPutLicenseAction extends BaseRestHandler {
|
||||||
PutLicenseRequest putLicenseRequest = new PutLicenseRequest();
|
PutLicenseRequest putLicenseRequest = new PutLicenseRequest();
|
||||||
putLicenseRequest.listenerThreaded(false);
|
putLicenseRequest.listenerThreaded(false);
|
||||||
putLicenseRequest.license(request.content().toUtf8());
|
putLicenseRequest.license(request.content().toUtf8());
|
||||||
client.admin().cluster().execute(PutLicenseAction.INSTANCE, putLicenseRequest, new AcknowledgedRestListener<PutLicenseResponse>(channel));
|
transportPutLicensesAction.execute(putLicenseRequest, new AcknowledgedRestListener<PutLicenseResponse>(channel));
|
||||||
|
// client.admin().cluster().execute(PutLicenseAction.INSTANCE, putLicenseRequest, );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,454 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.license.plugin.service;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
|
||||||
import org.elasticsearch.cluster.*;
|
|
||||||
import org.elasticsearch.cluster.ack.ClusterStateUpdateRequest;
|
|
||||||
import org.elasticsearch.cluster.ack.ClusterStateUpdateResponse;
|
|
||||||
import org.elasticsearch.cluster.metadata.MetaData;
|
|
||||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.inject.Injector;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.license.core.ESLicenses;
|
|
||||||
import org.elasticsearch.license.core.LicenseBuilders;
|
|
||||||
import org.elasticsearch.license.plugin.action.put.PutLicenseRequest;
|
|
||||||
import org.elasticsearch.license.plugin.cluster.LicensesMetaData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Service responsible for maintaining and providing access to licenses on nodes.
|
|
||||||
*
|
|
||||||
* TODO: Work in progress:
|
|
||||||
* - implement logic in clusterChanged
|
|
||||||
* - interface with LicenseManager
|
|
||||||
*/
|
|
||||||
public class LicensesService extends AbstractComponent implements ClusterStateListener {
|
|
||||||
|
|
||||||
// private final RepositoryTypesRegistry typesRegistry;
|
|
||||||
|
|
||||||
private final Injector injector;
|
|
||||||
|
|
||||||
private final ClusterService clusterService;
|
|
||||||
|
|
||||||
//private volatile ESLicenses licenses = null;//ImmutableMap.of();
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public LicensesService(Settings settings, ClusterService clusterService, Injector injector) {
|
|
||||||
super(settings);
|
|
||||||
this.injector = injector;
|
|
||||||
this.clusterService = clusterService;
|
|
||||||
// Doesn't make sense to maintain repositories on non-master and non-data nodes
|
|
||||||
// Nothing happens there anyway
|
|
||||||
if (DiscoveryNode.dataNode(settings) || DiscoveryNode.masterNode(settings)) {
|
|
||||||
clusterService.add(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers new repository in the cluster
|
|
||||||
* <p/>
|
|
||||||
* This method can be only called on the master node. It tries to create a new repository on the master
|
|
||||||
* and if it was successful it adds new repository to cluster metadata.
|
|
||||||
*
|
|
||||||
* @param request register repository request
|
|
||||||
* @param listener register repository listener
|
|
||||||
*/
|
|
||||||
public void registerLicenses(final String source, final PutLicenseRequest request, final ActionListener<ClusterStateUpdateResponse> listener) {
|
|
||||||
final LicensesMetaData newLicenseMetaData = new LicensesMetaData(request.license());
|
|
||||||
//TODO: add a source field to request
|
|
||||||
clusterService.submitStateUpdateTask(source, new AckedClusterStateUpdateTask<ClusterStateUpdateResponse>(request, listener) {
|
|
||||||
@Override
|
|
||||||
protected ClusterStateUpdateResponse newResponse(boolean acknowledged) {
|
|
||||||
return new ClusterStateUpdateResponse(acknowledged);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClusterState execute(ClusterState currentState) throws Exception {
|
|
||||||
// TODO check if newLicenseMetaData actually needs a cluster update
|
|
||||||
MetaData metaData = currentState.metaData();
|
|
||||||
MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData());
|
|
||||||
LicensesMetaData currentLicenses = metaData.custom(LicensesMetaData.TYPE);
|
|
||||||
|
|
||||||
if (currentLicenses == null) {
|
|
||||||
// no licenses were registered
|
|
||||||
currentLicenses = newLicenseMetaData;
|
|
||||||
} else {
|
|
||||||
// merge previous license with new one
|
|
||||||
currentLicenses = new LicensesMetaData(LicenseBuilders.merge(currentLicenses, newLicenseMetaData));
|
|
||||||
}
|
|
||||||
mdBuilder.putCustom(LicensesMetaData.TYPE, currentLicenses);
|
|
||||||
return ClusterState.builder(currentState).metaData(mdBuilder).build();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
|
||||||
final RepositoryMetaData newRepositoryMetaData = new RepositoryMetaData(request.name, request.type, request.settings);
|
|
||||||
|
|
||||||
clusterService.submitStateUpdateTask(request.cause, new AckedClusterStateUpdateTask<ClusterStateUpdateResponse>(request, listener) {
|
|
||||||
@Override
|
|
||||||
protected ClusterStateUpdateResponse newResponse(boolean acknowledged) {
|
|
||||||
return new ClusterStateUpdateResponse(acknowledged);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClusterState execute(ClusterState currentState) {
|
|
||||||
ensureRepositoryNotInUse(currentState, request.name);
|
|
||||||
// Trying to create the new repository on master to make sure it works
|
|
||||||
if (!registerLicenses(newRepositoryMetaData)) {
|
|
||||||
// The new repository has the same settings as the old one - ignore
|
|
||||||
return currentState;
|
|
||||||
}
|
|
||||||
MetaData metaData = currentState.metaData();
|
|
||||||
MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData());
|
|
||||||
RepositoriesMetaData repositories = metaData.custom(RepositoriesMetaData.TYPE);
|
|
||||||
if (repositories == null) {
|
|
||||||
logger.info("put repository [{}]", request.name);
|
|
||||||
repositories = new RepositoriesMetaData(new RepositoryMetaData(request.name, request.type, request.settings));
|
|
||||||
} else {
|
|
||||||
boolean found = false;
|
|
||||||
List<RepositoryMetaData> repositoriesMetaData = new ArrayList<>(repositories.repositories().size() + 1);
|
|
||||||
|
|
||||||
for (RepositoryMetaData repositoryMetaData : repositories.repositories()) {
|
|
||||||
if (repositoryMetaData.name().equals(newRepositoryMetaData.name())) {
|
|
||||||
found = true;
|
|
||||||
repositoriesMetaData.add(newRepositoryMetaData);
|
|
||||||
} else {
|
|
||||||
repositoriesMetaData.add(repositoryMetaData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
logger.info("put repository [{}]", request.name);
|
|
||||||
repositoriesMetaData.add(new RepositoryMetaData(request.name, request.type, request.settings));
|
|
||||||
} else {
|
|
||||||
logger.info("update repository [{}]", request.name);
|
|
||||||
}
|
|
||||||
repositories = new RepositoriesMetaData(repositoriesMetaData.toArray(new RepositoryMetaData[repositoriesMetaData.size()]));
|
|
||||||
}
|
|
||||||
mdBuilder.putCustom(RepositoriesMetaData.TYPE, repositories);
|
|
||||||
return ClusterState.builder(currentState).metaData(mdBuilder).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(String source, Throwable t) {
|
|
||||||
logger.warn("failed to create repository [{}]", t, request.name);
|
|
||||||
super.onFailure(source, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean mustAck(DiscoveryNode discoveryNode) {
|
|
||||||
return discoveryNode.masterNode();
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregisters repository in the cluster
|
|
||||||
* <p/>
|
|
||||||
* This method can be only called on the master node. It removes repository information from cluster metadata.
|
|
||||||
*
|
|
||||||
* @param request unregister repository request
|
|
||||||
* @param listener unregister repository listener
|
|
||||||
*/
|
|
||||||
public void unregisterRepository(final UnregisterRepositoryRequest request, final ActionListener<ClusterStateUpdateResponse> listener) {
|
|
||||||
/*
|
|
||||||
clusterService.submitStateUpdateTask(request.cause, new AckedClusterStateUpdateTask<ClusterStateUpdateResponse>(request, listener) {
|
|
||||||
@Override
|
|
||||||
protected ClusterStateUpdateResponse newResponse(boolean acknowledged) {
|
|
||||||
return new ClusterStateUpdateResponse(acknowledged);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClusterState execute(ClusterState currentState) {
|
|
||||||
ensureRepositoryNotInUse(currentState, request.name);
|
|
||||||
MetaData metaData = currentState.metaData();
|
|
||||||
MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData());
|
|
||||||
RepositoriesMetaData repositories = metaData.custom(RepositoriesMetaData.TYPE);
|
|
||||||
if (repositories != null && repositories.repositories().size() > 0) {
|
|
||||||
List<RepositoryMetaData> repositoriesMetaData = new ArrayList<>(repositories.repositories().size());
|
|
||||||
boolean changed = false;
|
|
||||||
for (RepositoryMetaData repositoryMetaData : repositories.repositories()) {
|
|
||||||
if (Regex.simpleMatch(request.name, repositoryMetaData.name())) {
|
|
||||||
logger.info("delete repository [{}]", repositoryMetaData.name());
|
|
||||||
changed = true;
|
|
||||||
} else {
|
|
||||||
repositoriesMetaData.add(repositoryMetaData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (changed) {
|
|
||||||
repositories = new RepositoriesMetaData(repositoriesMetaData.toArray(new RepositoryMetaData[repositoriesMetaData.size()]));
|
|
||||||
mdBuilder.putCustom(RepositoriesMetaData.TYPE, repositories);
|
|
||||||
return ClusterState.builder(currentState).metaData(mdBuilder).build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new RepositoryMissingException(request.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean mustAck(DiscoveryNode discoveryNode) {
|
|
||||||
// Since operation occurs only on masters, it's enough that only master-eligible nodes acked
|
|
||||||
return discoveryNode.masterNode();
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if new repositories appeared in or disappeared from cluster metadata and updates current list of
|
|
||||||
* repositories accordingly.
|
|
||||||
*
|
|
||||||
* @param event cluster changed event
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void clusterChanged(ClusterChangedEvent event) {
|
|
||||||
/*
|
|
||||||
try {
|
|
||||||
RepositoriesMetaData oldMetaData = event.previousState().getMetaData().custom(RepositoriesMetaData.TYPE);
|
|
||||||
RepositoriesMetaData newMetaData = event.state().getMetaData().custom(RepositoriesMetaData.TYPE);
|
|
||||||
|
|
||||||
// Check if repositories got changed
|
|
||||||
if ((oldMetaData == null && newMetaData == null) || (oldMetaData != null && oldMetaData.equals(newMetaData))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.trace("processing new index repositories for state version [{}]", event.state().version());
|
|
||||||
|
|
||||||
Map<String, RepositoryHolder> survivors = newHashMap();
|
|
||||||
// First, remove repositories that are no longer there
|
|
||||||
for (Map.Entry<String, RepositoryHolder> entry : repositories.entrySet()) {
|
|
||||||
if (newMetaData == null || newMetaData.repository(entry.getKey()) == null) {
|
|
||||||
logger.debug("unregistering repository [{}]", entry.getKey());
|
|
||||||
closeRepository(entry.getKey(), entry.getValue());
|
|
||||||
} else {
|
|
||||||
survivors.put(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImmutableMap.Builder<String, RepositoryHolder> builder = ImmutableMap.builder();
|
|
||||||
if (newMetaData != null) {
|
|
||||||
// Now go through all repositories and update existing or create missing
|
|
||||||
for (RepositoryMetaData repositoryMetaData : newMetaData.repositories()) {
|
|
||||||
RepositoryHolder holder = survivors.get(repositoryMetaData.name());
|
|
||||||
if (holder != null) {
|
|
||||||
// Found previous version of this repository
|
|
||||||
if (!holder.type.equals(repositoryMetaData.type()) || !holder.settings.equals(repositoryMetaData.settings())) {
|
|
||||||
// Previous version is different from the version in settings
|
|
||||||
logger.debug("updating repository [{}]", repositoryMetaData.name());
|
|
||||||
closeRepository(repositoryMetaData.name(), holder);
|
|
||||||
holder = createRepositoryHolder(repositoryMetaData);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
holder = createRepositoryHolder(repositoryMetaData);
|
|
||||||
}
|
|
||||||
if (holder != null) {
|
|
||||||
logger.debug("registering repository [{}]", repositoryMetaData.name());
|
|
||||||
builder.put(repositoryMetaData.name(), holder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
repositories = builder.build();
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
logger.warn("failure updating cluster state ", ex);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns registered repository
|
|
||||||
* <p/>
|
|
||||||
* This method is called only on the master node
|
|
||||||
*
|
|
||||||
* @param repository repository name
|
|
||||||
* @return registered repository
|
|
||||||
* @throws RepositoryMissingException if repository with such name isn't registered
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
public Repository repository(String repository) {
|
|
||||||
RepositoryHolder holder = repositories.get(repository);
|
|
||||||
if (holder != null) {
|
|
||||||
return holder.repository;
|
|
||||||
}
|
|
||||||
throw new RepositoryMissingException(repository);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns registered index shard repository
|
|
||||||
* <p/>
|
|
||||||
* This method is called only on data nodes
|
|
||||||
*
|
|
||||||
* @param repository repository name
|
|
||||||
* @return registered repository
|
|
||||||
* @throws RepositoryMissingException if repository with such name isn't registered
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
public IndexShardRepository indexShardRepository(String repository) {
|
|
||||||
RepositoryHolder holder = repositories.get(repository);
|
|
||||||
if (holder != null) {
|
|
||||||
return holder.indexShardRepository;
|
|
||||||
}
|
|
||||||
throw new RepositoryMissingException(repository);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new repository and adds it to the list of registered repositories.
|
|
||||||
* <p/>
|
|
||||||
* If a repository with the same name but different types or settings already exists, it will be closed and
|
|
||||||
* replaced with the new repository. If a repository with the same name exists but it has the same type and settings
|
|
||||||
* the new repository is ignored.
|
|
||||||
*
|
|
||||||
* @param repositoryMetaData new repository metadata
|
|
||||||
* @return {@code true} if new repository was added or {@code false} if it was ignored
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
private boolean registerLicenses(RepositoryMetaData repositoryMetaData) {
|
|
||||||
RepositoryHolder previous = repositories.get(repositoryMetaData.name());
|
|
||||||
if (previous != null) {
|
|
||||||
if (!previous.type.equals(repositoryMetaData.type()) && previous.settings.equals(repositoryMetaData.settings())) {
|
|
||||||
// Previous version is the same as this one - ignore it
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RepositoryHolder holder = createRepositoryHolder(repositoryMetaData);
|
|
||||||
if (previous != null) {
|
|
||||||
// Closing previous version
|
|
||||||
closeRepository(repositoryMetaData.name(), previous);
|
|
||||||
}
|
|
||||||
Map<String, RepositoryHolder> newRepositories = newHashMap(repositories);
|
|
||||||
newRepositories.put(repositoryMetaData.name(), holder);
|
|
||||||
repositories = ImmutableMap.copyOf(newRepositories);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Closes the repository
|
|
||||||
*
|
|
||||||
* @param name repository name
|
|
||||||
* @param holder repository holder
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
private void closeRepository(String name, RepositoryHolder holder) {
|
|
||||||
logger.debug("closing repository [{}][{}]", holder.type, name);
|
|
||||||
if (holder.injector != null) {
|
|
||||||
Injectors.close(holder.injector);
|
|
||||||
}
|
|
||||||
if (holder.repository != null) {
|
|
||||||
holder.repository.close();
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates repository holder
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
private RepositoryHolder createRepositoryHolder(RepositoryMetaData repositoryMetaData) {
|
|
||||||
logger.debug("creating repository [{}][{}]", repositoryMetaData.type(), repositoryMetaData.name());
|
|
||||||
Injector repositoryInjector = null;
|
|
||||||
try {
|
|
||||||
ModulesBuilder modules = new ModulesBuilder();
|
|
||||||
RepositoryName name = new RepositoryName(repositoryMetaData.type(), repositoryMetaData.name());
|
|
||||||
modules.add(new RepositoryNameModule(name));
|
|
||||||
modules.add(new RepositoryModule(name, repositoryMetaData.settings(), this.settings, typesRegistry));
|
|
||||||
|
|
||||||
repositoryInjector = modules.createChildInjector(injector);
|
|
||||||
Repository repository = repositoryInjector.getInstance(Repository.class);
|
|
||||||
IndexShardRepository indexShardRepository = repositoryInjector.getInstance(IndexShardRepository.class);
|
|
||||||
repository.start();
|
|
||||||
return new RepositoryHolder(repositoryMetaData.type(), repositoryMetaData.settings(), repositoryInjector, repository, indexShardRepository);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
if (repositoryInjector != null) {
|
|
||||||
Injectors.close(repositoryInjector);
|
|
||||||
}
|
|
||||||
logger.warn("failed to create repository [{}][{}]", t, repositoryMetaData.type(), repositoryMetaData.name());
|
|
||||||
throw new RepositoryException(repositoryMetaData.name(), "failed to create repository", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ensureRepositoryNotInUse(ClusterState clusterState, String repository) {
|
|
||||||
if (SnapshotsService.isRepositoryInUse(clusterState, repository) || RestoreService.isRepositoryInUse(clusterState, repository)) {
|
|
||||||
throw new ElasticsearchIllegalStateException("trying to modify or unregister repository that is currently used ");
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal data structure for holding repository with its configuration information and injector
|
|
||||||
*/
|
|
||||||
/* private static class RepositoryHolder {
|
|
||||||
|
|
||||||
private final String type;
|
|
||||||
private final Settings settings;
|
|
||||||
private final Injector injector;
|
|
||||||
private final Repository repository;
|
|
||||||
private final IndexShardRepository indexShardRepository;
|
|
||||||
|
|
||||||
public RepositoryHolder(String type, Settings settings, Injector injector, Repository repository, IndexShardRepository indexShardRepository) {
|
|
||||||
this.type = type;
|
|
||||||
this.settings = settings;
|
|
||||||
this.repository = repository;
|
|
||||||
this.indexShardRepository = indexShardRepository;
|
|
||||||
this.injector = injector;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Register repository request
|
|
||||||
*/
|
|
||||||
public static class RegisterRepositoryRequest extends ClusterStateUpdateRequest<RegisterRepositoryRequest> {
|
|
||||||
|
|
||||||
final String cause;
|
|
||||||
|
|
||||||
final String name;
|
|
||||||
|
|
||||||
final String type;
|
|
||||||
|
|
||||||
Settings settings = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs new register repository request
|
|
||||||
*
|
|
||||||
* @param cause repository registration cause
|
|
||||||
* @param name repository name
|
|
||||||
* @param type repository type
|
|
||||||
*/
|
|
||||||
public RegisterRepositoryRequest(String cause, String name, String type) {
|
|
||||||
this.cause = cause;
|
|
||||||
this.name = name;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets repository settings
|
|
||||||
*
|
|
||||||
* @param settings repository settings
|
|
||||||
* @return this request
|
|
||||||
*/
|
|
||||||
public RegisterRepositoryRequest settings(Settings settings) {
|
|
||||||
this.settings = settings;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregister repository request
|
|
||||||
*/
|
|
||||||
public static class UnregisterRepositoryRequest extends ClusterStateUpdateRequest<UnregisterRepositoryRequest> {
|
|
||||||
|
|
||||||
final String cause;
|
|
||||||
|
|
||||||
final String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new unregister repository request
|
|
||||||
*
|
|
||||||
* @param cause repository unregistration cause
|
|
||||||
* @param name repository name
|
|
||||||
*/
|
|
||||||
public UnregisterRepositoryRequest(String cause, String name) {
|
|
||||||
this.cause = cause;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,38 +6,67 @@
|
||||||
package org.elasticsearch.license.plugin;
|
package org.elasticsearch.license.plugin;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionFuture;
|
import org.elasticsearch.action.ActionFuture;
|
||||||
|
import org.elasticsearch.action.ActionModule;
|
||||||
|
import org.elasticsearch.client.transport.TransportClient;
|
||||||
import org.elasticsearch.cluster.metadata.MetaData;
|
import org.elasticsearch.cluster.metadata.MetaData;
|
||||||
|
import org.elasticsearch.common.collect.ImmutableSet;
|
||||||
|
import org.elasticsearch.common.component.LifecycleComponent;
|
||||||
|
import org.elasticsearch.common.inject.Injector;
|
||||||
|
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.license.TestUtils;
|
import org.elasticsearch.license.TestUtils;
|
||||||
import org.elasticsearch.license.core.ESLicenses;
|
import org.elasticsearch.license.core.ESLicenses;
|
||||||
|
import org.elasticsearch.license.core.LicenseUtils;
|
||||||
import org.elasticsearch.license.licensor.tools.KeyPairGeneratorTool;
|
import org.elasticsearch.license.licensor.tools.KeyPairGeneratorTool;
|
||||||
|
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.license.plugin.action.get.TransportGetLicenseAction;
|
||||||
import org.elasticsearch.license.plugin.action.put.PutLicenseAction;
|
import org.elasticsearch.license.plugin.action.put.PutLicenseAction;
|
||||||
import org.elasticsearch.license.plugin.action.put.PutLicenseRequest;
|
import org.elasticsearch.license.plugin.action.put.PutLicenseRequest;
|
||||||
import org.elasticsearch.license.plugin.action.put.PutLicenseResponse;
|
import org.elasticsearch.license.plugin.action.put.PutLicenseResponse;
|
||||||
import org.elasticsearch.license.plugin.cluster.LicensesMetaData;
|
import org.elasticsearch.license.plugin.action.put.TransportPutLicenseAction;
|
||||||
|
import org.elasticsearch.license.plugin.core.LicensesMetaData;
|
||||||
|
import org.elasticsearch.license.plugin.rest.RestGetLicenseAction;
|
||||||
|
import org.elasticsearch.license.plugin.rest.RestPutLicenseAction;
|
||||||
|
import org.elasticsearch.license.plugin.core.LicensesService;
|
||||||
|
import org.elasticsearch.plugins.AbstractPlugin;
|
||||||
|
import org.elasticsearch.rest.RestModule;
|
||||||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||||
|
import org.elasticsearch.test.InternalTestCluster;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import static org.elasticsearch.test.ElasticsearchIntegrationTest.*;
|
||||||
|
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope.*;
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.CoreMatchers.nullValue;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
@ClusterScope(scope = SUITE, numDataNodes = 10)
|
||||||
public class LicenseTransportTests extends ElasticsearchIntegrationTest {
|
public class LicenseTransportTests extends ElasticsearchIntegrationTest {
|
||||||
|
|
||||||
static {
|
|
||||||
MetaData.registerFactory(LicensesMetaData.TYPE, LicensesMetaData.FACTORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String pubKeyPath = null;
|
private static String pubKeyPath = null;
|
||||||
private static String priKeyPath = null;
|
private static String priKeyPath = null;
|
||||||
private static String keyPass = null;
|
private static String keyPass = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Settings nodeSettings(int nodeOrdinal) {
|
||||||
|
return ImmutableSettings.settingsBuilder()
|
||||||
|
.put("plugins.load_classpath_plugins", false)
|
||||||
|
.put("plugin.types", LicensePlugin.class.getName())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setup() throws IOException {
|
public static void setup() throws IOException {
|
||||||
|
|
||||||
|
@ -63,7 +92,17 @@ public class LicenseTransportTests extends ElasticsearchIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPutLicense() throws ParseException, ExecutionException, InterruptedException {
|
public void testEmptyGetLicense() throws Exception {
|
||||||
|
final ActionFuture<GetLicenseResponse> getLicenseFuture = licenseGetAction().execute(new GetLicenseRequest());
|
||||||
|
|
||||||
|
final GetLicenseResponse getLicenseResponse = getLicenseFuture.get();
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
//assertThat(getLicenseResponse.licenses(), nullValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPutLicense() throws ParseException, ExecutionException, InterruptedException, IOException {
|
||||||
|
|
||||||
Map<ESLicenses.FeatureType, TestUtils.FeatureAttributes> map = new HashMap<>();
|
Map<ESLicenses.FeatureType, TestUtils.FeatureAttributes> map = new HashMap<>();
|
||||||
TestUtils.FeatureAttributes featureAttributes =
|
TestUtils.FeatureAttributes featureAttributes =
|
||||||
|
@ -72,14 +111,46 @@ public class LicenseTransportTests extends ElasticsearchIntegrationTest {
|
||||||
|
|
||||||
String licenseString = TestUtils.generateESLicenses(map);
|
String licenseString = TestUtils.generateESLicenses(map);
|
||||||
|
|
||||||
|
|
||||||
|
String[] args = new String[8];
|
||||||
|
args[0] = "--license";
|
||||||
|
args[1] = licenseString;
|
||||||
|
args[2] = "--publicKeyPath";
|
||||||
|
args[3] = pubKeyPath;
|
||||||
|
args[4] = "--privateKeyPath";
|
||||||
|
args[5] = priKeyPath;
|
||||||
|
args[6] = "--keyPass";
|
||||||
|
args[7] = keyPass;
|
||||||
|
|
||||||
|
String licenseOutput = TestUtils.runLicenseGenerationTool(args);
|
||||||
|
|
||||||
PutLicenseRequest putLicenseRequest = new PutLicenseRequest();
|
PutLicenseRequest putLicenseRequest = new PutLicenseRequest();
|
||||||
putLicenseRequest.license(licenseString);
|
//putLicenseRequest.license(licenseString);
|
||||||
|
final ESLicenses putLicenses = LicenseUtils.readLicensesFromString(licenseOutput);
|
||||||
|
putLicenseRequest.license(putLicenses);
|
||||||
|
LicenseUtils.printLicense(putLicenses);
|
||||||
|
ensureGreen();
|
||||||
|
|
||||||
final ActionFuture<PutLicenseResponse> execute = client().admin().cluster().execute(PutLicenseAction.INSTANCE, putLicenseRequest);
|
final ActionFuture<PutLicenseResponse> putLicenseFuture = licensePutAction().execute(putLicenseRequest);
|
||||||
|
|
||||||
final PutLicenseResponse putLicenseResponse = execute.get();
|
final PutLicenseResponse putLicenseResponse = putLicenseFuture.get();
|
||||||
|
|
||||||
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
|
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
|
||||||
|
|
||||||
|
final ActionFuture<GetLicenseResponse> getLicenseFuture = licenseGetAction().execute(new GetLicenseRequest());
|
||||||
|
|
||||||
|
final GetLicenseResponse getLicenseResponse = getLicenseFuture.get();
|
||||||
|
|
||||||
|
LicenseUtils.printLicense(getLicenseResponse.licenses());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransportGetLicenseAction licenseGetAction() {
|
||||||
|
final InternalTestCluster clients = internalCluster();
|
||||||
|
return clients.getInstance(TransportGetLicenseAction.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransportPutLicenseAction licensePutAction() {
|
||||||
|
final InternalTestCluster clients = internalCluster();
|
||||||
|
return clients.getInstance(TransportPutLicenseAction.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue