[fix] Removing license did not update the Licensees
- Introduced a `MISSING` operation mode - now when the license is removed (and a tombstone license is placed), the licensees get notified with a `MISSING` license status - the monitoring, security and watcher licensees were updated Original commit: elastic/x-pack-elasticsearch@650d940666
This commit is contained in:
parent
233c64e942
commit
06a0a9cbb5
|
@ -77,6 +77,7 @@ public class License implements ToXContent {
|
|||
* Note: The mode indicates features that should be made available, but it does not indicate whether the license is active!
|
||||
*/
|
||||
public enum OperationMode {
|
||||
MISSING,
|
||||
TRIAL,
|
||||
BASIC,
|
||||
STANDARD,
|
||||
|
@ -85,6 +86,8 @@ public class License implements ToXContent {
|
|||
|
||||
public static OperationMode resolve(String type) {
|
||||
switch (type.toLowerCase(Locale.ROOT)) {
|
||||
case "missing":
|
||||
return MISSING;
|
||||
case "trial":
|
||||
case "none": // bwc for 1.x subscription_type field
|
||||
case "dev": // bwc for 1.x subscription_type field
|
||||
|
|
|
@ -53,6 +53,7 @@ public interface Licensee {
|
|||
class Status {
|
||||
|
||||
public static Status ENABLED = new Status(OperationMode.TRIAL, LicenseState.ENABLED);
|
||||
public static Status MISSING = new Status(OperationMode.MISSING, LicenseState.DISABLED);
|
||||
|
||||
private final OperationMode mode;
|
||||
private final LicenseState licenseState;
|
||||
|
|
|
@ -511,72 +511,77 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
|||
*/
|
||||
private void notifyAndSchedule(final LicensesMetaData currentLicensesMetaData) {
|
||||
final License license = getLicense(currentLicensesMetaData);
|
||||
if (license != null) {
|
||||
logger.debug("notifying [{}] listeners", registeredLicensees.size());
|
||||
long now = System.currentTimeMillis();
|
||||
if (license.issueDate() > now) {
|
||||
logger.info("license [{}] - invalid", license.uid());
|
||||
return;
|
||||
if (license == null) {
|
||||
for (InternalLicensee licensee : registeredLicensees) {
|
||||
licensee.onRemove();
|
||||
}
|
||||
long expiryDuration = license.expiryDate() - now;
|
||||
if (license.expiryDate() > now) {
|
||||
for (InternalLicensee licensee : registeredLicensees) {
|
||||
licensee.onChange(license, LicenseState.ENABLED);
|
||||
}
|
||||
logger.info("license [{}] - valid", license.uid());
|
||||
final TimeValue delay = TimeValue.timeValueMillis(expiryDuration);
|
||||
// cancel any previous notifications
|
||||
cancelNotifications(expiryNotifications);
|
||||
try {
|
||||
logger.debug("schedule grace notification after [{}] for license [{}]", delay.toString(), license.uid());
|
||||
expiryNotifications.add(threadPool.schedule(delay, executorName(), new LicensingClientNotificationJob()));
|
||||
} catch (EsRejectedExecutionException ex) {
|
||||
logger.debug("couldn't schedule grace notification", ex);
|
||||
}
|
||||
} else if ((license.expiryDate() + gracePeriodDuration.getMillis()) > now) {
|
||||
for (InternalLicensee licensee : registeredLicensees) {
|
||||
licensee.onChange(license, LicenseState.GRACE_PERIOD);
|
||||
}
|
||||
logger.info("license [{}] - grace", license.uid());
|
||||
final TimeValue delay = TimeValue.timeValueMillis(expiryDuration + gracePeriodDuration.getMillis());
|
||||
// cancel any previous notifications
|
||||
cancelNotifications(expiryNotifications);
|
||||
try {
|
||||
logger.debug("schedule expiry notification after [{}] for license [{}]", delay.toString(), license.uid());
|
||||
expiryNotifications.add(threadPool.schedule(delay, executorName(), new LicensingClientNotificationJob()));
|
||||
} catch (EsRejectedExecutionException ex) {
|
||||
logger.debug("couldn't schedule expiry notification", ex);
|
||||
}
|
||||
} else {
|
||||
for (InternalLicensee licensee : registeredLicensees) {
|
||||
licensee.onChange(license, LicenseState.DISABLED);
|
||||
}
|
||||
logger.info("license [{}] - expired", license.uid());
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug("notifying [{}] listeners", registeredLicensees.size());
|
||||
long now = System.currentTimeMillis();
|
||||
if (license.issueDate() > now) {
|
||||
logger.info("license [{}] - invalid", license.uid());
|
||||
return;
|
||||
}
|
||||
long expiryDuration = license.expiryDate() - now;
|
||||
if (license.expiryDate() > now) {
|
||||
for (InternalLicensee licensee : registeredLicensees) {
|
||||
licensee.onChange(license, LicenseState.ENABLED);
|
||||
}
|
||||
if (!license.equals(currentLicense.get())) {
|
||||
currentLicense.set(license);
|
||||
// cancel all scheduled event notifications
|
||||
cancelNotifications(eventNotifications);
|
||||
// schedule expiry callbacks
|
||||
for (ExpirationCallback expirationCallback : this.expirationCallbacks) {
|
||||
final TimeValue delay;
|
||||
if (expirationCallback.matches(license.expiryDate(), now)) {
|
||||
expirationCallback.on(license);
|
||||
TimeValue frequency = expirationCallback.frequency();
|
||||
delay = frequency != null ? frequency : expirationCallback.delay(expiryDuration);
|
||||
} else {
|
||||
delay = expirationCallback.delay(expiryDuration);
|
||||
}
|
||||
if (delay != null) {
|
||||
eventNotifications.add(threadPool.schedule(delay, executorName(), new EventNotificationJob(expirationCallback)));
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("schedule [{}] after [{}]", expirationCallback, delay);
|
||||
}
|
||||
}
|
||||
logger.debug("scheduled expiry callbacks for [{}] expiring after [{}]", license.uid(),
|
||||
TimeValue.timeValueMillis(expiryDuration));
|
||||
logger.info("license [{}] - valid", license.uid());
|
||||
final TimeValue delay = TimeValue.timeValueMillis(expiryDuration);
|
||||
// cancel any previous notifications
|
||||
cancelNotifications(expiryNotifications);
|
||||
try {
|
||||
logger.debug("schedule grace notification after [{}] for license [{}]", delay.toString(), license.uid());
|
||||
expiryNotifications.add(threadPool.schedule(delay, executorName(), new LicensingClientNotificationJob()));
|
||||
} catch (EsRejectedExecutionException ex) {
|
||||
logger.debug("couldn't schedule grace notification", ex);
|
||||
}
|
||||
} else if ((license.expiryDate() + gracePeriodDuration.getMillis()) > now) {
|
||||
for (InternalLicensee licensee : registeredLicensees) {
|
||||
licensee.onChange(license, LicenseState.GRACE_PERIOD);
|
||||
}
|
||||
logger.info("license [{}] - grace", license.uid());
|
||||
final TimeValue delay = TimeValue.timeValueMillis(expiryDuration + gracePeriodDuration.getMillis());
|
||||
// cancel any previous notifications
|
||||
cancelNotifications(expiryNotifications);
|
||||
try {
|
||||
logger.debug("schedule expiry notification after [{}] for license [{}]", delay.toString(), license.uid());
|
||||
expiryNotifications.add(threadPool.schedule(delay, executorName(), new LicensingClientNotificationJob()));
|
||||
} catch (EsRejectedExecutionException ex) {
|
||||
logger.debug("couldn't schedule expiry notification", ex);
|
||||
}
|
||||
} else {
|
||||
for (InternalLicensee licensee : registeredLicensees) {
|
||||
licensee.onChange(license, LicenseState.DISABLED);
|
||||
}
|
||||
logger.info("license [{}] - expired", license.uid());
|
||||
}
|
||||
if (!license.equals(currentLicense.get())) {
|
||||
currentLicense.set(license);
|
||||
// cancel all scheduled event notifications
|
||||
cancelNotifications(eventNotifications);
|
||||
// schedule expiry callbacks
|
||||
for (ExpirationCallback expirationCallback : this.expirationCallbacks) {
|
||||
final TimeValue delay;
|
||||
if (expirationCallback.matches(license.expiryDate(), now)) {
|
||||
expirationCallback.on(license);
|
||||
TimeValue frequency = expirationCallback.frequency();
|
||||
delay = frequency != null ? frequency : expirationCallback.delay(expiryDuration);
|
||||
} else {
|
||||
delay = expirationCallback.delay(expiryDuration);
|
||||
}
|
||||
if (delay != null) {
|
||||
eventNotifications.add(threadPool.schedule(delay, executorName(), new EventNotificationJob(expirationCallback)));
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("schedule [{}] after [{}]", expirationCallback, delay);
|
||||
}
|
||||
}
|
||||
logger.debug("scheduled expiry callbacks for [{}] expiring after [{}]", license.uid(),
|
||||
TimeValue.timeValueMillis(expiryDuration));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -845,6 +850,14 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onRemove() {
|
||||
synchronized (this) {
|
||||
currentLicense = null;
|
||||
currentLicenseState = null;
|
||||
licensee.onChange(Licensee.Status.MISSING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,7 +23,6 @@ import org.elasticsearch.common.xcontent.XContentType;
|
|||
import org.elasticsearch.license.core.License;
|
||||
import org.elasticsearch.license.licensor.LicenseSigner;
|
||||
import org.elasticsearch.license.plugin.action.put.PutLicenseRequest;
|
||||
import org.elasticsearch.license.plugin.core.LicenseState;
|
||||
import org.elasticsearch.license.plugin.core.Licensee;
|
||||
import org.elasticsearch.license.plugin.core.LicensesService;
|
||||
import org.elasticsearch.license.plugin.core.LicensesStatus;
|
||||
|
@ -162,7 +161,7 @@ public class TestUtils {
|
|||
public static class AssertingLicensee implements Licensee {
|
||||
public final ESLogger logger;
|
||||
public final String id;
|
||||
public final List<LicenseState> licenseStates = new CopyOnWriteArrayList<>();
|
||||
public final List<Licensee.Status> statuses = new CopyOnWriteArrayList<>();
|
||||
public final AtomicInteger expirationMessagesCalled = new AtomicInteger(0);
|
||||
public final List<Tuple<License, License>> acknowledgementRequested = new CopyOnWriteArrayList<>();
|
||||
|
||||
|
@ -196,7 +195,7 @@ public class TestUtils {
|
|||
@Override
|
||||
public void onChange(Status status) {
|
||||
assertNotNull(status);
|
||||
licenseStates.add(status.getLicenseState());
|
||||
statuses.add(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,9 @@ import org.elasticsearch.common.unit.TimeValue;
|
|||
import org.elasticsearch.license.plugin.TestUtils.AssertingLicensee;
|
||||
import org.elasticsearch.test.ESSingleNodeTestCase;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.elasticsearch.license.plugin.TestUtils.awaitNoBlock;
|
||||
import static org.elasticsearch.license.plugin.TestUtils.awaitNoPendingTasks;
|
||||
|
@ -41,10 +43,10 @@ public class LicensesExpiryNotificationTests extends ESSingleNodeTestCase {
|
|||
awaitNoBlock(client());
|
||||
licensesService.register(licensee);
|
||||
awaitNoPendingTasks(client());
|
||||
boolean success = awaitBusy(() -> licensee.licenseStates.size() == 3);
|
||||
boolean success = awaitBusy(() -> licensee.statuses.size() == 3);
|
||||
// trail license: enable, grace, disabled
|
||||
assertLicenseStates(licensee, LicenseState.ENABLED, LicenseState.GRACE_PERIOD, LicenseState.DISABLED);
|
||||
assertTrue(dumpLicensingStates(licensee.licenseStates), success);
|
||||
assertTrue(dumpLicensingStates(licensee.statuses), success);
|
||||
licensesService.stop();
|
||||
}
|
||||
|
||||
|
@ -61,10 +63,10 @@ public class LicensesExpiryNotificationTests extends ESSingleNodeTestCase {
|
|||
licensesService.register(licensee1);
|
||||
licensesService.register(licensee2);
|
||||
awaitNoPendingTasks(client());
|
||||
boolean success = awaitBusy(() -> licensee1.licenseStates.size() == 3);
|
||||
assertTrue(dumpLicensingStates(licensee1.licenseStates), success);
|
||||
success = awaitBusy(() -> licensee2.licenseStates.size() == 3);
|
||||
assertTrue(dumpLicensingStates(licensee2.licenseStates), success);
|
||||
boolean success = awaitBusy(() -> licensee1.statuses.size() == 3);
|
||||
assertTrue(dumpLicensingStates(licensee1.statuses), success);
|
||||
success = awaitBusy(() -> licensee2.statuses.size() == 3);
|
||||
assertTrue(dumpLicensingStates(licensee2.statuses), success);
|
||||
// trail license: enable, grace, disabled
|
||||
assertLicenseStates(licensee1, LicenseState.ENABLED, LicenseState.GRACE_PERIOD, LicenseState.DISABLED);
|
||||
assertLicenseStates(licensee2, LicenseState.ENABLED, LicenseState.GRACE_PERIOD, LicenseState.DISABLED);
|
||||
|
@ -81,13 +83,13 @@ public class LicensesExpiryNotificationTests extends ESSingleNodeTestCase {
|
|||
awaitNoBlock(client());
|
||||
licensesService.register(licensee);
|
||||
awaitNoPendingTasks(client());
|
||||
boolean success = awaitBusy(() -> licensee.licenseStates.size() == 1);
|
||||
assertTrue(dumpLicensingStates(licensee.licenseStates), success);
|
||||
boolean success = awaitBusy(() -> licensee.statuses.size() == 1);
|
||||
assertTrue(dumpLicensingStates(licensee.statuses), success);
|
||||
registerAndAckSignedLicenses(licensesService, generateSignedLicense(TimeValue.timeValueSeconds(4)), LicensesStatus.VALID);
|
||||
success = awaitBusy(() -> licensee.licenseStates.size() == 4);
|
||||
success = awaitBusy(() -> licensee.statuses.size() == 4);
|
||||
// trial: enable, signed: enable, signed: grace, signed: disabled
|
||||
assertLicenseStates(licensee, LicenseState.ENABLED, LicenseState.ENABLED, LicenseState.GRACE_PERIOD, LicenseState.DISABLED);
|
||||
assertTrue(dumpLicensingStates(licensee.licenseStates), success);
|
||||
assertTrue(dumpLicensingStates(licensee.statuses), success);
|
||||
licensesService.stop();
|
||||
}
|
||||
|
||||
|
@ -102,10 +104,10 @@ public class LicensesExpiryNotificationTests extends ESSingleNodeTestCase {
|
|||
registerAndAckSignedLicenses(licensesService, generateSignedLicense(TimeValue.timeValueSeconds(2)), LicensesStatus.VALID);
|
||||
licensesService.register(licensee);
|
||||
awaitNoPendingTasks(client());
|
||||
boolean success = awaitBusy(() -> licensee.licenseStates.size() == 3);
|
||||
boolean success = awaitBusy(() -> licensee.statuses.size() == 3);
|
||||
// signed: enable, signed: grace, signed: disabled
|
||||
assertLicenseStates(licensee, LicenseState.ENABLED, LicenseState.GRACE_PERIOD, LicenseState.DISABLED);
|
||||
assertTrue(dumpLicensingStates(licensee.licenseStates), success);
|
||||
assertTrue(dumpLicensingStates(licensee.statuses), success);
|
||||
licensesService.stop();
|
||||
}
|
||||
|
||||
|
@ -123,10 +125,10 @@ public class LicensesExpiryNotificationTests extends ESSingleNodeTestCase {
|
|||
licensesService.register(licensee1);
|
||||
licensesService.register(licensee2);
|
||||
awaitNoPendingTasks(client());
|
||||
boolean success = awaitBusy(() -> licensee1.licenseStates.size() == 3);
|
||||
assertTrue(dumpLicensingStates(licensee1.licenseStates), success);
|
||||
success = awaitBusy(() -> licensee2.licenseStates.size() == 3);
|
||||
assertTrue(dumpLicensingStates(licensee2.licenseStates), success);
|
||||
boolean success = awaitBusy(() -> licensee1.statuses.size() == 3);
|
||||
assertTrue(dumpLicensingStates(licensee1.statuses), success);
|
||||
success = awaitBusy(() -> licensee2.statuses.size() == 3);
|
||||
assertTrue(dumpLicensingStates(licensee2.statuses), success);
|
||||
// signed license: enable, grace, disabled
|
||||
assertLicenseStates(licensee1, LicenseState.ENABLED, LicenseState.GRACE_PERIOD, LicenseState.DISABLED);
|
||||
assertLicenseStates(licensee2, LicenseState.ENABLED, LicenseState.GRACE_PERIOD, LicenseState.DISABLED);
|
||||
|
@ -145,18 +147,18 @@ public class LicensesExpiryNotificationTests extends ESSingleNodeTestCase {
|
|||
licensesService.register(licensee);
|
||||
awaitNoPendingTasks(client());
|
||||
// trial license enabled
|
||||
boolean success = awaitBusy(() -> licensee.licenseStates.size() == 1);
|
||||
assertTrue(dumpLicensingStates(licensee.licenseStates), success);
|
||||
boolean success = awaitBusy(() -> licensee.statuses.size() == 1);
|
||||
assertTrue(dumpLicensingStates(licensee.statuses), success);
|
||||
registerAndAckSignedLicenses(licensesService, generateSignedLicense("basic", TimeValue.timeValueSeconds(3)), LicensesStatus.VALID);
|
||||
// signed license enabled
|
||||
success = awaitBusy(() -> licensee.licenseStates.size() == 2);
|
||||
assertTrue(dumpLicensingStates(licensee.licenseStates), success);
|
||||
success = awaitBusy(() -> licensee.statuses.size() == 2);
|
||||
assertTrue(dumpLicensingStates(licensee.statuses), success);
|
||||
registerAndAckSignedLicenses(licensesService, generateSignedLicense("gold", TimeValue.timeValueSeconds(2)), LicensesStatus.VALID);
|
||||
// second signed license enabled, grace and expired
|
||||
success = awaitBusy(() ->licensee.licenseStates.size() == 5);
|
||||
success = awaitBusy(() ->licensee.statuses.size() == 5);
|
||||
assertLicenseStates(licensee, LicenseState.ENABLED, LicenseState.ENABLED, LicenseState.ENABLED, LicenseState.GRACE_PERIOD,
|
||||
LicenseState.DISABLED);
|
||||
assertTrue(dumpLicensingStates(licensee.licenseStates), success);
|
||||
assertTrue(dumpLicensingStates(licensee.statuses), success);
|
||||
licensesService.stop();
|
||||
}
|
||||
|
||||
|
@ -171,33 +173,39 @@ public class LicensesExpiryNotificationTests extends ESSingleNodeTestCase {
|
|||
awaitNoBlock(client());
|
||||
licensesService.register(licensee);
|
||||
// trial license: enabled, grace, disabled
|
||||
boolean success = awaitBusy(() -> licensee.licenseStates.size() == 3);
|
||||
boolean success = awaitBusy(() -> licensee.statuses.size() == 3);
|
||||
|
||||
assertTrue(dumpLicensingStates(licensee.licenseStates), success);
|
||||
assertTrue(dumpLicensingStates(licensee.statuses), success);
|
||||
// install license
|
||||
registerAndAckSignedLicenses(licensesService, generateSignedLicense("basic", TimeValue.timeValueSeconds(2)), LicensesStatus.VALID);
|
||||
// trial license: enabled, grace, disabled, signed license: enabled, grace, disabled
|
||||
success = awaitBusy(() -> licensee.licenseStates.size() == 6);
|
||||
success = awaitBusy(() -> licensee.statuses.size() == 6);
|
||||
assertLicenseStates(licensee, LicenseState.ENABLED, LicenseState.GRACE_PERIOD, LicenseState.DISABLED, LicenseState.ENABLED,
|
||||
LicenseState.GRACE_PERIOD, LicenseState.DISABLED);
|
||||
assertTrue(dumpLicensingStates(licensee.licenseStates), success);
|
||||
assertTrue(dumpLicensingStates(licensee.statuses), success);
|
||||
licensesService.stop();
|
||||
}
|
||||
|
||||
private void assertLicenseStates(AssertingLicensee licensee, LicenseState... states) {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("Actual: ");
|
||||
msg.append(dumpLicensingStates(licensee.licenseStates));
|
||||
msg.append(dumpLicensingStates(licensee.statuses));
|
||||
msg.append(" Expected: ");
|
||||
msg.append(dumpLicensingStates(states));
|
||||
assertThat(msg.toString(), licensee.licenseStates.size(), equalTo(states.length));
|
||||
assertThat(msg.toString(), licensee.statuses.size(), equalTo(states.length));
|
||||
for (int i = 0; i < states.length; i++) {
|
||||
assertThat(msg.toString(), licensee.licenseStates.get(i), equalTo(states[i]));
|
||||
assertThat(msg.toString(), licensee.statuses.get(i), equalTo(states[i]));
|
||||
}
|
||||
}
|
||||
|
||||
private String dumpLicensingStates(List<LicenseState> states) {
|
||||
return dumpLicensingStates(states.toArray(new LicenseState[states.size()]));
|
||||
private String dumpLicensingStates(List<Licensee.Status> statuses) {
|
||||
return dumpLicensingStates(statuses.toArray(new Licensee.Status[statuses.size()]));
|
||||
}
|
||||
|
||||
|
||||
private String dumpLicensingStates(Licensee.Status... statuses) {
|
||||
return dumpLicensingStates((LicenseState[]) Arrays.asList(statuses).stream()
|
||||
.map(Licensee.Status::getLicenseState).collect(Collectors.toList()).toArray());
|
||||
}
|
||||
|
||||
private String dumpLicensingStates(LicenseState... states) {
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
package org.elasticsearch.license.plugin.core;
|
||||
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.cluster.ack.ClusterStateUpdateResponse;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.license.core.License;
|
||||
import org.elasticsearch.license.plugin.TestUtils;
|
||||
|
@ -20,9 +20,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
|
||||
import static org.elasticsearch.license.plugin.TestUtils.generateSignedLicense;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
public class LicensesManagerServiceTests extends ESSingleNodeTestCase {
|
||||
|
||||
static {
|
||||
MetaData.registerPrototype(LicensesMetaData.TYPE, LicensesMetaData.PROTO);
|
||||
}
|
||||
|
@ -111,6 +114,53 @@ public class LicensesManagerServiceTests extends ESSingleNodeTestCase {
|
|||
assertThat(licensesMetaData.getLicense(), equalTo(LicensesMetaData.LICENSE_TOMBSTONE));
|
||||
}
|
||||
|
||||
public void testRemoveLicensesAndLicenseeNotification() throws Exception {
|
||||
LicensesService licensesService = getInstanceFromNode(LicensesService.class);
|
||||
licensesService.start();
|
||||
ClusterService clusterService = getInstanceFromNode(ClusterService.class);
|
||||
|
||||
// generate a trial license for one feature
|
||||
TestUtils.AssertingLicensee licensee = new TestUtils.AssertingLicensee("", logger);
|
||||
licensesService.register(licensee);
|
||||
|
||||
// we should get a trial license to begin with
|
||||
assertBusy(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
assertThat(licensee.statuses, hasSize(1));
|
||||
assertThat(licensee.statuses.get(0).getMode(), is(License.OperationMode.TRIAL));
|
||||
assertThat(licensee.statuses.get(0).getLicenseState(), is(LicenseState.ENABLED));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// generate signed licenses
|
||||
License license = generateSignedLicense(TimeValue.timeValueHours(1));
|
||||
TestUtils.registerAndAckSignedLicenses(licensesService, license, LicensesStatus.VALID);
|
||||
assertBusy(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
assertThat(licensee.statuses, hasSize(2));
|
||||
assertThat(licensee.statuses.get(1).getMode(), not(License.OperationMode.TRIAL));
|
||||
assertThat(licensee.statuses.get(1).getLicenseState(), is(LicenseState.ENABLED));
|
||||
}
|
||||
});
|
||||
|
||||
// remove signed licenses
|
||||
removeAndAckSignedLicenses(licensesService);
|
||||
assertBusy(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
assertThat(licensee.statuses, hasSize(3));
|
||||
}
|
||||
});
|
||||
LicensesMetaData licensesMetaData = clusterService.state().metaData().custom(LicensesMetaData.TYPE);
|
||||
assertThat(licensesMetaData.getLicense(), is(LicensesMetaData.LICENSE_TOMBSTONE));
|
||||
assertThat(licensee.statuses, hasSize(3));
|
||||
assertThat(licensee.statuses.get(2).getLicenseState(), is(LicenseState.DISABLED));
|
||||
assertThat(licensee.statuses.get(2).getMode(), is(License.OperationMode.MISSING));
|
||||
}
|
||||
|
||||
private void removeAndAckSignedLicenses(final LicensesService licensesService) {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final AtomicBoolean success = new AtomicBoolean(false);
|
||||
|
|
|
@ -36,7 +36,7 @@ public class MonitoringFeatureSet implements XPackFeatureSet {
|
|||
|
||||
@Override
|
||||
public boolean available() {
|
||||
return licensee != null && licensee.available();
|
||||
return licensee != null && licensee.isAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -75,12 +75,12 @@ public class MonitoringLicensee extends AbstractLicenseeComponent<MonitoringLice
|
|||
}
|
||||
|
||||
/**
|
||||
* Monitoring is always available regardless of the license type (operation mode)
|
||||
* Monitoring is always available as long as there is a valid license
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public boolean available() {
|
||||
return true;
|
||||
public boolean isAvailable() {
|
||||
return status.getMode() != OperationMode.MISSING && status.getLicenseState() != LicenseState.DISABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,7 +36,7 @@ public class WatcherFeatureSet implements XPackFeatureSet {
|
|||
|
||||
@Override
|
||||
public boolean available() {
|
||||
return licensee != null && licensee.available();
|
||||
return licensee != null && licensee.isAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -62,12 +62,22 @@ public class WatcherLicensee extends AbstractLicenseeComponent<WatcherLicensee>
|
|||
*
|
||||
* @return {@code true} as long as the license is valid. Otherwise {@code false}.
|
||||
*/
|
||||
public boolean available() {
|
||||
public boolean isAvailable() {
|
||||
// status is volatile, so a local variable is used for a consistent view
|
||||
Status localStatus = status;
|
||||
|
||||
return localStatus.getLicenseState() != LicenseState.DISABLED && (localStatus.getMode() == OperationMode.TRIAL ||
|
||||
localStatus.getMode() == OperationMode.GOLD || localStatus.getMode() == OperationMode.PLATINUM);
|
||||
if (localStatus.getLicenseState() == LicenseState.DISABLED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (localStatus.getMode()) {
|
||||
case TRIAL:
|
||||
case GOLD:
|
||||
case PLATINUM:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isExecutingActionsAllowed() {
|
||||
|
@ -84,7 +94,7 @@ public class WatcherLicensee extends AbstractLicenseeComponent<WatcherLicensee>
|
|||
|
||||
|
||||
public boolean isWatcherTransportActionAllowed() {
|
||||
return available();
|
||||
return isAvailable();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue