Tests & Refactoring:
- Added LicensesPluginsIntegrationTests (test with more than one consumer plugin) - Minor fix for LicensesService - Remove public_key_file from verify-license - WIP: STATE_NOT_RECOVERED_BLOCK tests Original commit: elastic/x-pack-elasticsearch@372034a86a
This commit is contained in:
parent
c5f5c807bb
commit
e0ec8f6059
|
@ -25,17 +25,14 @@ public class LicenseVerificationTool {
|
|||
|
||||
static class Options {
|
||||
private final Set<ESLicense> licenses;
|
||||
private final String publicKeyFilePath;
|
||||
|
||||
Options(Set<ESLicense> licenses, String publicKeyFilePath) {
|
||||
Options(Set<ESLicense> licenses) {
|
||||
this.licenses = licenses;
|
||||
this.publicKeyFilePath = publicKeyFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
private static Options parse(String[] args) throws IOException {
|
||||
Set<ESLicense> licenses = new HashSet<>();
|
||||
String publicKeyPath = null;
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
String command = args[i];
|
||||
|
@ -53,18 +50,12 @@ public class LicenseVerificationTool {
|
|||
case "--licenses":
|
||||
licenses.addAll(ESLicenses.fromSource(args[++i]));
|
||||
break;
|
||||
case "--publicKeyPath":
|
||||
publicKeyPath = args[++i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (licenses.size() == 0) {
|
||||
throw new IllegalArgumentException("mandatory option '--licensesFiles' or '--licenses' is missing");
|
||||
}
|
||||
if (publicKeyPath == null) {
|
||||
throw new IllegalArgumentException("mandatory option '--publicKeyPath' is missing");
|
||||
}
|
||||
return new Options(licenses, publicKeyPath);
|
||||
return new Options(licenses);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
|
|
@ -614,7 +614,7 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
|||
private void clearFinishedNotifications() {
|
||||
while (!scheduledNotifications.isEmpty()) {
|
||||
ScheduledFuture notification = scheduledNotifications.peek();
|
||||
if (notification.isDone()) {
|
||||
if (notification != null && notification.isDone()) {
|
||||
// remove the notifications that are done
|
||||
scheduledNotifications.poll();
|
||||
} else {
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.elasticsearch.license.plugin.core.LicensesManagerService;
|
|||
import org.elasticsearch.license.plugin.core.LicensesMetaData;
|
||||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||
import org.elasticsearch.test.InternalTestCluster;
|
||||
import org.hamcrest.Matchers;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
@ -31,6 +32,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import static org.elasticsearch.license.AbstractLicensingTestBase.getTestPriKeyPath;
|
||||
import static org.elasticsearch.license.AbstractLicensingTestBase.getTestPubKeyPath;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
|
||||
/**
|
||||
*/
|
||||
|
@ -130,12 +132,14 @@ public abstract class AbstractLicensesIntegrationTests extends ElasticsearchInte
|
|||
}
|
||||
|
||||
protected void assertConsumerPlugin2Notification(final boolean expectedEnabled, int timeoutInSec) throws InterruptedException {
|
||||
final Iterable<TestPluginServiceBase> consumerPluginServices = consumerPlugin2Services();
|
||||
final List<TestPluginServiceBase> consumerPluginServices = consumerPlugin2Services();
|
||||
assertThat("At least one instance has to be present", consumerPluginServices.size(), greaterThan(0));
|
||||
assertConsumerPluginNotification(consumerPluginServices, expectedEnabled, timeoutInSec);
|
||||
}
|
||||
|
||||
protected void assertConsumerPlugin1Notification(final boolean expectedEnabled, int timeoutInSec) throws InterruptedException {
|
||||
final Iterable<TestPluginServiceBase> consumerPluginServices = consumerPlugin1Services();
|
||||
final List<TestPluginServiceBase> consumerPluginServices = consumerPlugin1Services();
|
||||
assertThat("At least one instance has to be present", consumerPluginServices.size(), greaterThan(0));
|
||||
assertConsumerPluginNotification(consumerPluginServices, expectedEnabled, timeoutInSec);
|
||||
}
|
||||
|
||||
|
@ -154,7 +158,7 @@ public abstract class AbstractLicensesIntegrationTests extends ElasticsearchInte
|
|||
|
||||
}
|
||||
|
||||
private Iterable<TestPluginServiceBase> consumerPlugin2Services() {
|
||||
private List<TestPluginServiceBase> consumerPlugin2Services() {
|
||||
final InternalTestCluster clients = internalCluster();
|
||||
List<TestPluginServiceBase> consumerPluginServices = new ArrayList<>();
|
||||
for (TestPluginServiceBase service : clients.getDataNodeInstances(TestPluginService2.class)) {
|
||||
|
@ -163,7 +167,7 @@ public abstract class AbstractLicensesIntegrationTests extends ElasticsearchInte
|
|||
return consumerPluginServices;
|
||||
}
|
||||
|
||||
private Iterable<TestPluginServiceBase> consumerPlugin1Services() {
|
||||
private List<TestPluginServiceBase> consumerPlugin1Services() {
|
||||
final InternalTestCluster clients = internalCluster();
|
||||
List<TestPluginServiceBase> consumerPluginServices = new ArrayList<>();
|
||||
for (TestPluginServiceBase service : clients.getDataNodeInstances(TestPluginService1.class)) {
|
||||
|
|
|
@ -24,7 +24,7 @@ import static org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
|
|||
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope.TEST;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
|
||||
@ClusterScope(scope = TEST, numDataNodes = 10, numClientNodes = 0)
|
||||
@ClusterScope(scope = TEST, numDataNodes = 0, numClientNodes = 0)
|
||||
public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegrationTests {
|
||||
|
||||
private final int trialLicenseDurationInSeconds = 2;
|
||||
|
@ -41,13 +41,72 @@ public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegration
|
|||
.build();
|
||||
}
|
||||
|
||||
private Settings nodeSettingsWithConsumerPlugin(int consumer1TrialLicenseDuration, int consumer2TrialLicenseDuration) {
|
||||
return ImmutableSettings.settingsBuilder()
|
||||
.put(super.nodeSettings(0))
|
||||
.put(TestConsumerPlugin1.NAME + ".trial_license_duration_in_seconds", consumer1TrialLicenseDuration)
|
||||
.put(TestConsumerPlugin2.NAME + ".trial_license_duration_in_seconds", consumer2TrialLicenseDuration)
|
||||
.putArray("plugin.types", LicensePlugin.class.getName(), TestConsumerPlugin1.class.getName(), TestConsumerPlugin2.class.getName())
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void beforeTest() throws Exception {
|
||||
wipeAllLicenses();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithNoTrialLicense() throws Exception {
|
||||
int nNodes = randomIntBetween(2, 10);
|
||||
String[] nodes = startNodesWithConsumerPlugins(nNodes, -1, -1);
|
||||
|
||||
assertConsumerPlugin1DisableNotification(trialLicenseDurationInSeconds * 2);
|
||||
assertConsumerPlugin2DisableNotification(trialLicenseDurationInSeconds * 2);
|
||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneTrialAndNonTrialConsumer() throws Exception {
|
||||
int nNodes = randomIntBetween(2, 10);
|
||||
int consumer2TrialLicenseDuration = 2;
|
||||
String[] nodes = startNodesWithConsumerPlugins(nNodes, -1, consumer2TrialLicenseDuration);
|
||||
|
||||
logger.info(" --> trial license generated for " + FEATURE_NAME_2 + " no trial license for " + FEATURE_NAME_1);
|
||||
// managerService should report feature to be enabled on all data nodes
|
||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
||||
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_2);
|
||||
// consumer plugin service should return enabled on all data nodes
|
||||
assertConsumerPlugin1DisableNotification(1);
|
||||
assertConsumerPlugin2EnableNotification(1);
|
||||
|
||||
logger.info(" --> put signed license for " + FEATURE_NAME_1);
|
||||
ESLicense license1 = generateSignedLicense(FEATURE_NAME_1, TimeValue.timeValueSeconds(consumer2TrialLicenseDuration));
|
||||
final PutLicenseResponse putLicenseResponse = new PutLicenseRequestBuilder(client().admin().cluster()).setLicense(Lists.newArrayList(license1)).get();
|
||||
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
|
||||
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
|
||||
|
||||
logger.info(" --> check that both " + FEATURE_NAME_1 + " and " + FEATURE_NAME_2 + " are enabled");
|
||||
assertConsumerPlugin1EnableNotification(1);
|
||||
assertConsumerPlugin2EnableNotification(1);
|
||||
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_1);
|
||||
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_2);
|
||||
|
||||
logger.info(" --> check signed license expiry notification");
|
||||
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
|
||||
assertConsumerPlugin1DisableNotification(consumer2TrialLicenseDuration * 2);
|
||||
assertConsumerPlugin2DisableNotification(consumer2TrialLicenseDuration * 2);
|
||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleConsumerPlugins() throws Exception {
|
||||
|
||||
int nNodes = randomIntBetween(2, 10);
|
||||
String[] nodes = startNodesWithConsumerPlugins(nNodes, trialLicenseDurationInSeconds, trialLicenseDurationInSeconds);
|
||||
|
||||
logger.info(" --> trial license generated");
|
||||
// managerService should report feature to be enabled on all data nodes
|
||||
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_1);
|
||||
|
@ -64,11 +123,8 @@ public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegration
|
|||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
||||
|
||||
logger.info(" --> put signed license");
|
||||
ESLicense license1 = generateSignedLicense(FEATURE_NAME_1, TimeValue.timeValueSeconds(trialLicenseDurationInSeconds));
|
||||
ESLicense license2 = generateSignedLicense(FEATURE_NAME_2, TimeValue.timeValueSeconds(trialLicenseDurationInSeconds));
|
||||
final PutLicenseResponse putLicenseResponse = new PutLicenseRequestBuilder(client().admin().cluster()).setLicense(Lists.newArrayList(license1, license2)).get();
|
||||
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
|
||||
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
|
||||
putLicense(FEATURE_NAME_1, TimeValue.timeValueSeconds(trialLicenseDurationInSeconds));
|
||||
putLicense(FEATURE_NAME_2, TimeValue.timeValueSeconds(trialLicenseDurationInSeconds));
|
||||
|
||||
logger.info(" --> check signed license enabled notification");
|
||||
// consumer plugin should notify onEnabled on all data nodes (signed license)
|
||||
|
@ -84,4 +140,60 @@ public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegration
|
|||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandomFeatureLicensesActions() throws Exception {
|
||||
int nNodes = randomIntBetween(2, 10);
|
||||
int trialLicenseDuration1 = rarely() ? -1 : randomIntBetween(1, 2);
|
||||
int trialLicenseDuration2 = rarely() ? -1 : randomIntBetween(1, 2);
|
||||
|
||||
String[] nodes = startNodesWithConsumerPlugins(nNodes, trialLicenseDuration1, trialLicenseDuration2);
|
||||
|
||||
if (trialLicenseDuration1 != -1) {
|
||||
assertConsumerPlugin1EnableNotification(1);
|
||||
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_1);
|
||||
} else {
|
||||
assertConsumerPlugin1DisableNotification(1);
|
||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
||||
putLicense(FEATURE_NAME_1, TimeValue.timeValueMillis(300 * 2));
|
||||
}
|
||||
|
||||
if (trialLicenseDuration2 != -1) {
|
||||
assertConsumerPlugin2EnableNotification(1);
|
||||
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_2);
|
||||
} else {
|
||||
assertConsumerPlugin2DisableNotification(1);
|
||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
||||
putLicense(FEATURE_NAME_2, TimeValue.timeValueMillis(300 * 2));
|
||||
}
|
||||
|
||||
logger.info(" --> check license enabled notification");
|
||||
assertConsumerPlugin1EnableNotification(1);
|
||||
assertConsumerPlugin2EnableNotification(1);
|
||||
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_1);
|
||||
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_2);
|
||||
|
||||
logger.info(" --> check license expiry notification");
|
||||
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
|
||||
assertConsumerPlugin1DisableNotification(2 * 2);
|
||||
assertConsumerPlugin2DisableNotification(2 * 2);
|
||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
||||
|
||||
}
|
||||
|
||||
private String[] startNodesWithConsumerPlugins(int nNodes, int consumer1TrialLicenseDuration, int consumer2TrialLicenseDuration) {
|
||||
String[] nodes = new String[nNodes];
|
||||
for (int i = 0; i < nNodes; i++) {
|
||||
nodes[i] = internalCluster().startNode(nodeSettingsWithConsumerPlugin(consumer1TrialLicenseDuration, consumer2TrialLicenseDuration));
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
private void putLicense(String feature, TimeValue expiryDuration) throws Exception {
|
||||
ESLicense license1 = generateSignedLicense(feature, expiryDuration);
|
||||
final PutLicenseResponse putLicenseResponse = new PutLicenseRequestBuilder(client().admin().cluster()).setLicense(Lists.newArrayList(license1)).get();
|
||||
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
|
||||
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
package org.elasticsearch.license.plugin;
|
||||
|
||||
import org.elasticsearch.client.ClusterAdminClient;
|
||||
import org.elasticsearch.cluster.block.ClusterBlockLevel;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.gateway.GatewayService;
|
||||
import org.elasticsearch.license.TestUtils;
|
||||
import org.elasticsearch.license.core.ESLicense;
|
||||
import org.elasticsearch.license.plugin.action.get.GetLicenseRequestBuilder;
|
||||
|
@ -25,11 +27,13 @@ import org.junit.Test;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
|
||||
import static org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
|
||||
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope.TEST;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
|
||||
@ClusterScope(scope = TEST, numDataNodes = 0, numClientNodes = 0)
|
||||
@ClusterScope(scope = TEST, numDataNodes = 0, numClientNodes = 0, maxNumDataNodes = 0, transportClientRatio = 0)
|
||||
public class LicensesServiceClusterTest extends AbstractLicensesIntegrationTests {
|
||||
|
||||
private final String FEATURE_NAME = TestPluginService1.FEATURE_NAME;
|
||||
|
@ -44,7 +48,7 @@ public class LicensesServiceClusterTest extends AbstractLicensesIntegrationTests
|
|||
}
|
||||
|
||||
private ImmutableSettings.Builder nodeSettingsBuilder(int nodeOrdinal) {
|
||||
return ImmutableSettings.settingsBuilder()
|
||||
return settingsBuilder()
|
||||
.put(super.nodeSettings(nodeOrdinal))
|
||||
.put("gateway.type", "local")
|
||||
.put("plugins.load_classpath_plugins", false)
|
||||
|
@ -84,9 +88,13 @@ public class LicensesServiceClusterTest extends AbstractLicensesIntegrationTests
|
|||
@Test
|
||||
public void testClusterNotRecovered() throws Exception {
|
||||
|
||||
|
||||
logger.info("--> start first node (should not recover)");
|
||||
internalCluster().startNode(nodeSettingsBuilder(0).put("gateway.recover_after_master_nodes", 2).put("node.master", true));
|
||||
String name = internalCluster().startNode(nodeSettingsBuilder(0).put("gateway.recover_after_master_nodes", 2).put("node.master", true));
|
||||
/* TODO: figure out why STATE_NOT_RECOVERED_BLOCK is not on
|
||||
assertThat(internalCluster().client(name).admin().cluster().prepareState().setLocal(true).execute().actionGet()
|
||||
.getState().blocks().global(ClusterBlockLevel.METADATA),
|
||||
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
|
||||
*/
|
||||
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME);
|
||||
assertConsumerPlugin1EnableNotification(1);
|
||||
|
||||
|
|
Loading…
Reference in New Issue