- Fix test concurrency bugs
- Minor test fixes - LicensesService documentation Original commit: elastic/x-pack-elasticsearch@ab98ba8a2d
This commit is contained in:
parent
93944f27f2
commit
3aec0fd1f0
|
@ -46,15 +46,19 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||||
import static org.elasticsearch.license.core.ESLicenses.reduceAndMap;
|
import static org.elasticsearch.license.core.ESLicenses.reduceAndMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service responsible for managing {@link org.elasticsearch.license.plugin.core.LicensesMetaData}
|
* Service responsible for managing {@link LicensesMetaData}
|
||||||
* Interfaces through which this is exposed are:
|
* Interfaces through which this is exposed are:
|
||||||
* - LicensesManagerService - responsible for managing signed and one-time-trial licenses
|
* - LicensesManagerService - responsible for managing signed and one-time-trial licenses
|
||||||
* - LicensesClientService - responsible for feature registration and notification to consumer plugin(s)
|
* - LicensesClientService - responsible for feature registration and notification to consumer plugin(s)
|
||||||
|
*
|
||||||
* <p/>
|
* <p/>
|
||||||
* Registration Scheme:
|
* Registration Scheme:
|
||||||
|
* <p/>
|
||||||
* A consumer plugin (feature) is registered with {@link LicensesClientService#register(String, TrialLicenseOptions, LicensesClientService.Listener)}
|
* A consumer plugin (feature) is registered with {@link LicensesClientService#register(String, TrialLicenseOptions, LicensesClientService.Listener)}
|
||||||
* This method can be called at any time during the life-cycle of the consumer plugin.
|
* This method can be called at any time during the life-cycle of the consumer plugin.
|
||||||
*
|
* If the feature can not be registered immediately, it is queued up and registered on the first clusterChanged event with
|
||||||
|
* no {@link GatewayService#STATE_NOT_RECOVERED_BLOCK} block
|
||||||
|
* Upon successful registration, the feature(s) are notified appropriately using the notification scheme
|
||||||
*
|
*
|
||||||
* <p/>
|
* <p/>
|
||||||
* Notification Scheme:
|
* Notification Scheme:
|
||||||
|
@ -69,7 +73,7 @@ import static org.elasticsearch.license.core.ESLicenses.reduceAndMap;
|
||||||
* <p/>
|
* <p/>
|
||||||
* The {@link LicensingClientNotificationJob} calls {@link #notifyFeaturesAndScheduleNotification(LicensesMetaData)} to schedule
|
* The {@link LicensingClientNotificationJob} calls {@link #notifyFeaturesAndScheduleNotification(LicensesMetaData)} to schedule
|
||||||
* another delayed {@link LicensingClientNotificationJob} as stated above. It is a no-op in case of a global block on
|
* another delayed {@link LicensingClientNotificationJob} as stated above. It is a no-op in case of a global block on
|
||||||
* {@link org.elasticsearch.gateway.GatewayService#STATE_NOT_RECOVERED_BLOCK}
|
* {@link GatewayService#STATE_NOT_RECOVERED_BLOCK}
|
||||||
* <p/>
|
* <p/>
|
||||||
* Upon successful registration of a new feature:
|
* Upon successful registration of a new feature:
|
||||||
* - {@link #notifyFeaturesAndScheduleNotification(LicensesMetaData)} is called
|
* - {@link #notifyFeaturesAndScheduleNotification(LicensesMetaData)} is called
|
||||||
|
@ -78,8 +82,8 @@ import static org.elasticsearch.license.core.ESLicenses.reduceAndMap;
|
||||||
* - {@link #notifyFeaturesAndScheduleNotification(LicensesMetaData)} is called if:
|
* - {@link #notifyFeaturesAndScheduleNotification(LicensesMetaData)} is called if:
|
||||||
* - new trial/signed license(s) are found in the cluster state meta data
|
* - new trial/signed license(s) are found in the cluster state meta data
|
||||||
* - if new feature(s) are added to the registeredListener
|
* - if new feature(s) are added to the registeredListener
|
||||||
* - if the previous cluster state had a global block on {@link org.elasticsearch.gateway.GatewayService#STATE_NOT_RECOVERED_BLOCK}
|
* - if the previous cluster state had a global block on {@link GatewayService#STATE_NOT_RECOVERED_BLOCK}
|
||||||
* - no-op in case of global block on {@link org.elasticsearch.gateway.GatewayService#STATE_NOT_RECOVERED_BLOCK}
|
* - no-op in case of global block on {@link GatewayService#STATE_NOT_RECOVERED_BLOCK}
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class LicensesService extends AbstractLifecycleComponent<LicensesService> implements ClusterStateListener, LicensesManagerService, LicensesClientService {
|
public class LicensesService extends AbstractLifecycleComponent<LicensesService> implements ClusterStateListener, LicensesManagerService, LicensesClientService {
|
||||||
|
@ -380,10 +384,10 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When there is no global block on {@link org.elasticsearch.gateway.GatewayService#STATE_NOT_RECOVERED_BLOCK}:
|
* When there is no global block on {@link GatewayService#STATE_NOT_RECOVERED_BLOCK}:
|
||||||
* - tries to register any {@link #pendingListeners} by calling {@link #registeredListeners}
|
* - tries to register any {@link #pendingListeners} by calling {@link #registeredListeners}
|
||||||
* - if any {@link #pendingListeners} are registered successfully or if previous cluster state had a block on
|
* - if any {@link #pendingListeners} are registered successfully or if previous cluster state had a block on
|
||||||
* {@link org.elasticsearch.gateway.GatewayService#STATE_NOT_RECOVERED_BLOCK}, calls
|
* {@link GatewayService#STATE_NOT_RECOVERED_BLOCK}, calls
|
||||||
* {@link #notifyFeaturesAndScheduleNotification(LicensesMetaData)}
|
* {@link #notifyFeaturesAndScheduleNotification(LicensesMetaData)}
|
||||||
* - else calls {@link #notifyFeaturesAndScheduleNotificationIfNeeded(LicensesMetaData)}
|
* - else calls {@link #notifyFeaturesAndScheduleNotificationIfNeeded(LicensesMetaData)}
|
||||||
*/
|
*/
|
||||||
|
@ -435,6 +439,7 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
notifyFeaturesAndScheduleNotification(currentLicensesMetaData);
|
notifyFeaturesAndScheduleNotification(currentLicensesMetaData);
|
||||||
|
logLicenseMetaDataStats("Setting last observed metaData", currentLicensesMetaData);
|
||||||
lastObservedLicensesState.set(currentLicensesMetaData);
|
lastObservedLicensesState.set(currentLicensesMetaData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,7 +498,6 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logLicenseMetaDataStats("Setting last observed metaData", currentLicensesMetaData);
|
|
||||||
if (nextScheduleFrequency == -1l) {
|
if (nextScheduleFrequency == -1l) {
|
||||||
logger.debug("no need to schedule next notification");
|
logger.debug("no need to schedule next notification");
|
||||||
} else {
|
} else {
|
||||||
|
@ -506,10 +510,22 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logLicenseMetaDataStats(String prefix, LicensesMetaData licensesMetaData) {
|
private void logLicenseMetaDataStats(String prefix, LicensesMetaData licensesMetaData) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
if (licensesMetaData != null) {
|
if (licensesMetaData != null) {
|
||||||
logger.debug(prefix + " LicensesMetaData: signedLicenses: " + licensesMetaData.getSignatures().size() + " trialLicenses: " + licensesMetaData.getEncodedTrialLicenses().size());
|
StringBuilder signedFeatures = new StringBuilder();
|
||||||
|
for (ESLicense license : licenseManager.fromSignatures(licensesMetaData.getSignatures())) {
|
||||||
|
signedFeatures.append(license.feature());
|
||||||
|
signedFeatures.append(", ");
|
||||||
|
}
|
||||||
|
StringBuilder trialFeatures = new StringBuilder();
|
||||||
|
for (ESLicense license : TrialLicenseUtils.fromEncodedTrialLicenses(licensesMetaData.getEncodedTrialLicenses())) {
|
||||||
|
trialFeatures.append(license.feature());
|
||||||
|
trialFeatures.append(", ");
|
||||||
|
}
|
||||||
|
logger.debug(prefix + " LicensesMetaData: signedLicenses: [" + signedFeatures.toString() + "] trialLicenses: [" + trialFeatures.toString() + "]");
|
||||||
} else {
|
} else {
|
||||||
logger.debug(prefix + " LicensesMetaData: signedLicenses: 0 trialLicenses: 0");
|
logger.debug(prefix + " LicensesMetaData: signedLicenses: [] trialLicenses: []");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,7 +553,7 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
||||||
*
|
*
|
||||||
* @param listenerHolder of the feature to register
|
* @param listenerHolder of the feature to register
|
||||||
* @return true if registration has been completed, false otherwise (if masterNode is not available & trail license spec is provided)
|
* @return true if registration has been completed, false otherwise (if masterNode is not available & trail license spec is provided)
|
||||||
* or if there is a global block on {@link org.elasticsearch.gateway.GatewayService#STATE_NOT_RECOVERED_BLOCK}
|
* or if there is a global block on {@link GatewayService#STATE_NOT_RECOVERED_BLOCK}
|
||||||
*/
|
*/
|
||||||
private boolean registerListener(final ListenerHolder listenerHolder) {
|
private boolean registerListener(final ListenerHolder listenerHolder) {
|
||||||
logger.debug("Registering listener for " + listenerHolder.feature);
|
logger.debug("Registering listener for " + listenerHolder.feature);
|
||||||
|
@ -644,7 +660,7 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Job for notifying on expired license(s) to registered feature(s)
|
* Job for notifying on expired license(s) to registered feature(s)
|
||||||
* In case of a global block on {@link org.elasticsearch.gateway.GatewayService#STATE_NOT_RECOVERED_BLOCK},
|
* In case of a global block on {@link GatewayService#STATE_NOT_RECOVERED_BLOCK},
|
||||||
* the notification is not run, instead the feature(s) would be notified on the next
|
* the notification is not run, instead the feature(s) would be notified on the next
|
||||||
* {@link #clusterChanged(org.elasticsearch.cluster.ClusterChangedEvent)} with no global block
|
* {@link #clusterChanged(org.elasticsearch.cluster.ClusterChangedEvent)} with no global block
|
||||||
*/
|
*/
|
||||||
|
@ -717,12 +733,14 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
||||||
|
|
||||||
private void enableFeatureIfNeeded() {
|
private void enableFeatureIfNeeded() {
|
||||||
if (enabled.compareAndSet(false, true)) {
|
if (enabled.compareAndSet(false, true)) {
|
||||||
|
logger.debug("feature: " + feature + " calling onEnabled");
|
||||||
listener.onEnabled();
|
listener.onEnabled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void disableFeatureIfNeeded() {
|
private void disableFeatureIfNeeded() {
|
||||||
if (enabled.compareAndSet(true, false)) {
|
if (enabled.compareAndSet(true, false)) {
|
||||||
|
logger.debug("feature: " + feature + " calling onDisabled");
|
||||||
listener.onDisabled();
|
listener.onDisabled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -733,7 +751,7 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thin wrapper to work with {@link org.elasticsearch.license.plugin.core.LicensesMetaData}
|
* Thin wrapper to work with {@link LicensesMetaData}
|
||||||
* Never mutates the wrapped metaData
|
* Never mutates the wrapped metaData
|
||||||
*/
|
*/
|
||||||
private static class LicensesWrapper {
|
private static class LicensesWrapper {
|
||||||
|
|
|
@ -11,16 +11,20 @@ import org.elasticsearch.cluster.ProcessedClusterStateUpdateTask;
|
||||||
import org.elasticsearch.cluster.metadata.MetaData;
|
import org.elasticsearch.cluster.metadata.MetaData;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.base.Predicate;
|
import org.elasticsearch.common.base.Predicate;
|
||||||
|
import org.elasticsearch.common.collect.Lists;
|
||||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.license.core.ESLicense;
|
import org.elasticsearch.license.core.ESLicense;
|
||||||
import org.elasticsearch.license.licensor.ESLicenseSigner;
|
import org.elasticsearch.license.licensor.ESLicenseSigner;
|
||||||
|
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.EagerLicenseRegistrationPluginService;
|
||||||
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationPluginService;
|
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationPluginService;
|
||||||
import org.elasticsearch.license.plugin.consumer.TestPluginServiceBase;
|
import org.elasticsearch.license.plugin.consumer.TestPluginServiceBase;
|
||||||
import org.elasticsearch.license.plugin.core.LicensesManagerService;
|
import org.elasticsearch.license.plugin.core.LicensesManagerService;
|
||||||
import org.elasticsearch.license.plugin.core.LicensesMetaData;
|
import org.elasticsearch.license.plugin.core.LicensesMetaData;
|
||||||
|
import org.elasticsearch.license.plugin.core.LicensesStatus;
|
||||||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||||
import org.elasticsearch.test.InternalTestCluster;
|
import org.elasticsearch.test.InternalTestCluster;
|
||||||
|
|
||||||
|
@ -92,6 +96,14 @@ public abstract class AbstractLicensesIntegrationTests extends ElasticsearchInte
|
||||||
return signer.sign(licenseSpec);
|
return signer.sign(licenseSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void assertLicenseManagerEnabledFeatureFor(final String feature) throws InterruptedException {
|
protected void assertLicenseManagerEnabledFeatureFor(final String feature) throws InterruptedException {
|
||||||
assertLicenseManagerStatusFor(feature, true);
|
assertLicenseManagerStatusFor(feature, true);
|
||||||
}
|
}
|
||||||
|
@ -101,7 +113,7 @@ public abstract class AbstractLicensesIntegrationTests extends ElasticsearchInte
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void assertLicenseManagerStatusFor(final String feature, final boolean expectedEnabled) throws InterruptedException {
|
protected void assertLicenseManagerStatusFor(final String feature, final boolean expectedEnabled) throws InterruptedException {
|
||||||
assertThat(awaitBusy(new Predicate<Object>() {
|
assertThat("LicenseManager for feature " + feature + " should have enabled status of " + expectedEnabled, awaitBusy(new Predicate<Object>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Object o) {
|
public boolean apply(Object o) {
|
||||||
for (LicensesManagerService managerService : licensesManagerServices()) {
|
for (LicensesManagerService managerService : licensesManagerServices()) {
|
||||||
|
@ -133,17 +145,17 @@ public abstract class AbstractLicensesIntegrationTests extends ElasticsearchInte
|
||||||
protected void assertLazyConsumerPluginNotification(final boolean expectedEnabled, int timeoutInSec) throws InterruptedException {
|
protected void assertLazyConsumerPluginNotification(final boolean expectedEnabled, int timeoutInSec) throws InterruptedException {
|
||||||
final List<TestPluginServiceBase> consumerPluginServices = consumerLazyPluginServices();
|
final List<TestPluginServiceBase> consumerPluginServices = consumerLazyPluginServices();
|
||||||
assertThat("At least one instance has to be present", consumerPluginServices.size(), greaterThan(0));
|
assertThat("At least one instance has to be present", consumerPluginServices.size(), greaterThan(0));
|
||||||
assertConsumerPluginNotification(consumerPluginServices, expectedEnabled, timeoutInSec);
|
assertConsumerPluginNotification("LazyConsumer should have license status of: " + expectedEnabled, consumerPluginServices, expectedEnabled, timeoutInSec);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void assertEagerConsumerPluginNotification(final boolean expectedEnabled, int timeoutInSec) throws InterruptedException {
|
protected void assertEagerConsumerPluginNotification(final boolean expectedEnabled, int timeoutInSec) throws InterruptedException {
|
||||||
final List<TestPluginServiceBase> consumerPluginServices = consumerEagerPluginServices();
|
final List<TestPluginServiceBase> consumerPluginServices = consumerEagerPluginServices();
|
||||||
assertThat("At least one instance has to be present", consumerPluginServices.size(), greaterThan(0));
|
assertThat("At least one instance has to be present", consumerPluginServices.size(), greaterThan(0));
|
||||||
assertConsumerPluginNotification(consumerPluginServices, expectedEnabled, timeoutInSec);
|
assertConsumerPluginNotification("EagerConsumer should have license status of: " + expectedEnabled, consumerPluginServices, expectedEnabled, timeoutInSec);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertConsumerPluginNotification(final Iterable<TestPluginServiceBase> consumerPluginServices, final boolean expectedEnabled, int timeoutInSec) throws InterruptedException {
|
private void assertConsumerPluginNotification(String msg, final Iterable<TestPluginServiceBase> consumerPluginServices, final boolean expectedEnabled, int timeoutInSec) throws InterruptedException {
|
||||||
assertThat(awaitBusy(new Predicate<Object>() {
|
assertThat(msg, awaitBusy(new Predicate<Object>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Object o) {
|
public boolean apply(Object o) {
|
||||||
for (TestPluginServiceBase pluginService : consumerPluginServices) {
|
for (TestPluginServiceBase pluginService : consumerPluginServices) {
|
||||||
|
|
|
@ -6,19 +6,14 @@
|
||||||
package org.elasticsearch.license.plugin;
|
package org.elasticsearch.license.plugin;
|
||||||
|
|
||||||
import org.elasticsearch.common.base.Predicate;
|
import org.elasticsearch.common.base.Predicate;
|
||||||
import org.elasticsearch.common.collect.Lists;
|
|
||||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.gateway.GatewayService;
|
import org.elasticsearch.gateway.GatewayService;
|
||||||
import org.elasticsearch.license.core.ESLicense;
|
|
||||||
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationConsumerPlugin;
|
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationConsumerPlugin;
|
||||||
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationPluginService;
|
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationPluginService;
|
||||||
import org.elasticsearch.license.plugin.action.put.PutLicenseRequestBuilder;
|
|
||||||
import org.elasticsearch.license.plugin.action.put.PutLicenseResponse;
|
|
||||||
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationConsumerPlugin;
|
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationConsumerPlugin;
|
||||||
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationPluginService;
|
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationPluginService;
|
||||||
import org.elasticsearch.license.plugin.core.LicensesStatus;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -31,7 +26,7 @@ public class LicensesPluginIntegrationTests extends AbstractLicensesIntegrationT
|
||||||
|
|
||||||
private final boolean useEagerLicenseRegistrationPlugin = randomBoolean();
|
private final boolean useEagerLicenseRegistrationPlugin = randomBoolean();
|
||||||
|
|
||||||
private final int trialLicenseDurationInSeconds = 2;
|
private final int trialLicenseDurationInSeconds = 5;
|
||||||
|
|
||||||
protected Settings nodeSettings(int nodeOrdinal) {
|
protected Settings nodeSettings(int nodeOrdinal) {
|
||||||
return ImmutableSettings.settingsBuilder()
|
return ImmutableSettings.settingsBuilder()
|
||||||
|
@ -69,10 +64,7 @@ public class LicensesPluginIntegrationTests extends AbstractLicensesIntegrationT
|
||||||
assertLicenseManagerDisabledFeatureFor(getCurrentFeatureName());
|
assertLicenseManagerDisabledFeatureFor(getCurrentFeatureName());
|
||||||
|
|
||||||
logger.info(" --> put signed license");
|
logger.info(" --> put signed license");
|
||||||
ESLicense license = generateSignedLicense(getCurrentFeatureName(), TimeValue.timeValueSeconds(trialLicenseDurationInSeconds));
|
putLicense(getCurrentFeatureName(), TimeValue.timeValueSeconds(trialLicenseDurationInSeconds));
|
||||||
final PutLicenseResponse putLicenseResponse = new PutLicenseRequestBuilder(client().admin().cluster()).setLicense(Lists.newArrayList(license)).get();
|
|
||||||
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
|
|
||||||
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
|
|
||||||
|
|
||||||
logger.info(" --> check signed license enabled notification");
|
logger.info(" --> check signed license enabled notification");
|
||||||
// consumer plugin should notify onEnabled on all data nodes (signed license)
|
// consumer plugin should notify onEnabled on all data nodes (signed license)
|
||||||
|
@ -111,10 +103,7 @@ public class LicensesPluginIntegrationTests extends AbstractLicensesIntegrationT
|
||||||
assertConsumerPluginEnabledNotification(1);
|
assertConsumerPluginEnabledNotification(1);
|
||||||
|
|
||||||
logger.info(" --> put signed license while trial license is in effect");
|
logger.info(" --> put signed license while trial license is in effect");
|
||||||
ESLicense license = generateSignedLicense(getCurrentFeatureName(), TimeValue.timeValueSeconds(trialLicenseDurationInSeconds * 2));
|
putLicense(getCurrentFeatureName(), TimeValue.timeValueSeconds(trialLicenseDurationInSeconds * 2));
|
||||||
final PutLicenseResponse putLicenseResponse = new PutLicenseRequestBuilder(client().admin().cluster()).setLicense(Lists.newArrayList(license)).get();
|
|
||||||
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
|
|
||||||
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
|
|
||||||
|
|
||||||
logger.info(" --> check signed license enabled notification");
|
logger.info(" --> check signed license enabled notification");
|
||||||
// consumer plugin should notify onEnabled on all data nodes (signed license)
|
// consumer plugin should notify onEnabled on all data nodes (signed license)
|
||||||
|
|
|
@ -5,38 +5,30 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.license.plugin;
|
package org.elasticsearch.license.plugin;
|
||||||
|
|
||||||
import org.elasticsearch.common.collect.Lists;
|
|
||||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.license.core.ESLicense;
|
|
||||||
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.EagerLicenseRegistrationConsumerPlugin;
|
||||||
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationPluginService;
|
import org.elasticsearch.license.plugin.consumer.EagerLicenseRegistrationPluginService;
|
||||||
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationConsumerPlugin;
|
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationConsumerPlugin;
|
||||||
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationPluginService;
|
import org.elasticsearch.license.plugin.consumer.LazyLicenseRegistrationPluginService;
|
||||||
import org.elasticsearch.license.plugin.core.LicensesStatus;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
|
import static org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
|
||||||
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope.TEST;
|
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope.TEST;
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
|
||||||
|
|
||||||
@ClusterScope(scope = TEST, numDataNodes = 0, numClientNodes = 0)
|
@ClusterScope(scope = TEST, numDataNodes = 0, numClientNodes = 0)
|
||||||
public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegrationTests {
|
public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegrationTests {
|
||||||
|
|
||||||
private final int trialLicenseDurationInSeconds = 2;
|
|
||||||
|
|
||||||
private final String FEATURE_NAME_1 = EagerLicenseRegistrationPluginService.FEATURE_NAME;
|
private final String FEATURE_NAME_1 = EagerLicenseRegistrationPluginService.FEATURE_NAME;
|
||||||
private final String FEATURE_NAME_2 = LazyLicenseRegistrationPluginService.FEATURE_NAME;
|
private final String FEATURE_NAME_2 = LazyLicenseRegistrationPluginService.FEATURE_NAME;
|
||||||
|
|
||||||
protected Settings nodeSettings(int nodeOrdinal) {
|
protected Settings nodeSettings(int nodeOrdinal) {
|
||||||
return ImmutableSettings.settingsBuilder()
|
return ImmutableSettings.settingsBuilder()
|
||||||
.put(super.nodeSettings(nodeOrdinal))
|
.put(super.nodeSettings(nodeOrdinal))
|
||||||
.put(EagerLicenseRegistrationConsumerPlugin.NAME + ".trial_license_duration_in_seconds", trialLicenseDurationInSeconds)
|
.put(EagerLicenseRegistrationConsumerPlugin.NAME + ".trial_license_duration_in_seconds", 2)
|
||||||
.put(LazyLicenseRegistrationConsumerPlugin.NAME + ".trial_license_duration_in_seconds", trialLicenseDurationInSeconds)
|
.put(LazyLicenseRegistrationConsumerPlugin.NAME + ".trial_license_duration_in_seconds", 2)
|
||||||
.putArray("plugin.types", LicensePlugin.class.getName(), EagerLicenseRegistrationConsumerPlugin.class.getName(), LazyLicenseRegistrationConsumerPlugin.class.getName())
|
.putArray("plugin.types", LicensePlugin.class.getName(), EagerLicenseRegistrationConsumerPlugin.class.getName(), LazyLicenseRegistrationConsumerPlugin.class.getName())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
@ -59,10 +51,10 @@ public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegration
|
||||||
@Test
|
@Test
|
||||||
public void testWithNoTrialLicense() throws Exception {
|
public void testWithNoTrialLicense() throws Exception {
|
||||||
int nNodes = randomIntBetween(2, 10);
|
int nNodes = randomIntBetween(2, 10);
|
||||||
String[] nodes = startNodesWithConsumerPlugins(nNodes, -1, -1);
|
startNodesWithConsumerPlugins(nNodes, -1, -1);
|
||||||
|
|
||||||
assertEagerConsumerPluginDisableNotification(trialLicenseDurationInSeconds * 2);
|
assertEagerConsumerPluginDisableNotification(1);
|
||||||
assertLazyConsumerPluginDisableNotification(trialLicenseDurationInSeconds * 2);
|
assertLazyConsumerPluginDisableNotification(1);
|
||||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
||||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
||||||
}
|
}
|
||||||
|
@ -71,7 +63,7 @@ public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegration
|
||||||
public void testOneTrialAndNonTrialConsumer() throws Exception {
|
public void testOneTrialAndNonTrialConsumer() throws Exception {
|
||||||
int nNodes = randomIntBetween(2, 10);
|
int nNodes = randomIntBetween(2, 10);
|
||||||
int consumer2TrialLicenseDuration = 2;
|
int consumer2TrialLicenseDuration = 2;
|
||||||
String[] nodes = startNodesWithConsumerPlugins(nNodes, -1, consumer2TrialLicenseDuration);
|
startNodesWithConsumerPlugins(nNodes, -1, consumer2TrialLicenseDuration);
|
||||||
|
|
||||||
logger.info(" --> trial license generated for " + FEATURE_NAME_2 + " no trial license for " + FEATURE_NAME_1);
|
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
|
// managerService should report feature to be enabled on all data nodes
|
||||||
|
@ -82,16 +74,11 @@ public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegration
|
||||||
assertLazyConsumerPluginEnableNotification(1);
|
assertLazyConsumerPluginEnableNotification(1);
|
||||||
|
|
||||||
logger.info(" --> put signed license for " + FEATURE_NAME_1);
|
logger.info(" --> put signed license for " + FEATURE_NAME_1);
|
||||||
ESLicense license1 = generateSignedLicense(FEATURE_NAME_1, TimeValue.timeValueSeconds(consumer2TrialLicenseDuration));
|
putLicense(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");
|
logger.info(" --> check that both " + FEATURE_NAME_1 + " and " + FEATURE_NAME_2 + " are enabled");
|
||||||
assertEagerConsumerPluginEnableNotification(1);
|
assertEagerConsumerPluginEnableNotification(1);
|
||||||
assertLazyConsumerPluginEnableNotification(1);
|
|
||||||
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_1);
|
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_1);
|
||||||
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_2);
|
|
||||||
|
|
||||||
logger.info(" --> check signed license expiry notification");
|
logger.info(" --> check signed license expiry notification");
|
||||||
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
|
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
|
||||||
|
@ -105,7 +92,10 @@ public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegration
|
||||||
public void testMultipleConsumerPlugins() throws Exception {
|
public void testMultipleConsumerPlugins() throws Exception {
|
||||||
|
|
||||||
int nNodes = randomIntBetween(2, 10);
|
int nNodes = randomIntBetween(2, 10);
|
||||||
String[] nodes = startNodesWithConsumerPlugins(nNodes, trialLicenseDurationInSeconds, trialLicenseDurationInSeconds);
|
int consumer1TrialLicenseExpiry = 2;
|
||||||
|
int consumer2TrialLicenseExpiry = 2;
|
||||||
|
startNodesWithConsumerPlugins(nNodes, consumer1TrialLicenseExpiry, consumer2TrialLicenseExpiry);
|
||||||
|
|
||||||
logger.info(" --> trial license generated");
|
logger.info(" --> trial license generated");
|
||||||
// managerService should report feature to be enabled on all data nodes
|
// managerService should report feature to be enabled on all data nodes
|
||||||
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_1);
|
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_1);
|
||||||
|
@ -116,14 +106,14 @@ public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegration
|
||||||
|
|
||||||
logger.info(" --> check trial license expiry notification");
|
logger.info(" --> check trial license expiry notification");
|
||||||
// consumer plugin should notify onDisabled on all data nodes (expired trial license)
|
// consumer plugin should notify onDisabled on all data nodes (expired trial license)
|
||||||
assertEagerConsumerPluginDisableNotification(trialLicenseDurationInSeconds * 2);
|
assertEagerConsumerPluginDisableNotification(consumer1TrialLicenseExpiry * 2);
|
||||||
assertLazyConsumerPluginDisableNotification(trialLicenseDurationInSeconds * 2);
|
assertLazyConsumerPluginDisableNotification(consumer2TrialLicenseExpiry * 2);
|
||||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
||||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
||||||
|
|
||||||
logger.info(" --> put signed license");
|
logger.info(" --> put signed license");
|
||||||
putLicense(FEATURE_NAME_1, TimeValue.timeValueSeconds(trialLicenseDurationInSeconds));
|
putLicense(FEATURE_NAME_1, TimeValue.timeValueSeconds(consumer1TrialLicenseExpiry));
|
||||||
putLicense(FEATURE_NAME_2, TimeValue.timeValueSeconds(trialLicenseDurationInSeconds));
|
putLicense(FEATURE_NAME_2, TimeValue.timeValueSeconds(consumer2TrialLicenseExpiry));
|
||||||
|
|
||||||
logger.info(" --> check signed license enabled notification");
|
logger.info(" --> check signed license enabled notification");
|
||||||
// consumer plugin should notify onEnabled on all data nodes (signed license)
|
// consumer plugin should notify onEnabled on all data nodes (signed license)
|
||||||
|
@ -134,8 +124,8 @@ public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegration
|
||||||
|
|
||||||
logger.info(" --> check signed license expiry notification");
|
logger.info(" --> check signed license expiry notification");
|
||||||
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
|
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
|
||||||
assertEagerConsumerPluginDisableNotification(trialLicenseDurationInSeconds * 2);
|
assertEagerConsumerPluginDisableNotification(consumer1TrialLicenseExpiry * 2);
|
||||||
assertLazyConsumerPluginDisableNotification(trialLicenseDurationInSeconds * 2);
|
assertLazyConsumerPluginDisableNotification(consumer2TrialLicenseExpiry * 2);
|
||||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
||||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
||||||
}
|
}
|
||||||
|
@ -143,27 +133,27 @@ public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegration
|
||||||
@Test
|
@Test
|
||||||
public void testRandomFeatureLicensesActions() throws Exception {
|
public void testRandomFeatureLicensesActions() throws Exception {
|
||||||
int nNodes = randomIntBetween(2, 10);
|
int nNodes = randomIntBetween(2, 10);
|
||||||
int trialLicenseDuration1 = rarely() ? -1 : randomIntBetween(1, 2);
|
int trialLicenseDuration1 = rarely() ? -1 : randomIntBetween(2, 3);
|
||||||
int trialLicenseDuration2 = rarely() ? -1 : randomIntBetween(1, 2);
|
int trialLicenseDuration2 = rarely() ? -1 : randomIntBetween(2, 3);
|
||||||
|
|
||||||
String[] nodes = startNodesWithConsumerPlugins(nNodes, trialLicenseDuration1, trialLicenseDuration2);
|
startNodesWithConsumerPlugins(nNodes, trialLicenseDuration1, trialLicenseDuration2);
|
||||||
|
|
||||||
if (trialLicenseDuration1 != -1) {
|
if (trialLicenseDuration1 != -1) {
|
||||||
assertEagerConsumerPluginEnableNotification(1);
|
assertEagerConsumerPluginEnableNotification(trialLicenseDuration1);
|
||||||
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_1);
|
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_1);
|
||||||
} else {
|
} else {
|
||||||
assertEagerConsumerPluginDisableNotification(1);
|
assertEagerConsumerPluginDisableNotification(3 * 2);
|
||||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
||||||
putLicense(FEATURE_NAME_1, TimeValue.timeValueMillis(300 * 2));
|
putLicense(FEATURE_NAME_1, TimeValue.timeValueMillis(500 * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trialLicenseDuration2 != -1) {
|
if (trialLicenseDuration2 != -1) {
|
||||||
assertLazyConsumerPluginEnableNotification(1);
|
assertLazyConsumerPluginEnableNotification(trialLicenseDuration2);
|
||||||
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_2);
|
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_2);
|
||||||
} else {
|
} else {
|
||||||
assertLazyConsumerPluginDisableNotification(1);
|
assertLazyConsumerPluginDisableNotification(3 * 2);
|
||||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
||||||
putLicense(FEATURE_NAME_2, TimeValue.timeValueMillis(300 * 2));
|
putLicense(FEATURE_NAME_2, TimeValue.timeValueMillis(500 * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(" --> check license enabled notification");
|
logger.info(" --> check license enabled notification");
|
||||||
|
@ -174,25 +164,16 @@ public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegration
|
||||||
|
|
||||||
logger.info(" --> check license expiry notification");
|
logger.info(" --> check license expiry notification");
|
||||||
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
|
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
|
||||||
assertEagerConsumerPluginDisableNotification(2 * 2);
|
assertEagerConsumerPluginDisableNotification(3 * 2);
|
||||||
assertLazyConsumerPluginDisableNotification(2 * 2);
|
assertLazyConsumerPluginDisableNotification(3 * 2);
|
||||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
|
||||||
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] startNodesWithConsumerPlugins(int nNodes, int consumer1TrialLicenseDuration, int consumer2TrialLicenseDuration) {
|
private void startNodesWithConsumerPlugins(int nNodes, int consumer1TrialLicenseDuration, int consumer2TrialLicenseDuration) {
|
||||||
String[] nodes = new String[nNodes];
|
|
||||||
for (int i = 0; i < nNodes; i++) {
|
for (int i = 0; i < nNodes; i++) {
|
||||||
nodes[i] = internalCluster().startNode(nodeSettingsWithConsumerPlugin(consumer1TrialLicenseDuration, consumer2TrialLicenseDuration));
|
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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,8 +109,9 @@ public class LicensesServiceTests extends AbstractLicensesIntegrationTests {
|
||||||
List<Action> actions = new ArrayList<>();
|
List<Action> actions = new ArrayList<>();
|
||||||
|
|
||||||
final TimeValue expiryDuration = TimeValue.timeValueSeconds(2);
|
final TimeValue expiryDuration = TimeValue.timeValueSeconds(2);
|
||||||
actions.add(registerWithTrialLicense(clientService, clientListener, "feature1", expiryDuration));
|
String feature1 = "feature1";
|
||||||
actions.add(assertExpiryAction("trial", expiryDuration));
|
actions.add(registerWithTrialLicense(clientService, clientListener, feature1, expiryDuration));
|
||||||
|
actions.add(assertExpiryAction(feature1, "trial", expiryDuration));
|
||||||
assertClientListenerNotificationCount(clientListener, actions);
|
assertClientListenerNotificationCount(clientListener, actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,14 +127,16 @@ public class LicensesServiceTests extends AbstractLicensesIntegrationTests {
|
||||||
List<Action> secondClientActions = new ArrayList<>();
|
List<Action> secondClientActions = new ArrayList<>();
|
||||||
|
|
||||||
final TimeValue firstExpiryDuration = TimeValue.timeValueSeconds(2);
|
final TimeValue firstExpiryDuration = TimeValue.timeValueSeconds(2);
|
||||||
firstClientActions.add(registerWithoutTrialLicense(licensesService, clientListener1, "feature1"));
|
String feature1 = "feature1";
|
||||||
firstClientActions.add(generateAndPutSignedLicenseAction(masterLicensesManagerService, "feature1", firstExpiryDuration));
|
firstClientActions.add(registerWithoutTrialLicense(licensesService, clientListener1, feature1));
|
||||||
firstClientActions.add(assertExpiryAction("signed", firstExpiryDuration));
|
firstClientActions.add(generateAndPutSignedLicenseAction(masterLicensesManagerService, feature1, firstExpiryDuration));
|
||||||
|
firstClientActions.add(assertExpiryAction(feature1, "signed", firstExpiryDuration));
|
||||||
|
|
||||||
final TimeValue secondExpiryDuration = TimeValue.timeValueSeconds(1);
|
final TimeValue secondExpiryDuration = TimeValue.timeValueSeconds(1);
|
||||||
secondClientActions.add(registerWithoutTrialLicense(licensesService, clientListener2, "feature2"));
|
String feature2 = "feature2";
|
||||||
secondClientActions.add(generateAndPutSignedLicenseAction(masterLicensesManagerService, "feature2", secondExpiryDuration));
|
secondClientActions.add(registerWithoutTrialLicense(licensesService, clientListener2, feature2));
|
||||||
secondClientActions.add(assertExpiryAction("signed", secondExpiryDuration));
|
secondClientActions.add(generateAndPutSignedLicenseAction(masterLicensesManagerService, feature2, secondExpiryDuration));
|
||||||
|
secondClientActions.add(assertExpiryAction(feature2, "signed", secondExpiryDuration));
|
||||||
|
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
assertClientListenerNotificationCount(clientListener1, firstClientActions);
|
assertClientListenerNotificationCount(clientListener1, firstClientActions);
|
||||||
|
@ -156,13 +159,15 @@ public class LicensesServiceTests extends AbstractLicensesIntegrationTests {
|
||||||
List<Action> secondClientActions = new ArrayList<>();
|
List<Action> secondClientActions = new ArrayList<>();
|
||||||
|
|
||||||
final TimeValue firstExpiryDuration = TimeValue.timeValueSeconds(2);
|
final TimeValue firstExpiryDuration = TimeValue.timeValueSeconds(2);
|
||||||
firstClientActions.add(registerWithoutTrialLicense(licensesService, clientListener1, "feature1"));
|
String feature1 = "feature1";
|
||||||
firstClientActions.add(generateAndPutSignedLicenseAction(masterLicensesManagerService, "feature1", firstExpiryDuration));
|
firstClientActions.add(registerWithoutTrialLicense(licensesService, clientListener1, feature1));
|
||||||
firstClientActions.add(assertExpiryAction("signed", firstExpiryDuration));
|
firstClientActions.add(generateAndPutSignedLicenseAction(masterLicensesManagerService, feature1, firstExpiryDuration));
|
||||||
|
firstClientActions.add(assertExpiryAction(feature1, "signed", firstExpiryDuration));
|
||||||
|
|
||||||
final TimeValue secondExpiryDuration = TimeValue.timeValueSeconds(1);
|
final TimeValue secondExpiryDuration = TimeValue.timeValueSeconds(1);
|
||||||
secondClientActions.add(registerWithTrialLicense(licensesService, clientListener2, "feature2", secondExpiryDuration));
|
String feature2 = "feature2";
|
||||||
secondClientActions.add(assertExpiryAction("trial", secondExpiryDuration));
|
secondClientActions.add(registerWithTrialLicense(licensesService, clientListener2, feature2, secondExpiryDuration));
|
||||||
|
secondClientActions.add(assertExpiryAction(feature2, "trial", secondExpiryDuration));
|
||||||
|
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
assertClientListenerNotificationCount(clientListener1, firstClientActions);
|
assertClientListenerNotificationCount(clientListener1, firstClientActions);
|
||||||
|
@ -184,12 +189,14 @@ public class LicensesServiceTests extends AbstractLicensesIntegrationTests {
|
||||||
List<Action> secondClientActions = new ArrayList<>();
|
List<Action> secondClientActions = new ArrayList<>();
|
||||||
|
|
||||||
TimeValue firstExpiryDuration = TimeValue.timeValueSeconds(1);
|
TimeValue firstExpiryDuration = TimeValue.timeValueSeconds(1);
|
||||||
firstClientActions.add(registerWithTrialLicense(licensesService, clientListener1, "feature1", firstExpiryDuration));
|
String feature1 = "feature1";
|
||||||
firstClientActions.add(assertExpiryAction("trial", firstExpiryDuration));
|
firstClientActions.add(registerWithTrialLicense(licensesService, clientListener1, feature1, firstExpiryDuration));
|
||||||
|
firstClientActions.add(assertExpiryAction(feature1, "trial", firstExpiryDuration));
|
||||||
|
|
||||||
TimeValue secondExpiryDuration = TimeValue.timeValueSeconds(2);
|
TimeValue secondExpiryDuration = TimeValue.timeValueSeconds(2);
|
||||||
secondClientActions.add(registerWithTrialLicense(licensesService, clientListener2, "feature2", secondExpiryDuration));
|
String feature2 = "feature2";
|
||||||
secondClientActions.add(assertExpiryAction("trial", secondExpiryDuration));
|
secondClientActions.add(registerWithTrialLicense(licensesService, clientListener2, feature2, secondExpiryDuration));
|
||||||
|
secondClientActions.add(assertExpiryAction(feature2, "trial", secondExpiryDuration));
|
||||||
|
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
assertClientListenerNotificationCount(clientListener1, firstClientActions);
|
assertClientListenerNotificationCount(clientListener1, firstClientActions);
|
||||||
|
@ -218,8 +225,9 @@ public class LicensesServiceTests extends AbstractLicensesIntegrationTests {
|
||||||
List<Action> actions = new ArrayList<>();
|
List<Action> actions = new ArrayList<>();
|
||||||
|
|
||||||
TimeValue expiryDuration = TimeValue.timeValueSeconds(2);
|
TimeValue expiryDuration = TimeValue.timeValueSeconds(2);
|
||||||
actions.add(registerWithTrialLicense(clientService, clientListener, "feature1", expiryDuration));
|
String feature = "feature1";
|
||||||
actions.add(assertExpiryAction("trial", expiryDuration));
|
actions.add(registerWithTrialLicense(clientService, clientListener, feature, expiryDuration));
|
||||||
|
actions.add(assertExpiryAction(feature, "trial", expiryDuration));
|
||||||
|
|
||||||
assertClientListenerNotificationCount(clientListener, actions);
|
assertClientListenerNotificationCount(clientListener, actions);
|
||||||
}
|
}
|
||||||
|
@ -231,19 +239,19 @@ public class LicensesServiceTests extends AbstractLicensesIntegrationTests {
|
||||||
Map<TestTrackingClientListener, List<Action>> clientListenersWithActions = new HashMap<>();
|
Map<TestTrackingClientListener, List<Action>> clientListenersWithActions = new HashMap<>();
|
||||||
|
|
||||||
TimeValue expiryDuration = TimeValue.timeValueSeconds(0);
|
TimeValue expiryDuration = TimeValue.timeValueSeconds(0);
|
||||||
for (int i = 0; i < randomIntBetween(10, 20); i++) {
|
for (int i = 0; i < randomIntBetween(5, 10); i++) {
|
||||||
final TestTrackingClientListener clientListener = new TestTrackingClientListener();
|
final TestTrackingClientListener clientListener = new TestTrackingClientListener();
|
||||||
String feature = randomRealisticUnicodeOfCodepointLengthBetween(2, 10);
|
String feature = "feature_" + String.valueOf(i);
|
||||||
expiryDuration = TimeValue.timeValueMillis(randomIntBetween(1, 5) * 100l + expiryDuration.millis());
|
expiryDuration = TimeValue.timeValueMillis(randomIntBetween(1, 3) * 1000l + expiryDuration.millis());
|
||||||
List<Action> actions = new ArrayList<>();
|
List<Action> actions = new ArrayList<>();
|
||||||
|
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
actions.add(registerWithTrialLicense(licensesService, clientListener, feature, expiryDuration));
|
actions.add(registerWithTrialLicense(licensesService, clientListener, feature, expiryDuration));
|
||||||
actions.add(assertExpiryAction("trial", expiryDuration));
|
actions.add(assertExpiryAction(feature, "trial", expiryDuration));
|
||||||
} else {
|
} else {
|
||||||
actions.add(registerWithoutTrialLicense(licensesService, clientListener, feature));
|
actions.add(registerWithoutTrialLicense(licensesService, clientListener, feature));
|
||||||
actions.add(generateAndPutSignedLicenseAction(masterLicensesManagerService, feature, expiryDuration));
|
actions.add(generateAndPutSignedLicenseAction(masterLicensesManagerService, feature, expiryDuration));
|
||||||
actions.add(assertExpiryAction("signed", expiryDuration));
|
actions.add(assertExpiryAction(feature, "signed", expiryDuration));
|
||||||
}
|
}
|
||||||
clientListenersWithActions.put(clientListener, actions);
|
clientListenersWithActions.put(clientListener, actions);
|
||||||
}
|
}
|
||||||
|
@ -274,8 +282,9 @@ public class LicensesServiceTests extends AbstractLicensesIntegrationTests {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
assertThat(latch.await(100, TimeUnit.MILLISECONDS), equalTo(true));
|
latch.await();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
fail(e.getMessage());
|
||||||
}
|
}
|
||||||
assertThat(success.get(), equalTo(true));
|
assertThat(success.get(), equalTo(true));
|
||||||
}
|
}
|
||||||
|
@ -320,51 +329,49 @@ public class LicensesServiceTests extends AbstractLicensesIntegrationTests {
|
||||||
}, 0, 1, "should trigger onEnable for " + feature + " once [trial license]");
|
}, 0, 1, "should trigger onEnable for " + feature + " once [trial license]");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Action assertExpiryAction(String licenseType, TimeValue expiryDuration) {
|
private Action assertExpiryAction(String feature, String licenseType, TimeValue expiryDuration) {
|
||||||
return new Action(new Runnable() {
|
return new Action(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {}
|
public void run() {}
|
||||||
}, 1, 0, TimeValue.timeValueMillis(expiryDuration.getMillis() * 2),
|
}, 1, 0, TimeValue.timeValueMillis(expiryDuration.getMillis() * 2),
|
||||||
"should trigger onDisable once [" + licenseType + " license expiry]");
|
"should trigger onDisable for " + feature + " once [" + licenseType + " license expiry]");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertClientListenerNotificationCount(final TestTrackingClientListener clientListener, List<Action> actions) throws Exception {
|
private void assertClientListenerNotificationCount(final TestTrackingClientListener clientListener, List<Action> actions) throws Exception {
|
||||||
assertThat(clientListener.onDisabledCount.get(), equalTo(0));
|
|
||||||
assertThat(clientListener.onEnabledCount.get(), equalTo(0));
|
|
||||||
|
|
||||||
for (final Action action : actions) {
|
for (final Action action : actions) {
|
||||||
final AtomicBoolean actionPerformed = new AtomicBoolean(false);
|
final CountDownLatch enableLatch = new CountDownLatch(action.expectedEnabledCount);
|
||||||
assertThat(action.msg, awaitBusy(new Predicate<Object>() {
|
final CountDownLatch disableLatch = new CountDownLatch(action.expectedDisabledCount);
|
||||||
AtomicInteger previousOnEnabledCount = new AtomicInteger(0);
|
|
||||||
AtomicInteger previousOnDisabledCount = new AtomicInteger(0);
|
|
||||||
|
|
||||||
@Override
|
clientListener.latch(enableLatch, disableLatch);
|
||||||
public boolean apply(Object o) {
|
|
||||||
if (actionPerformed.compareAndSet(false, true)) {
|
|
||||||
previousOnEnabledCount.set(clientListener.onEnabledCount.get());
|
|
||||||
previousOnDisabledCount.set(clientListener.onDisabledCount.get());
|
|
||||||
action.run();
|
action.run();
|
||||||
|
|
||||||
|
if (action.expectedEnabledCount > 0) {
|
||||||
|
assertThat(action.msg, enableLatch.await(action.timeout.getMillis() * 2, TimeUnit.MILLISECONDS), equalTo(true));
|
||||||
|
} else if (action.expectedDisabledCount > 0) {
|
||||||
|
assertThat(action.msg, disableLatch.await(action.timeout.getMillis() * 2, TimeUnit.MILLISECONDS), equalTo(true));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((clientListener.onEnabledCount.get() - previousOnEnabledCount.get()) == action.expectedEnabledCount
|
|
||||||
&& (clientListener.onDisabledCount.get() - previousOnDisabledCount.get()) == action.expectedDisabledCount);
|
|
||||||
}
|
|
||||||
}, action.timeout.getMillis(), TimeUnit.MILLISECONDS), equalTo(true));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestTrackingClientListener implements LicensesClientService.Listener {
|
private class TestTrackingClientListener implements LicensesClientService.Listener {
|
||||||
AtomicInteger onEnabledCount = new AtomicInteger(0);
|
CountDownLatch enableLatch;
|
||||||
AtomicInteger onDisabledCount = new AtomicInteger(0);
|
CountDownLatch disableLatch;
|
||||||
|
|
||||||
|
public synchronized void latch(CountDownLatch enableLatch, CountDownLatch disableLatch) {
|
||||||
|
this.enableLatch = enableLatch;
|
||||||
|
this.disableLatch = disableLatch;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnabled() {
|
public void onEnabled() {
|
||||||
onEnabledCount.incrementAndGet();
|
this.enableLatch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisabled() {
|
public void onDisabled() {
|
||||||
onDisabledCount.incrementAndGet();
|
this.disableLatch.countDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue