Removed redundant tests from the days when license was a separate plugin

Original commit: elastic/x-pack-elasticsearch@def1c5092a
This commit is contained in:
Areek Zillur 2016-07-07 17:38:29 -04:00
parent 57544b8688
commit adce8215ab
16 changed files with 60 additions and 970 deletions

View File

@ -337,7 +337,8 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
if (registeredLicensees.size() > 0) {
return registeredLicensees.get(0).currentLicenseState;
} else {
return getLicenseState(getLicense(), clock.millis());
final License license = getLicense(clusterService.state().metaData().custom(LicensesMetaData.TYPE));
return getLicenseState(license, clock.millis());
}
}
@ -481,6 +482,9 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
}
static LicenseState getLicenseState(final License license, long time) {
if (license == null) {
return LicenseState.DISABLED;
}
if (license.issueDate() > time) {
return LicenseState.DISABLED;
}

View File

@ -1,153 +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;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.gateway.GatewayService;
import org.elasticsearch.license.plugin.consumer.TestConsumerPluginBase;
import org.elasticsearch.license.plugin.consumer.TestPluginServiceBase;
import org.elasticsearch.license.plugin.core.LicenseState;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
import org.elasticsearch.test.InternalTestCluster;
import org.elasticsearch.xpack.XPackPlugin;
import org.junit.After;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import static org.elasticsearch.test.ESIntegTestCase.Scope.TEST;
/**
* Framework to test licensing plugin integration for existing/new consumer plugins
* see {@link org.elasticsearch.license.plugin.LicensesEagerConsumerPluginIntegrationTests}
* and {@link org.elasticsearch.license.plugin.LicensesLazyConsumerPluginIntegrationTests}
* for example usage
*/
@ClusterScope(scope = TEST, numDataNodes = 2, numClientNodes = 0, transportClientRatio = 0.0)
public abstract class AbstractLicensesConsumerPluginIntegrationTestCase extends AbstractLicensesIntegrationTestCase {
protected final TestConsumerPluginBase consumerPlugin;
public AbstractLicensesConsumerPluginIntegrationTestCase(TestConsumerPluginBase consumerPlugin) {
this.consumerPlugin = consumerPlugin;
}
private final int trialLicenseDurationInSeconds = 20;
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
// this setting is only used in tests
.put("_trial_license_duration_in_seconds", trialLicenseDurationInSeconds)
.build();
}
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Arrays.asList(XPackPlugin.class, consumerPlugin.getClass());
}
@Override
protected Collection<Class<? extends Plugin>> transportClientPlugins() {
return nodePlugins();
}
@After
public void afterTest() throws Exception {
wipeAllLicenses();
assertTrue(awaitBusy(() -> !clusterService().state().blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK)));
}
public void testTrialLicenseAndSignedLicenseNotification() throws Exception {
logger.info("using {} consumer plugin", consumerPlugin.getClass().getName());
logger.info(" --> trial license generated");
// managerService should report feature to be enabled on all data nodes
assertLicenseeState(LicenseState.ENABLED);
// consumer plugin service should return enabled on all data nodes
assertConsumerPluginNotification(consumerPluginServices(), LicenseState.ENABLED, 2);
logger.info(" --> check trial license expiry notification");
// consumer plugin should notify onDisabled on all data nodes (expired trial license)
assertConsumerPluginNotification(consumerPluginServices(), LicenseState.GRACE_PERIOD, trialLicenseDurationInSeconds * 2);
assertLicenseeState(LicenseState.GRACE_PERIOD);
assertConsumerPluginNotification(consumerPluginServices(), LicenseState.DISABLED, trialLicenseDurationInSeconds * 2);
assertLicenseeState(LicenseState.DISABLED);
logger.info(" --> put signed license");
putLicense(TimeValue.timeValueSeconds(trialLicenseDurationInSeconds));
logger.info(" --> check signed license enabled notification");
// consumer plugin should notify onEnabled on all data nodes (signed license)
assertConsumerPluginNotification(consumerPluginServices(), LicenseState.ENABLED, 1);
assertLicenseeState(LicenseState.ENABLED);
logger.info(" --> check signed license expiry notification");
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
assertConsumerPluginNotification(consumerPluginServices(), LicenseState.GRACE_PERIOD, trialLicenseDurationInSeconds * 2);
assertLicenseeState(LicenseState.GRACE_PERIOD);
assertConsumerPluginNotification(consumerPluginServices(), LicenseState.DISABLED, trialLicenseDurationInSeconds * 2);
assertLicenseeState(LicenseState.DISABLED);
}
public void testTrialLicenseNotification() throws Exception {
logger.info(" --> check onEnabled for trial license");
// managerService should report feature to be enabled on all data nodes
assertLicenseeState(LicenseState.ENABLED);
// consumer plugin service should return enabled on all data nodes
assertConsumerPluginNotification(consumerPluginServices(), LicenseState.ENABLED, 1);
logger.info(" --> check trial license expiry notification");
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
assertConsumerPluginNotification(consumerPluginServices(), LicenseState.GRACE_PERIOD, trialLicenseDurationInSeconds);
assertLicenseeState(LicenseState.GRACE_PERIOD);
assertConsumerPluginNotification(consumerPluginServices(), LicenseState.DISABLED, trialLicenseDurationInSeconds);
assertLicenseeState(LicenseState.DISABLED);
}
public void testOverlappingTrialAndSignedLicenseNotification() throws Exception {
logger.info(" --> check onEnabled for trial license");
// managerService should report feature to be enabled on all data nodes
assertLicenseeState(LicenseState.ENABLED);
// consumer plugin service should return enabled on all data nodes
assertConsumerPluginNotification(consumerPluginServices(), LicenseState.ENABLED, 1);
logger.info(" --> put signed license while trial license is in effect");
putLicense(TimeValue.timeValueSeconds(trialLicenseDurationInSeconds * 2));
logger.info(" --> check signed license enabled notification");
// consumer plugin should notify onEnabled on all data nodes (signed license)
assertConsumerPluginNotification(consumerPluginServices(), LicenseState.ENABLED, 1);
assertLicenseeState(LicenseState.ENABLED);
logger.info(" --> sleep for rest of trailLicense duration");
Thread.sleep(trialLicenseDurationInSeconds * 1000L);
logger.info(" --> check consumer is still enabled [signed license]");
// consumer plugin should notify onEnabled on all data nodes (signed license)
assertConsumerPluginNotification(consumerPluginServices(), LicenseState.ENABLED, 1);
assertLicenseeState(LicenseState.ENABLED);
logger.info(" --> check signed license expiry notification");
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
assertConsumerPluginNotification(consumerPluginServices(), LicenseState.GRACE_PERIOD, trialLicenseDurationInSeconds * 2 * 2);
assertLicenseeState(LicenseState.GRACE_PERIOD);
assertConsumerPluginNotification(consumerPluginServices(), LicenseState.DISABLED, trialLicenseDurationInSeconds * 2 * 2);
assertLicenseeState(LicenseState.DISABLED);
}
private List<TestPluginServiceBase> consumerPluginServices() {
final InternalTestCluster clients = internalCluster();
List<TestPluginServiceBase> consumerPluginServices = new ArrayList<>();
for (TestPluginServiceBase service : clients.getDataNodeInstances(consumerPlugin.service())) {
consumerPluginServices.add(service);
}
return consumerPluginServices;
}
}

View File

@ -11,37 +11,19 @@ import org.elasticsearch.cluster.ClusterStateUpdateTask;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.license.core.License;
import org.elasticsearch.license.plugin.action.put.PutLicenseAction;
import org.elasticsearch.license.plugin.action.put.PutLicenseRequestBuilder;
import org.elasticsearch.license.plugin.action.put.PutLicenseResponse;
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationPluginService;
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationPluginService;
import org.elasticsearch.license.plugin.consumer.TestPluginServiceBase;
import org.elasticsearch.license.plugin.core.LicenseState;
import org.elasticsearch.license.plugin.core.LicensesManagerService;
import org.elasticsearch.license.plugin.core.LicensesMetaData;
import org.elasticsearch.license.plugin.core.LicensesStatus;
import org.elasticsearch.xpack.monitoring.Monitoring;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.xpack.security.Security;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.InternalTestCluster;
import org.elasticsearch.xpack.watcher.Watcher;
import org.elasticsearch.xpack.XPackPlugin;
import org.elasticsearch.xpack.graph.Graph;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import static org.elasticsearch.license.plugin.TestUtils.generateSignedLicense;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
public abstract class AbstractLicensesIntegrationTestCase extends ESIntegTestCase {
@ -71,6 +53,30 @@ public abstract class AbstractLicensesIntegrationTestCase extends ESIntegTestCas
return nodeSettings(0);
}
protected void putLicense(final License license) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
ClusterService clusterService = internalCluster().getInstance(ClusterService.class, internalCluster().getMasterName());
clusterService.submitStateUpdateTask("putting license", new ClusterStateUpdateTask() {
@Override
public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
latch.countDown();
}
@Override
public ClusterState execute(ClusterState currentState) throws Exception {
MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData());
mdBuilder.putCustom(LicensesMetaData.TYPE, new LicensesMetaData(license));
return ClusterState.builder(currentState).metaData(mdBuilder).build();
}
@Override
public void onFailure(String source, @Nullable Exception e) {
logger.error("error on metaData cleanup after test", e);
}
});
latch.await();
}
protected void wipeAllLicenses() throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
ClusterService clusterService = internalCluster().getInstance(ClusterService.class, internalCluster().getMasterName());
@ -94,67 +100,4 @@ public abstract class AbstractLicensesIntegrationTestCase extends ESIntegTestCas
});
latch.await();
}
protected void putLicense(TimeValue expiryDuration) throws Exception {
License license1 = generateSignedLicense(expiryDuration);
final PutLicenseResponse putLicenseResponse = new PutLicenseRequestBuilder(client().admin().cluster(),
PutLicenseAction.INSTANCE).setLicense(license1).get();
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
}
protected void assertLicenseeState(final LicenseState state) throws InterruptedException {
assertTrue("license should have status " + state.name(), awaitBusy(() -> {
final InternalTestCluster clients = internalCluster();
for (LicensesManagerService managerService : clients.getDataNodeInstances(LicensesManagerService.class)) {
if (managerService.licenseState() != state) {
return false;
}
}
return true;
}));
}
protected void assertLazyConsumerPluginNotification(final LicenseState state, int timeoutInSec) throws InterruptedException {
final List<TestPluginServiceBase> consumerPluginServices = consumerLazyPluginServices();
assertConsumerPluginNotification(consumerPluginServices, state, timeoutInSec);
}
protected void assertEagerConsumerPluginNotification(final LicenseState state, int timeoutInSec) throws InterruptedException {
final List<TestPluginServiceBase> consumerPluginServices = consumerEagerPluginServices();
assertConsumerPluginNotification(consumerPluginServices, state, timeoutInSec);
}
protected void assertConsumerPluginNotification(final List<TestPluginServiceBase> consumerPluginServices, final LicenseState state,
int timeoutInSec) throws InterruptedException {
assertThat("At least one instance has to be present", consumerPluginServices.size(), greaterThan(0));
boolean success = awaitBusy(() -> {
for (TestPluginServiceBase pluginService : consumerPluginServices) {
if (state != pluginService.state()) {
return false;
}
}
return true;
}, timeoutInSec + 1, TimeUnit.SECONDS);
logger.debug("Notification assertion complete");
assertThat(consumerPluginServices.get(0).getClass().getName() + " should have status " + state.name(), success, equalTo(true));
}
private List<TestPluginServiceBase> consumerLazyPluginServices() {
final InternalTestCluster clients = internalCluster();
List<TestPluginServiceBase> consumerPluginServices = new ArrayList<>();
for (TestPluginServiceBase service : clients.getDataNodeInstances(LazyLicenseRegistrationPluginService.class)) {
consumerPluginServices.add(service);
}
return consumerPluginServices;
}
private List<TestPluginServiceBase> consumerEagerPluginServices() {
final InternalTestCluster clients = internalCluster();
List<TestPluginServiceBase> consumerPluginServices = new ArrayList<>();
for (TestPluginServiceBase service : clients.getDataNodeInstances(EagerLicenseRegistrationPluginService.class)) {
consumerPluginServices.add(service);
}
return consumerPluginServices;
}
}

View File

@ -1,19 +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;
import org.apache.lucene.util.LuceneTestCase.BadApple;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationConsumerPlugin;
// test is just too slow, please fix it to not be sleep-based
@BadApple(bugUrl = "https://github.com/elastic/x-plugins/issues/1007")
public class LicensesEagerConsumerPluginIntegrationTests extends AbstractLicensesConsumerPluginIntegrationTestCase {
public LicensesEagerConsumerPluginIntegrationTests() {
super(new EagerLicenseRegistrationConsumerPlugin(Settings.EMPTY));
}
}

View File

@ -1,19 +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;
import org.apache.lucene.util.LuceneTestCase.BadApple;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationConsumerPlugin;
//test is just too slow, please fix it to not be sleep-based
@BadApple(bugUrl = "https://github.com/elastic/x-plugins/issues/1007")
public class LicensesLazyConsumerPluginIntegrationTests extends AbstractLicensesConsumerPluginIntegrationTestCase {
public LicensesLazyConsumerPluginIntegrationTests() {
super(new LazyLicenseRegistrationConsumerPlugin(Settings.EMPTY));
}
}

View File

@ -1,162 +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;
import org.apache.lucene.util.LuceneTestCase.BadApple;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.gateway.GatewayService;
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationConsumerPlugin;
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationPluginService;
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationConsumerPlugin;
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationPluginService;
import org.elasticsearch.license.plugin.core.LicenseState;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
import org.elasticsearch.xpack.XPackPlugin;
import org.junit.After;
import java.util.Arrays;
import java.util.Collection;
import static org.elasticsearch.test.ESIntegTestCase.Scope.TEST;
//test is just too slow, please fix it to not be sleep-based
@BadApple(bugUrl = "https://github.com/elastic/x-plugins/issues/1007")
@ClusterScope(scope = TEST, numDataNodes = 2, numClientNodes = 0)
public class LicensesPluginIntegrationTests extends AbstractLicensesIntegrationTestCase {
private final boolean useEagerLicenseRegistrationPlugin = randomBoolean();
private final int trialLicenseDurationInSeconds = 10;
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
// this setting is only used in tests
.put("_trial_license_duration_in_seconds", trialLicenseDurationInSeconds)
.build();
}
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
if (useEagerLicenseRegistrationPlugin) {
return Arrays.asList(XPackPlugin.class, EagerLicenseRegistrationConsumerPlugin.class);
} else {
return Arrays.asList(XPackPlugin.class, LazyLicenseRegistrationConsumerPlugin.class);
}
}
@Override
protected Collection<Class<? extends Plugin>> transportClientPlugins() {
return nodePlugins();
}
@After
public void afterTest() throws Exception {
wipeAllLicenses();
assertTrue(awaitBusy(() -> !clusterService().state().blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK)));
}
public void testTrialLicenseAndSignedLicenseNotification() throws Exception {
logger.info("using {} consumer plugin", useEagerLicenseRegistrationPlugin ? "eager" : "lazy");
logger.info(" --> trial license generated");
// managerService should report feature to be enabled on all data nodes
assertLicenseeState(LicenseState.ENABLED);
// consumer plugin service should return enabled on all data nodes
assertConsumerPluginEnabledNotification(2);
logger.info(" --> check trial license expiry notification");
// consumer plugin should notify onDisabled on all data nodes (expired trial license)
assertConsumerPluginDisabledNotification(trialLicenseDurationInSeconds * 2);
assertLicenseeState(LicenseState.GRACE_PERIOD);
assertLicenseeState(LicenseState.DISABLED);
logger.info(" --> put signed license");
putLicense(TimeValue.timeValueSeconds(trialLicenseDurationInSeconds));
logger.info(" --> check signed license enabled notification");
// consumer plugin should notify onEnabled on all data nodes (signed license)
assertConsumerPluginEnabledNotification(1);
assertLicenseeState(LicenseState.ENABLED);
logger.info(" --> check signed license expiry notification");
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
assertConsumerPluginDisabledNotification(trialLicenseDurationInSeconds * 2);
assertLicenseeState(LicenseState.GRACE_PERIOD);
assertLicenseeState(LicenseState.DISABLED);
}
public void testTrialLicenseNotification() throws Exception {
logger.info(" --> check onEnabled for trial license");
// managerService should report feature to be enabled on all data nodes
assertLicenseeState(LicenseState.ENABLED);
// consumer plugin service should return enabled on all data nodes
assertConsumerPluginEnabledNotification(1);
logger.info(" --> check trial license expiry notification");
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
assertConsumerPluginDisabledNotification(trialLicenseDurationInSeconds * 2);
assertLicenseeState(LicenseState.GRACE_PERIOD);
assertLicenseeState(LicenseState.DISABLED);
}
public void testOverlappingTrialAndSignedLicenseNotification() throws Exception {
logger.info(" --> check onEnabled for trial license");
// managerService should report feature to be enabled on all data nodes
assertLicenseeState(LicenseState.ENABLED);
// consumer plugin service should return enabled on all data nodes
assertConsumerPluginEnabledNotification(1);
logger.info(" --> put signed license while trial license is in effect");
putLicense(TimeValue.timeValueSeconds(trialLicenseDurationInSeconds * 2));
logger.info(" --> check signed license enabled notification");
// consumer plugin should notify onEnabled on all data nodes (signed license)
assertConsumerPluginEnabledNotification(1);
assertLicenseeState(LicenseState.ENABLED);
logger.info(" --> sleep for rest of trailLicense duration");
Thread.sleep(trialLicenseDurationInSeconds * 1000L);
logger.info(" --> check consumer is still enabled [signed license]");
// consumer plugin should notify onEnabled on all data nodes (signed license)
assertConsumerPluginEnabledNotification(1);
assertLicenseeState(LicenseState.ENABLED);
logger.info(" --> check signed license expiry notification");
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
assertConsumerPluginDisabledNotification(trialLicenseDurationInSeconds * 2 * 2);
assertLicenseeState(LicenseState.GRACE_PERIOD);
assertLicenseeState(LicenseState.DISABLED);
}
private String getCurrentFeatureName() {
if (useEagerLicenseRegistrationPlugin) {
return EagerLicenseRegistrationPluginService.ID;
} else {
return LazyLicenseRegistrationPluginService.ID;
}
}
private void assertConsumerPluginEnabledNotification(int timeoutInSec) throws InterruptedException {
if (useEagerLicenseRegistrationPlugin) {
assertEagerConsumerPluginNotification(LicenseState.ENABLED, timeoutInSec);
} else {
assertLazyConsumerPluginNotification(LicenseState.ENABLED, timeoutInSec);
}
}
private void assertConsumerPluginDisabledNotification(int timeoutInSec) throws InterruptedException {
if (useEagerLicenseRegistrationPlugin) {
assertEagerConsumerPluginNotification(LicenseState.GRACE_PERIOD, timeoutInSec);
} else {
assertLazyConsumerPluginNotification(LicenseState.GRACE_PERIOD, timeoutInSec);
}
}
}

View File

@ -1,139 +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;
import org.apache.lucene.util.LuceneTestCase.BadApple;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationConsumerPlugin;
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationPluginService;
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationConsumerPlugin;
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationPluginService;
import org.elasticsearch.license.plugin.core.LicenseState;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
import org.elasticsearch.xpack.XPackPlugin;
import org.junit.After;
import java.util.Arrays;
import java.util.Collection;
import static org.elasticsearch.test.ESIntegTestCase.Scope.TEST;
//test is just too slow, please fix it to not be sleep-based
@BadApple(bugUrl = "https://github.com/elastic/x-plugins/issues/1007")
@ClusterScope(scope = TEST, numDataNodes = 0, numClientNodes = 0)
public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegrationTestCase {
private static final String ID_1 = EagerLicenseRegistrationPluginService.ID;
private static final String ID_2 = LazyLicenseRegistrationPluginService.ID;
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
.build();
}
private Settings nodeSettingsWithConsumerPlugin(int trialLicenseDuration) {
return Settings.builder()
.put(super.nodeSettings(0))
// this setting is only used in tests
.put("_trial_license_duration_in_seconds", trialLicenseDuration)
.build();
}
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Arrays.asList(XPackPlugin.class, EagerLicenseRegistrationConsumerPlugin.class, LazyLicenseRegistrationConsumerPlugin.class);
}
@Override
protected Collection<Class<? extends Plugin>> transportClientPlugins() {
return nodePlugins();
}
@After
public void afterTest() throws Exception {
wipeAllLicenses();
}
public void testMultipleConsumerPlugins() throws Exception {
int nNodes = randomIntBetween(2, 3);
int trialLicenseDurationInSec = 20;
int signedLicenseDuration = 5;
startNodesWithConsumerPlugins(nNodes, trialLicenseDurationInSec);
logger.info(" --> trial license generated");
// managerService should report feature to be enabled on all data nodes
assertLicenseeState(LicenseState.ENABLED);
assertLicenseeState(LicenseState.ENABLED);
// consumer plugin service should return enabled on all data nodes
assertEagerConsumerPluginNotification(LicenseState.ENABLED, 1);
assertLazyConsumerPluginNotification(LicenseState.ENABLED, 1);
logger.info(" --> check trial license expiry notification");
// consumer plugin should notify onDisabled on all data nodes (expired trial license)
assertEagerConsumerPluginNotification(LicenseState.GRACE_PERIOD, trialLicenseDurationInSec * 2);
assertLazyConsumerPluginNotification(LicenseState.GRACE_PERIOD, trialLicenseDurationInSec * 2);
assertLicenseeState(LicenseState.GRACE_PERIOD);
assertLicenseeState(LicenseState.GRACE_PERIOD);
assertLicenseeState(LicenseState.DISABLED);
assertLicenseeState(LicenseState.DISABLED);
logger.info(" --> put signed license");
putLicense(TimeValue.timeValueSeconds(signedLicenseDuration));
logger.info(" --> check signed license enabled notification");
// consumer plugin should notify onEnabled on all data nodes (signed license)
assertEagerConsumerPluginNotification(LicenseState.ENABLED, 1);
assertLazyConsumerPluginNotification(LicenseState.ENABLED, 1);
assertLicenseeState(LicenseState.ENABLED);
assertLicenseeState(LicenseState.ENABLED);
logger.info(" --> check signed license expiry notification");
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
assertEagerConsumerPluginNotification(LicenseState.GRACE_PERIOD, signedLicenseDuration * 2);
assertLazyConsumerPluginNotification(LicenseState.GRACE_PERIOD, signedLicenseDuration * 2);
assertLicenseeState(LicenseState.GRACE_PERIOD);
assertLicenseeState(LicenseState.GRACE_PERIOD);
assertEagerConsumerPluginNotification(LicenseState.DISABLED, 10 * 2);
assertLazyConsumerPluginNotification(LicenseState.DISABLED, 10 * 2);
assertLicenseeState(LicenseState.DISABLED);
assertLicenseeState(LicenseState.DISABLED);
}
public void testRandomFeatureLicensesActions() throws Exception {
int nNodes = randomIntBetween(2, 3);
startNodesWithConsumerPlugins(nNodes, 10);
logger.info(" --> check license enabled notification");
assertEagerConsumerPluginNotification(LicenseState.ENABLED, 1);
assertLazyConsumerPluginNotification(LicenseState.ENABLED, 1);
assertLicenseeState(LicenseState.ENABLED);
assertLicenseeState(LicenseState.ENABLED);
logger.info(" --> check license expiry notification");
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
assertEagerConsumerPluginNotification(LicenseState.GRACE_PERIOD, 10 * 2);
assertLazyConsumerPluginNotification(LicenseState.GRACE_PERIOD, 10 * 2);
assertLicenseeState(LicenseState.GRACE_PERIOD);
assertLicenseeState(LicenseState.GRACE_PERIOD);
assertEagerConsumerPluginNotification(LicenseState.DISABLED, 10 * 2);
assertLazyConsumerPluginNotification(LicenseState.DISABLED, 10 * 2);
assertLicenseeState(LicenseState.DISABLED);
assertLicenseeState(LicenseState.DISABLED);
}
private void startNodesWithConsumerPlugins(int nNodes, int trialLicenseDuration) {
for (int i = 0; i < nNodes; i++) {
internalCluster().startNode(nodeSettingsWithConsumerPlugin(trialLicenseDuration));
}
}
}

View File

@ -19,19 +19,16 @@ import org.elasticsearch.license.plugin.action.get.GetLicenseResponse;
import org.elasticsearch.license.plugin.action.put.PutLicenseAction;
import org.elasticsearch.license.plugin.action.put.PutLicenseRequestBuilder;
import org.elasticsearch.license.plugin.action.put.PutLicenseResponse;
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationConsumerPlugin;
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationPluginService;
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationConsumerPlugin;
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationPluginService;
import org.elasticsearch.license.plugin.core.LicenseState;
import org.elasticsearch.license.plugin.core.LicensesMetaData;
import org.elasticsearch.license.plugin.core.LicensesService;
import org.elasticsearch.license.plugin.core.LicensesStatus;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
import org.elasticsearch.xpack.XPackPlugin;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import static org.elasticsearch.license.plugin.TestUtils.generateSignedLicense;
import static org.elasticsearch.test.ESIntegTestCase.Scope.TEST;
@ -42,7 +39,6 @@ import static org.hamcrest.CoreMatchers.nullValue;
@ClusterScope(scope = TEST, numDataNodes = 0, numClientNodes = 0, maxNumDataNodes = 0, transportClientRatio = 0)
public class LicensesServiceClusterTests extends AbstractLicensesIntegrationTestCase {
private final String[] PLUGINS = {EagerLicenseRegistrationPluginService.ID, LazyLicenseRegistrationPluginService.ID};
@Override
protected Settings transportClientSettings() {
@ -58,16 +54,12 @@ public class LicensesServiceClusterTests extends AbstractLicensesIntegrationTest
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
.put("node.data", true)
// this setting is only used in tests
.put("_trial_license_duration_in_seconds", 9)
// this setting is only used in tests
.put("_grace_duration_in_seconds", 9)
.put(NetworkModule.HTTP_ENABLED.getKey(), true);
}
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Arrays.asList(XPackPlugin.class, EagerLicenseRegistrationConsumerPlugin.class, LazyLicenseRegistrationConsumerPlugin.class);
return Collections.singletonList(XPackPlugin.class);
}
@Override
@ -106,48 +98,57 @@ public class LicensesServiceClusterTests extends AbstractLicensesIntegrationTest
wipeAllLicenses();
}
private void assertLicenseState(LicenseState state) throws InterruptedException {
boolean success = awaitBusy(() -> {
for (LicensesService service : internalCluster().getDataNodeInstances(LicensesService.class)) {
if (service.licenseState() == state) {
return true;
}
}
return false;
});
assertTrue(success);
}
public void testClusterRestartWhileEnabled() throws Exception {
wipeAllLicenses();
internalCluster().startNode();
ensureGreen();
assertEagerConsumerPluginNotification(LicenseState.ENABLED, 5);
assertLazyConsumerPluginNotification(LicenseState.ENABLED, 5);
assertLicenseState(LicenseState.ENABLED);
logger.info("--> restart node");
internalCluster().fullRestart();
ensureYellow();
logger.info("--> await node for enabled");
assertEagerConsumerPluginNotification(LicenseState.ENABLED, 5);
assertLazyConsumerPluginNotification(LicenseState.ENABLED, 5);
assertLicenseState(LicenseState.ENABLED);
}
@AwaitsFix(bugUrl = "todo fix test using mock clock")
public void testClusterRestartWhileGrace() throws Exception {
wipeAllLicenses();
internalCluster().startNode();
assertLicenseState(LicenseState.ENABLED);
putLicense(TestUtils.generateSignedLicense(TimeValue.timeValueMillis(0)));
ensureGreen();
assertEagerConsumerPluginNotification(LicenseState.GRACE_PERIOD, 10);
assertLazyConsumerPluginNotification(LicenseState.GRACE_PERIOD, 10);
assertLicenseState(LicenseState.GRACE_PERIOD);
logger.info("--> restart node");
internalCluster().fullRestart();
ensureYellow();
logger.info("--> await node for grace_period");
assertEagerConsumerPluginNotification(LicenseState.GRACE_PERIOD, 5);
assertLazyConsumerPluginNotification(LicenseState.GRACE_PERIOD, 5);
assertLicenseState(LicenseState.GRACE_PERIOD);
}
@AwaitsFix(bugUrl = "todo fix test using mock clock")
public void testClusterRestartWhileExpired() throws Exception {
wipeAllLicenses();
internalCluster().startNode();
ensureGreen();
assertEagerConsumerPluginNotification(LicenseState.DISABLED, 20);
assertLazyConsumerPluginNotification(LicenseState.DISABLED, 20);
assertLicenseState(LicenseState.ENABLED);
putLicense(TestUtils.generateExpiredLicense(System.currentTimeMillis() - LicensesService.GRACE_PERIOD_DURATION.getMillis()));
assertLicenseState(LicenseState.DISABLED);
logger.info("--> restart node");
internalCluster().fullRestart();
ensureYellow();
logger.info("--> await node for disabled");
assertEagerConsumerPluginNotification(LicenseState.DISABLED, 5);
assertLazyConsumerPluginNotification(LicenseState.DISABLED, 5);
assertLicenseState(LicenseState.DISABLED);
}
public void testClusterNotRecovered() throws Exception {
@ -155,27 +156,7 @@ public class LicensesServiceClusterTests extends AbstractLicensesIntegrationTest
internalCluster().startNode(nodeSettingsBuilder(0).put("discovery.zen.minimum_master_nodes", 2).put("node.master", true));
logger.info("--> start second master out of two [recovered state]");
internalCluster().startNode(nodeSettingsBuilder(1).put("discovery.zen.minimum_master_nodes", 2).put("node.master", true));
assertLicenseesStateEnabled();
assertConsumerPluginEnabledNotification(1);
}
public void testAtMostOnceTrialLicenseGeneration() throws Exception {
wipeAllLicenses();
logger.info("--> start one node [trial license should be generated & enabled]");
internalCluster().startNode(nodeSettingsBuilder(0));
assertLicenseesStateEnabled();
assertConsumerPluginEnabledNotification(1);
logger.info("--> start another node [trial license should be propagated from the old master not generated]");
internalCluster().startNode(nodeSettings(1));
assertLicenseesStateEnabled();
assertConsumerPluginEnabledNotification(1);
logger.info("--> check if multiple trial licenses are found for a id");
LicensesMetaData licensesMetaData = clusterService().state().metaData().custom(LicensesMetaData.TYPE);
assertThat(licensesMetaData.getLicense(), not(LicensesMetaData.LICENSE_TOMBSTONE));
wipeAllLicenses();
assertLicenseState(LicenseState.ENABLED);
}
private void removeLicense() throws Exception {
@ -217,15 +198,4 @@ public class LicensesServiceClusterTests extends AbstractLicensesIntegrationTest
assertThat(licensesMetaData, notNullValue());
assertThat(licensesMetaData.getLicense(), not(LicensesMetaData.LICENSE_TOMBSTONE));
}
private void assertLicenseesStateEnabled() throws Exception {
for (String id : PLUGINS) {
assertLicenseeState(LicenseState.ENABLED);
}
}
private void assertConsumerPluginEnabledNotification(int timeoutInSec) throws InterruptedException {
assertEagerConsumerPluginNotification(LicenseState.ENABLED, timeoutInSec);
assertLazyConsumerPluginNotification(LicenseState.ENABLED, timeoutInSec);
}
}

View File

@ -1,59 +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;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationConsumerPlugin;
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationPluginService;
import org.elasticsearch.license.plugin.core.LicenseState;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.xpack.XPackPlugin;
import java.util.Arrays;
import java.util.Collection;
import static org.elasticsearch.test.ESIntegTestCase.Scope.TEST;
/**
*/
@ESIntegTestCase.ClusterScope(scope = TEST, supportsDedicatedMasters = false, numDataNodes = 10, numClientNodes = 0)
public class LicensesServiceNodeTests extends AbstractLicensesIntegrationTestCase {
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
.put(NetworkModule.HTTP_ENABLED.getKey(), true)
.build();
}
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Arrays.asList(XPackPlugin.class, EagerLicenseRegistrationConsumerPlugin.class);
}
@Override
protected Collection<Class<? extends Plugin>> transportClientPlugins() {
return nodePlugins();
}
public void testPluginStatus() throws Exception {
final Iterable<EagerLicenseRegistrationPluginService> testPluginServices =
internalCluster().getDataNodeInstances(EagerLicenseRegistrationPluginService.class);
assertTrue(awaitBusy(() -> {
for (EagerLicenseRegistrationPluginService pluginService : testPluginServices) {
if (pluginService.state() != LicenseState.ENABLED) {
return false;
}
}
return true;
}));
}
}

View File

@ -118,7 +118,10 @@ public class TestUtils {
}
public static License generateExpiredLicense() throws Exception {
long expiryDate = System.currentTimeMillis() - TimeValue.timeValueHours(randomIntBetween(1, 10)).getMillis();
return generateExpiredLicense(System.currentTimeMillis() - TimeValue.timeValueHours(randomIntBetween(1, 10)).getMillis());
}
public static License generateExpiredLicense(long expiryDate) throws Exception {
final License.Builder builder = License.builder()
.uid(UUID.randomUUID().toString())
.version(License.VERSION_CURRENT)

View File

@ -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.license.plugin.consumer;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
/**
* Registers licenses upon the start of the service lifecycle
* see {@link EagerLicenseRegistrationPluginService}
* <p>
* License registration might happen before clusterService start()
*/
public class EagerLicenseRegistrationConsumerPlugin extends TestConsumerPluginBase {
public static final String NAME = "test_consumer_plugin_1";
@Inject
public EagerLicenseRegistrationConsumerPlugin(Settings settings) {
super(settings);
}
@Override
public Class<? extends TestPluginServiceBase> service() {
return EagerLicenseRegistrationPluginService.class;
}
@Override
public String id() {
return EagerLicenseRegistrationPluginService.ID;
}
}

View File

@ -1,27 +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.consumer;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.inject.Singleton;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.plugin.core.LicensesService;
@Singleton
public class EagerLicenseRegistrationPluginService extends TestPluginServiceBase {
public static String ID = "id1";
@Inject
public EagerLicenseRegistrationPluginService(Settings settings, LicensesService licensesClientService) {
super(true, settings, licensesClientService, null);
}
@Override
public String id() {
return ID;
}
}

View File

@ -1,33 +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.consumer;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
/**
* Registers licenses only after cluster has recovered
* see {@link LazyLicenseRegistrationPluginService}
* <p>
* License registration happens after clusterservice start()
*/
public class LazyLicenseRegistrationConsumerPlugin extends TestConsumerPluginBase {
@Inject
public LazyLicenseRegistrationConsumerPlugin(Settings settings) {
super(settings);
}
@Override
public Class<? extends TestPluginServiceBase> service() {
return LazyLicenseRegistrationPluginService.class;
}
@Override
public String id() {
return LazyLicenseRegistrationPluginService.ID;
}
}

View File

@ -1,28 +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.consumer;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.inject.Singleton;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.plugin.core.LicensesService;
@Singleton
public class LazyLicenseRegistrationPluginService extends TestPluginServiceBase {
public static String ID = "id2";
@Inject
public LazyLicenseRegistrationPluginService(Settings settings, LicensesService licensesClientService, ClusterService clusterService) {
super(false, settings, licensesClientService, clusterService);
}
@Override
public String id() {
return ID;
}
}

View File

@ -1,48 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.license.plugin.consumer;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.component.LifecycleComponent;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsModule;
import org.elasticsearch.plugins.Plugin;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public abstract class TestConsumerPluginBase extends Plugin {
private final boolean isEnabled;
public TestConsumerPluginBase(Settings settings) {
this.isEnabled = TransportClient.CLIENT_TYPE.equals(settings.get(Client.CLIENT_TYPE_SETTING_S.getKey())) == false;
}
@Override
public Collection<Class<? extends LifecycleComponent>> nodeServices() {
Collection<Class<? extends LifecycleComponent>> services = new ArrayList<>();
if (isEnabled) {
services.add(service());
}
return services;
}
@Override
public List<Setting<?>> getSettings() {
return Arrays.asList(Setting.simpleString("_trial_license_duration_in_seconds", Setting.Property.NodeScope,
Setting.Property.Shared), Setting.simpleString("_grace_duration_in_seconds", Setting.Property.NodeScope,
Setting.Property.Shared));
}
public abstract Class<? extends TestPluginServiceBase> service();
public abstract String id();
}

View File

@ -1,108 +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.consumer;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.cluster.ClusterChangedEvent;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.cluster.ClusterStateListener;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.gateway.GatewayService;
import org.elasticsearch.license.core.License;
import org.elasticsearch.license.plugin.core.LicenseState;
import org.elasticsearch.license.plugin.core.Licensee;
import org.elasticsearch.license.plugin.core.LicensesService;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
public abstract class TestPluginServiceBase extends AbstractLifecycleComponent
implements ClusterStateListener, Licensee {
private LicensesService licensesClientService;
private final ClusterService clusterService;
final boolean eagerLicenseRegistration;
public final AtomicBoolean registered = new AtomicBoolean(false);
private AtomicReference<LicenseState> state = new AtomicReference<>(LicenseState.DISABLED);
public TestPluginServiceBase(boolean eagerLicenseRegistration, Settings settings, LicensesService licensesClientService,
ClusterService clusterService) {
super(settings);
this.eagerLicenseRegistration = eagerLicenseRegistration;
this.licensesClientService = licensesClientService;
int trialDurationInSec = settings.getAsInt("_trial_license_duration_in_seconds", -1);
// TODO: remove integ licensing tests for external plugins
/*
if (trialDurationInSec != -1) {
licensesClientService.setTrialLicenseDuration(TimeValue.timeValueSeconds(trialDurationInSec));
}
int graceDurationInSec = settings.getAsInt("_grace_duration_in_seconds", 5);
licensesClientService.setGracePeriodDuration(TimeValue.timeValueSeconds(graceDurationInSec));
*/
if (!eagerLicenseRegistration) {
this.clusterService = clusterService;
clusterService.add(this);
} else {
this.clusterService = null;
}
}
// should be the same string used by the license Manger to generate
// signed license
public abstract String id();
// check if feature is enabled
public LicenseState state() {
return state.get();
}
@Override
public void clusterChanged(ClusterChangedEvent event) {
if (!eagerLicenseRegistration && !event.state().blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK)) {
if (registered.compareAndSet(false, true)) {
logger.info("Registering to licensesService [lazy]");
licensesClientService.register(this);
}
}
}
protected void doStart() throws ElasticsearchException {
if (eagerLicenseRegistration) {
if (registered.compareAndSet(false, true)) {
logger.info("Registering to licensesService [eager]");
licensesClientService.register(this);
}
}
}
@Override
public String[] expirationMessages() {
return new String[0];
}
@Override
public String[] acknowledgmentMessages(License currentLicense, License newLicense) {
return new String[0];
}
@Override
public void onChange(Status status) {
this.state.set(status.getLicenseState());
}
@Override
protected void doStop() throws ElasticsearchException {
if (clusterService != null) {
clusterService.remove(this);
}
}
@Override
protected void doClose() throws ElasticsearchException {
}
}