From 1964ebc6f2cfdf1db96f38e4dba16b53c59e512c Mon Sep 17 00:00:00 2001 From: Areek Zillur Date: Mon, 20 Oct 2014 15:42:23 -0400 Subject: [PATCH] Consumer Plugin integration tests; Represent feature as string; proper handling of trial licenses Original commit: elastic/x-pack-elasticsearch@d86f98a435c8b985c97acc9de1823eabf7784eee --- .../license/core/ESLicenses.java | 35 +---- .../license/core/LicenseBuilders.java | 18 +-- .../license/core/LicenseUtils.java | 6 +- .../license/licensor/ESLicenseSigner.java | 6 +- .../tools/FileBasedESLicenseProvider.java | 4 +- .../license/manager/ESLicenseManager.java | 43 +++--- .../license/manager/ESLicenseProvider.java | 3 +- .../license/plugin/action/Utils.java | 4 +- .../plugin/core/LicensesManagerService.java | 4 + .../license/plugin/core/LicensesService.java | 126 ++++++++---------- .../plugin/core/trial/TrialLicenseUtils.java | 9 +- .../plugin/core/trial/TrialLicenses.java | 6 +- .../core/trial/TrialLicensesBuilder.java | 15 +-- .../plugin/rest/RestDeleteLicenseAction.java | 23 +--- .../license/AbstractLicensingTestBase.java | 2 +- .../org/elasticsearch/license/TestUtils.java | 18 +-- .../licensor/LicenseGenerationTests.java | 51 ++----- .../LicenseVerificationToolTests.java | 28 ++-- .../manager/LicenseVerificationTests.java | 40 +++--- .../license/plugin/LicenseTransportTests.java | 10 +- .../LicensesPluginIntegrationTests.java | 57 ++++++++ .../license/plugin/LicensesServiceTests.java | 68 +++++++--- .../license/plugin/TestConsumerPlugin.java | 49 +++++++ .../license/plugin/TestPluginService.java | 70 ++++++++++ 24 files changed, 408 insertions(+), 287 deletions(-) create mode 100644 src/test/java/org/elasticsearch/license/plugin/LicensesPluginIntegrationTests.java create mode 100644 src/test/java/org/elasticsearch/license/plugin/TestConsumerPlugin.java create mode 100644 src/test/java/org/elasticsearch/license/plugin/TestPluginService.java diff --git a/src/main/java/org/elasticsearch/license/core/ESLicenses.java b/src/main/java/org/elasticsearch/license/core/ESLicenses.java index 83bd4417659..dc229403ab3 100644 --- a/src/main/java/org/elasticsearch/license/core/ESLicenses.java +++ b/src/main/java/org/elasticsearch/license/core/ESLicenses.java @@ -25,12 +25,13 @@ public interface ESLicenses extends Iterable { /** * @return Set of features for which there exists an underlying license */ - public Set features(); + public Set features(); /** * @return a license for a code>featureType< + * @param feature */ - public ESLicense get(FeatureType featureType); + public ESLicense get(String feature); /** * Enum for License Type @@ -103,34 +104,6 @@ public interface ESLicenses extends Iterable { } } - /** - * Enum for License FeatureType - */ - public enum FeatureType { - SHIELD("shield"), - MARVEL("marvel"); - - private final String name; - - private FeatureType(String name) { - this.name = name; - } - - public String string() { - return name; - } - - public static FeatureType fromString(String featureType) { - if (featureType.equalsIgnoreCase(SHIELD.string())) { - return SHIELD; - } else if (featureType.equalsIgnoreCase(MARVEL.string())) { - return MARVEL; - } else { - throw new IllegalArgumentException("Invalid FeatureType=" + featureType); - } - } - } - /** * Interface representing all the license fields */ @@ -159,7 +132,7 @@ public interface ESLicenses extends Iterable { /** * @return the featureType for the license [shield, marvel] */ - public FeatureType feature(); + public String feature(); /** * @return the expiry date in milliseconds diff --git a/src/main/java/org/elasticsearch/license/core/LicenseBuilders.java b/src/main/java/org/elasticsearch/license/core/LicenseBuilders.java index 78b8f485e94..29b9877a097 100644 --- a/src/main/java/org/elasticsearch/license/core/LicenseBuilders.java +++ b/src/main/java/org/elasticsearch/license/core/LicenseBuilders.java @@ -49,7 +49,7 @@ public class LicenseBuilders { } } - public static ESLicenses removeFeatures(ESLicenses licenses, Set featureTypesToDelete) { + public static ESLicenses removeFeatures(ESLicenses licenses, Set featureTypesToDelete) { final LicensesBuilder licensesBuilder = licensesBuilder(); for (ESLicense license : licenses) { if (!featureTypesToDelete.contains(license.feature())) { @@ -60,7 +60,7 @@ public class LicenseBuilders { } public static class LicensesBuilder { - private Map licenseMap = new HashMap<>(); + private Map licenseMap = new HashMap<>(); public LicensesBuilder() { } @@ -98,13 +98,13 @@ public class LicenseBuilders { } @Override - public Set features() { + public Set features() { return licenseMap.keySet(); } @Override - public ESLicense get(FeatureType featureType) { - return licenseMap.get(featureType); + public ESLicense get(String feature) { + return licenseMap.get(feature); } @Override @@ -124,7 +124,7 @@ public class LicenseBuilders { * @param license license in question */ private void putIfAppropriate(ESLicense license) { - final FeatureType featureType = license.feature(); + final String featureType = license.feature(); if (licenseMap.containsKey(featureType)) { final ESLicense previousLicense = licenseMap.get(featureType); if (license.expiryDate() > previousLicense.expiryDate()) { @@ -143,7 +143,7 @@ public class LicenseBuilders { private long issueDate = -1; private Type type; private SubscriptionType subscriptionType = SubscriptionType.DEFAULT; - private FeatureType feature; + private String feature; private String signature; private long expiryDate = -1; private int maxNodes; @@ -185,7 +185,7 @@ public class LicenseBuilders { return this; } - public LicenseBuilder feature(FeatureType feature) { + public LicenseBuilder feature(String feature) { this.feature = feature; return this; } @@ -251,7 +251,7 @@ public class LicenseBuilders { } @Override - public FeatureType feature() { + public String feature() { return feature; } diff --git a/src/main/java/org/elasticsearch/license/core/LicenseUtils.java b/src/main/java/org/elasticsearch/license/core/LicenseUtils.java index a644bc39240..153e626802a 100644 --- a/src/main/java/org/elasticsearch/license/core/LicenseUtils.java +++ b/src/main/java/org/elasticsearch/license/core/LicenseUtils.java @@ -34,7 +34,7 @@ public class LicenseUtils { generator.writeStringField("issued_to", esLicense.issuedTo()); generator.writeStringField("issue_date", DateUtils.dateStringFromLongDate(esLicense.issueDate())); generator.writeStringField("expiry_date", DateUtils.dateStringFromLongDate(esLicense.expiryDate())); - generator.writeStringField("feature", esLicense.feature().string()); + generator.writeStringField("feature", esLicense.feature()); generator.writeNumberField("max_nodes", esLicense.maxNodes()); generator.writeStringField("signature", esLicense.signature()); } @@ -101,7 +101,7 @@ public class LicenseUtils { .issueDate(getValueAsDate(licenseNode, "issue_date")) .type(ESLicenses.Type.fromString(getValueAsString(licenseNode, "type"))) .subscriptionType(ESLicenses.SubscriptionType.fromString(getValueAsString(licenseNode, "subscription_type"))) - .feature(ESLicenses.FeatureType.fromString(getValueAsString(licenseNode, "feature"))) + .feature(getValueAsString(licenseNode, "feature")) .expiryDate(getValueAsExpiryDate(licenseNode, "expiry_date")) .maxNodes(getValueAsInt(licenseNode, "max_nodes")) .signature(getValueAsString(licenseNode, "signature", true)) @@ -168,7 +168,7 @@ public class LicenseUtils { printValue(" subscription_type", license.subscriptionType().string()); printValue(" issueDate", DateUtils.dateStringFromLongDate(license.issueDate())); printValue(" issuedTo", license.issuedTo()); - printValue(" feature", license.feature().string()); + printValue(" feature", license.feature()); printValue(" maxNodes", license.maxNodes()); printValue(" expiryDate", DateUtils.dateStringFromLongDate(license.expiryDate())); printValue(" signature", license.signature()); diff --git a/src/main/java/org/elasticsearch/license/licensor/ESLicenseSigner.java b/src/main/java/org/elasticsearch/license/licensor/ESLicenseSigner.java index 31f730a72d9..855c45a35a4 100644 --- a/src/main/java/org/elasticsearch/license/licensor/ESLicenseSigner.java +++ b/src/main/java/org/elasticsearch/license/licensor/ESLicenseSigner.java @@ -6,6 +6,7 @@ package org.elasticsearch.license.licensor; import net.nicholaswilliams.java.licensing.License; +import net.nicholaswilliams.java.licensing.SignedLicense; import net.nicholaswilliams.java.licensing.encryption.Hasher; import net.nicholaswilliams.java.licensing.encryption.PasswordProvider; import net.nicholaswilliams.java.licensing.encryption.PrivateKeyDataProvider; @@ -91,7 +92,7 @@ public class ESLicenseSigner { .withProductKey(esLicense.uid()) .withHolder(esLicense.issuedTo()) .withIssuer(esLicense.issuer()) - .addFeature(esLicense.feature().string(), esLicense.expiryDate()) + .addFeature("feature:" + esLicense.feature(), esLicense.expiryDate()) .addFeature("maxNodes:" + String.valueOf(esLicense.maxNodes())) .addFeature("type:" + esLicense.type().string()) .addFeature("subscription_type:" + esLicense.subscriptionType().string()); @@ -101,7 +102,8 @@ public class ESLicenseSigner { final byte[] magic = new byte[MAGIC_LENGTH]; Random random = new Random(); random.nextBytes(magic); - final byte[] licenseSignature = licenseCreator.signAndSerializeLicense(license); + //final SignedLicense signedLicense = licenseCreator.signLicense(license); + final byte[] licenseSignature = licenseCreator.signAndSerializeLicense(license);//signedLicense.getSignatureContent(); final byte[] hash = Hasher.hash(Base64.encodeBase64String( Files.readAllBytes(publicKeyPath)) ).getBytes(Charset.forName("UTF-8")); diff --git a/src/main/java/org/elasticsearch/license/licensor/tools/FileBasedESLicenseProvider.java b/src/main/java/org/elasticsearch/license/licensor/tools/FileBasedESLicenseProvider.java index bd97847c4cf..1b3babce660 100644 --- a/src/main/java/org/elasticsearch/license/licensor/tools/FileBasedESLicenseProvider.java +++ b/src/main/java/org/elasticsearch/license/licensor/tools/FileBasedESLicenseProvider.java @@ -25,8 +25,8 @@ public class FileBasedESLicenseProvider implements ESLicenseProvider { } @Override - public ESLicenses.ESLicense getESLicense(ESLicenses.FeatureType featureType) { - return esLicenses.get(featureType); + public ESLicenses.ESLicense getESLicense(String feature) { + return esLicenses.get(feature); } @Override diff --git a/src/main/java/org/elasticsearch/license/manager/ESLicenseManager.java b/src/main/java/org/elasticsearch/license/manager/ESLicenseManager.java index 3d1d7e90cb3..e6148420c69 100644 --- a/src/main/java/org/elasticsearch/license/manager/ESLicenseManager.java +++ b/src/main/java/org/elasticsearch/license/manager/ESLicenseManager.java @@ -80,8 +80,8 @@ public class ESLicenseManager { public void verifyLicenses(ESLicenses esLicenses) { try { - for (FeatureType featureType : esLicenses.features()) { - ESLicense esLicense = esLicenses.get(featureType); + for (String feature : esLicenses.features()) { + ESLicense esLicense = esLicenses.get(feature); // verify signature final License license = this.licenseManager.decryptAndVerifyLicense( extractSignedLicence(esLicense.signature())); @@ -94,7 +94,7 @@ public class ESLicenseManager { } catch (ExpiredLicenseException e) { throw new InvalidLicenseException("Expired License"); } catch (InvalidLicenseException e) { - throw new InvalidLicenseException("Invalid License"); + throw new InvalidLicenseException("Invalid License: " + e.getCause()); } } @@ -132,6 +132,7 @@ public class ESLicenseManager { String maxNodesPrefix = "maxNodes:"; String typePrefix = "type:"; String subscriptionTypePrefix = "subscription_type:"; + String featurePrefix = "feature:"; boolean maxNodesValid = false; boolean featureValid = false; boolean typeValid = false; @@ -145,8 +146,9 @@ public class ESLicenseManager { typeValid = eslicense.type() == Type.fromString(featureName.substring(typePrefix.length())); } else if (featureName.startsWith(subscriptionTypePrefix)) { subscriptionTypeValid = eslicense.subscriptionType() == SubscriptionType.fromString(featureName.substring(subscriptionTypePrefix.length())); - } else { - featureValid = feature.getName().equals(eslicense.feature().string()) + } else if (featureName.startsWith(featurePrefix)) { + String featureValue = featureName.substring(featurePrefix.length()); + featureValid = featureValue.equals(eslicense.feature()) && feature.getGoodBeforeDate() == eslicense.expiryDate(); } } @@ -160,8 +162,8 @@ public class ESLicenseManager { throw new InvalidLicenseException("Invalid License"); } } - private License getLicense(FeatureType featureType) { - ESLicense esLicense = licenseProvider.getESLicense(featureType); + private License getLicense(String feature) { + ESLicense esLicense = licenseProvider.getESLicense(feature); if (esLicense != null) { String signature = esLicense.signature(); License license = this.licenseManager.decryptAndVerifyLicense(extractSignedLicence(signature)); @@ -173,11 +175,11 @@ public class ESLicenseManager { //TODO wrap License validation methods so a plugin does not have to provide featureType param - public boolean hasLicenseForFeature(FeatureType featureType) { + public boolean hasLicenseForFeature(String feature) { try { - final License license = getLicense(featureType); + final License license = getLicense(feature); if (license != null) { - return license.hasLicenseForFeature(featureType.string()); + return license.hasLicenseForFeature("feature:" + feature); } return false; } catch (ExpiredLicenseException e) { @@ -187,42 +189,42 @@ public class ESLicenseManager { } } - public boolean hasLicenseForNodes(FeatureType featureType, int nodes) { + public boolean hasLicenseForNodes(String featureType, int nodes) { ESLicense esLicense = getESLicense(featureType); return esLicense.maxNodes() >= nodes; } - public String getIssuerForLicense(FeatureType featureType) { + public String getIssuerForLicense(String featureType) { final License license = getLicense(featureType); return license.getIssuer(); } - public long getIssueDateForLicense(FeatureType featureType) { + public long getIssueDateForLicense(String featureType) { final License license = getLicense(featureType); return license.getIssueDate(); } - public long getExpiryDateForLicense(FeatureType featureType) { + public long getExpiryDateForLicense(String featureType) { final License license = getLicense(featureType); return license.getGoodBeforeDate(); } - public String getIssuedToForLicense(FeatureType featureType) { + public String getIssuedToForLicense(String featureType) { final License license = getLicense(featureType); return license.getHolder(); } - public Type getTypeForLicense(FeatureType featureType) { + public Type getTypeForLicense(String featureType) { ESLicense esLicense = getESLicense(featureType); return esLicense.type(); } - public SubscriptionType getSubscriptionTypeForLicense(FeatureType featureType) { + public SubscriptionType getSubscriptionTypeForLicense(String featureType) { ESLicense esLicense = getESLicense(featureType); return esLicense.subscriptionType(); } - ESLicense getESLicense(FeatureType featureType) { + ESLicense getESLicense(String featureType) { final License license = getLicense(featureType); return convertToESLicense(license); } @@ -252,6 +254,7 @@ public class ESLicenseManager { String maxNodesPrefix = "maxNodes:"; String typePrefix = "type:"; String subscriptionTypePrefix = "subscription_type:"; + String featurePrefix = "feature:"; for (License.Feature feature : license.getFeatures()) { String featureName = feature.getName(); if (featureName.startsWith(maxNodesPrefix)) { @@ -260,8 +263,8 @@ public class ESLicenseManager { licenseBuilder.type(Type.fromString(featureName.substring(typePrefix.length()))); } else if (featureName.startsWith(subscriptionTypePrefix)) { licenseBuilder.subscriptionType(SubscriptionType.fromString(featureName.substring(subscriptionTypePrefix.length()))); - } else { - licenseBuilder.feature(FeatureType.fromString(featureName)); + } else if (featureName.startsWith(featurePrefix)) { + licenseBuilder.feature(featureName.substring(featurePrefix.length())); } } return licenseBuilder.build(); diff --git a/src/main/java/org/elasticsearch/license/manager/ESLicenseProvider.java b/src/main/java/org/elasticsearch/license/manager/ESLicenseProvider.java index ec79c3decb5..6303f75c916 100644 --- a/src/main/java/org/elasticsearch/license/manager/ESLicenseProvider.java +++ b/src/main/java/org/elasticsearch/license/manager/ESLicenseProvider.java @@ -8,11 +8,10 @@ package org.elasticsearch.license.manager; import org.elasticsearch.license.core.ESLicenses; import static org.elasticsearch.license.core.ESLicenses.ESLicense; -import static org.elasticsearch.license.core.ESLicenses.FeatureType; public interface ESLicenseProvider { - ESLicense getESLicense(FeatureType featureType); + ESLicense getESLicense(String feature); ESLicenses getEffectiveLicenses(); } diff --git a/src/main/java/org/elasticsearch/license/plugin/action/Utils.java b/src/main/java/org/elasticsearch/license/plugin/action/Utils.java index 4493078c8ff..766b6ab5d0b 100644 --- a/src/main/java/org/elasticsearch/license/plugin/action/Utils.java +++ b/src/main/java/org/elasticsearch/license/plugin/action/Utils.java @@ -60,7 +60,7 @@ public class Utils { builder.put(LicenseFields.TYPE, esLicense.type().string()); builder.put(LicenseFields.SUBSCRIPTION_TYPE, esLicense.subscriptionType().string()); builder.put(LicenseFields.ISSUE_DATE, esLicense.issueDate()); - builder.put(LicenseFields.FEATURE, esLicense.feature().string()); + builder.put(LicenseFields.FEATURE, esLicense.feature()); builder.put(LicenseFields.EXPIRY_DATE, esLicense.expiryDate()); builder.put(LicenseFields.MAX_NODES, esLicense.maxNodes()); builder.put(LicenseFields.ISSUED_TO, esLicense.issuedTo()); @@ -74,7 +74,7 @@ public class Utils { .type(Type.fromString((String) map.get(LicenseFields.TYPE))) .subscriptionType(SubscriptionType.fromString((String) map.get(LicenseFields.SUBSCRIPTION_TYPE))) .issueDate((long) map.get(LicenseFields.ISSUE_DATE)) - .feature(FeatureType.fromString((String) map.get(LicenseFields.FEATURE))) + .feature((String) map.get(LicenseFields.FEATURE)) .expiryDate((long) map.get(LicenseFields.EXPIRY_DATE)) .maxNodes((int) map.get(LicenseFields.MAX_NODES)) .issuedTo((String) map.get(LicenseFields.ISSUED_TO)) diff --git a/src/main/java/org/elasticsearch/license/plugin/core/LicensesManagerService.java b/src/main/java/org/elasticsearch/license/plugin/core/LicensesManagerService.java index 836db9eb73b..67b0dd8bf67 100644 --- a/src/main/java/org/elasticsearch/license/plugin/core/LicensesManagerService.java +++ b/src/main/java/org/elasticsearch/license/plugin/core/LicensesManagerService.java @@ -11,6 +11,8 @@ import org.elasticsearch.common.inject.ImplementedBy; import org.elasticsearch.common.inject.Singleton; import org.elasticsearch.license.core.ESLicenses; +import java.util.Set; + import static org.elasticsearch.license.plugin.core.LicensesService.DeleteLicenseRequestHolder; import static org.elasticsearch.license.plugin.core.LicensesService.PutLicenseRequestHolder; @@ -22,4 +24,6 @@ public interface LicensesManagerService { public void unregisterLicenses(final DeleteLicenseRequestHolder requestHolder, final ActionListener listener); public LicensesStatus checkLicenses(ESLicenses licenses); + + public Set enabledFeatures(); } diff --git a/src/main/java/org/elasticsearch/license/plugin/core/LicensesService.java b/src/main/java/org/elasticsearch/license/plugin/core/LicensesService.java index 0eaf0a963ff..bfbe7fd51a3 100644 --- a/src/main/java/org/elasticsearch/license/plugin/core/LicensesService.java +++ b/src/main/java/org/elasticsearch/license/plugin/core/LicensesService.java @@ -36,16 +36,13 @@ import org.elasticsearch.license.plugin.core.trial.TrialLicensesBuilder; import org.elasticsearch.threadpool.ThreadPool; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.atomic.AtomicBoolean; -import static org.elasticsearch.license.core.ESLicenses.FeatureType; import static org.elasticsearch.license.plugin.core.trial.TrialLicenses.TrialLicense; -import static org.elasticsearch.license.plugin.core.trial.TrialLicensesBuilder.trialLicensesBuilder; /** * Service responsible for managing {@link org.elasticsearch.license.plugin.core.LicensesMetaData} @@ -110,20 +107,6 @@ public class LicensesService extends AbstractLifecycleComponent return ClusterState.builder(currentState).metaData(mdBuilder).build(); } - /** - * If signed license is found for any feature, remove the trial license for it - * NOTE: not used - * TODO: figure out desired behaviour for deleting trial licenses - */ - private TrialLicenses reduceTrialLicenses(ESLicenses currentLicenses, TrialLicenses currentTrialLicenses) { - TrialLicensesBuilder builder = trialLicensesBuilder(); - for (TrialLicense currentTrialLicense : currentTrialLicenses) { - if (currentLicenses.get(currentTrialLicense.feature()) == null) { - builder.license(currentTrialLicense); - } - } - return builder.build(); - } }); return LicensesStatus.VALID; } @@ -131,7 +114,6 @@ public class LicensesService extends AbstractLifecycleComponent @Override public void unregisterLicenses(final DeleteLicenseRequestHolder requestHolder, final ActionListener listener) { final DeleteLicenseRequest request = requestHolder.request; - final Set featuresToDelete = asFeatureTypes(request.features()); clusterService.submitStateUpdateTask(requestHolder.source, new AckedClusterStateUpdateTask(request, listener) { @Override protected ClusterStateUpdateResponse newResponse(boolean acknowledged) { @@ -144,7 +126,7 @@ public class LicensesService extends AbstractLifecycleComponent MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData()); LicensesMetaData currentLicenses = metaData.custom(LicensesMetaData.TYPE); final LicensesWrapper licensesWrapper = LicensesWrapper.wrap(currentLicenses); - licensesWrapper.removeFeatures(esLicenseManager, featuresToDelete); + licensesWrapper.removeFeatures(esLicenseManager, request.features()); mdBuilder.putCustom(LicensesMetaData.TYPE, licensesWrapper.createLicensesMetaData()); return ClusterState.builder(currentState).metaData(mdBuilder).build(); } @@ -164,12 +146,24 @@ public class LicensesService extends AbstractLifecycleComponent return status; } + @Override + public Set enabledFeatures() { + Set enabledFeatures = Sets.newHashSet(); + if (registeredListeners != null) { + for (ListenerHolder holder : registeredListeners) { + if (holder.enabled.get()) { + enabledFeatures.add(holder.feature); + } + } + } + return enabledFeatures; + } + private void registerTrialLicense(final TrialLicense trialLicense) { clusterService.submitStateUpdateTask("register trial license []", new ProcessedClusterStateUpdateTask() { @Override public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { - } @Override @@ -178,7 +172,8 @@ public class LicensesService extends AbstractLifecycleComponent MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData()); LicensesMetaData currentLicenses = metaData.custom(LicensesMetaData.TYPE); final LicensesWrapper licensesWrapper = LicensesWrapper.wrap(currentLicenses); - if (trialLicenseCheck(trialLicense.feature().string())) { + // do not generate a trial license for a feature that already has a signed license + if (!esLicenseManager.hasLicenseForFeature(trialLicense.feature())) { licensesWrapper.addTrialLicense(trialLicense); } mdBuilder.putCustom(LicensesMetaData.TYPE, licensesWrapper.createLicensesMetaData()); @@ -187,24 +182,7 @@ public class LicensesService extends AbstractLifecycleComponent @Override public void onFailure(String source, @Nullable Throwable t) { - //TODO - logger.info("LICENSING" + source, t); - } - - private boolean trialLicenseCheck(String feature) { - // check if actual license exists - if (esLicenseManager.hasLicenseForFeature(FeatureType.fromString(feature))) { - return false; - } - // check if trial license for feature exists - for (ListenerHolder holder : registeredListeners) { - if (holder.feature.equals(feature) && holder.registered.get()) { - if (holder.trialLicenseGenerated.compareAndSet(false, true)) { - return true; - } - } - } - return false; + logger.info("LicensesService: " + source, t); } }); } @@ -228,7 +206,15 @@ public class LicensesService extends AbstractLifecycleComponent notificationScheduler = null; } clusterService.remove(this); - registeredListeners.clear(); + + if (registeredListeners != null) { + // notify features to be disabled + for (ListenerHolder holder : registeredListeners) { + holder.disableFeatureIfNeeded(); + } + // clear all handlers + registeredListeners.clear(); + } } @Override @@ -259,7 +245,7 @@ public class LicensesService extends AbstractLifecycleComponent private void registerListeners(LicensesMetaData currentMetaData) { for (ListenerHolder listenerHolder : registeredListeners) { if (listenerHolder.registered.compareAndSet(false, true)) { - if (!esLicenseManager.hasLicenseForFeature(FeatureType.fromString(listenerHolder.feature))) { + if (!esLicenseManager.hasLicenseForFeature(listenerHolder.feature)) { // does not have actual license so generate a trial license TrialLicenseOptions options = listenerHolder.trialLicenseOptions; if (options != null) { @@ -298,8 +284,8 @@ public class LicensesService extends AbstractLifecycleComponent } @Override - public ESLicenses.ESLicense getESLicense(FeatureType featureType) { - return getEffectiveLicenses().get(featureType); + public ESLicenses.ESLicense getESLicense(String feature) { + return getEffectiveLicenses().get(feature); } @Override @@ -378,10 +364,10 @@ public class LicensesService extends AbstractLifecycleComponent long offset = TimeValue.timeValueMinutes(1).getMillis(); for (ListenerHolder listenerHolder : registeredListeners) { long expiryDate = -1l; - if (esLicenseManager.hasLicenseForFeature(FeatureType.fromString(listenerHolder.feature))) { - expiryDate = esLicenseManager.getExpiryDateForLicense(FeatureType.fromString(listenerHolder.feature)); + if (esLicenseManager.hasLicenseForFeature(listenerHolder.feature)) { + expiryDate = esLicenseManager.getExpiryDateForLicense(listenerHolder.feature); } else { - final TrialLicense trialLicense = licensesWrapper.trialLicenses().getTrialLicense(FeatureType.fromString(listenerHolder.feature)); + final TrialLicense trialLicense = licensesWrapper.trialLicenses().getTrialLicense(listenerHolder.feature); if (trialLicense != null) { expiryDate = trialLicense.expiryDate(); } @@ -406,14 +392,6 @@ public class LicensesService extends AbstractLifecycleComponent return nextScheduleFrequency; } - private static Set asFeatureTypes(Set featureTypeStrings) { - Set featureTypes = new HashSet<>(featureTypeStrings.size()); - for (String featureString : featureTypeStrings) { - featureTypes.add(FeatureType.fromString(featureString)); - } - return featureTypes; - } - public static class PutLicenseRequestHolder { private final PutLicenseRequest request; private final String source; @@ -439,7 +417,7 @@ public class LicensesService extends AbstractLifecycleComponent .issuedTo(clusterService.state().getClusterName().value()) .issueDate(System.currentTimeMillis()) .durationInDays(durationInDays) - .feature(FeatureType.fromString(feature)) + .feature(feature) .maxNodes(maxNodes) .build(); } @@ -460,10 +438,8 @@ public class LicensesService extends AbstractLifecycleComponent final TrialLicenseOptions trialLicenseOptions; final Listener listener; final AtomicBoolean registered = new AtomicBoolean(false); - final AtomicBoolean trialLicenseGenerated = new AtomicBoolean(false); - final AtomicBoolean toggle = new AtomicBoolean(false); - final AtomicBoolean initialState = new AtomicBoolean(true); + final AtomicBoolean enabled = new AtomicBoolean(false); // by default, a consumer plugin should be disabled private ListenerHolder(String feature, TrialLicenseOptions trialLicenseOptions, Listener listener) { this.feature = feature; @@ -472,18 +448,14 @@ public class LicensesService extends AbstractLifecycleComponent } private void enableFeatureIfNeeded() { - if (toggle.compareAndSet(false, true) || initialState.compareAndSet(true, false)) { + if (enabled.compareAndSet(false, true)) { listener.onEnabled(); - // needed as toggle may not be set - toggle.set(true); } } private void disableFeatureIfNeeded() { - if (toggle.compareAndSet(true, false) || initialState.compareAndSet(true, false)) { + if (enabled.compareAndSet(true, false)) { listener.onDisabled(); - // needed as toggle may not be set - toggle.set(false); } } } @@ -512,19 +484,34 @@ public class LicensesService extends AbstractLifecycleComponent return TrialLicenseUtils.fromEncodedTrialLicenses(encodedTrialLicenses); } + /** + * Check if any trial license for the feature exists, + * if no trial license for feature exists, add new + * trial license for feature + * @param trialLicense to add + */ public void addTrialLicense(TrialLicense trialLicense) { - this.encodedTrialLicenses = ImmutableSet.copyOf(Sets.union(encodedTrialLicenses, - Collections.singleton(TrialLicenseUtils.toEncodedTrialLicense(trialLicense)))); + boolean featureTrialLicenseExists = false; + for (TrialLicense currentTrialLicense : trialLicenses()) { + if (currentTrialLicense.feature().equals(trialLicense.feature())) { + featureTrialLicenseExists = true; + break; + } + } + if (!featureTrialLicenseExists) { + this.encodedTrialLicenses = ImmutableSet.copyOf(Sets.union(encodedTrialLicenses, + Collections.singleton(TrialLicenseUtils.toEncodedTrialLicense(trialLicense)))); + } } - public void addSignedLicenses(ESLicenseManager licenseManage, ESLicenses licenses) { - ESLicenses currentSignedLicenses = signedLicenses(licenseManage); + public void addSignedLicenses(ESLicenseManager licenseManager, ESLicenses licenses) { + ESLicenses currentSignedLicenses = signedLicenses(licenseManager); final ESLicenses mergedLicenses = LicenseBuilders.merge(currentSignedLicenses, licenses); Set newSignatures = Sets.newHashSet(Utils.toSignatures(mergedLicenses)); this.signatures = ImmutableSet.copyOf(Sets.union(signatures, newSignatures)); } - public void removeFeatures(ESLicenseManager licenseManage, Set featuresToDelete) { + public void removeFeatures(ESLicenseManager licenseManage, Set featuresToDelete) { ESLicenses currentSignedLicenses = signedLicenses(licenseManage); final ESLicenses reducedLicenses = LicenseBuilders.removeFeatures(currentSignedLicenses, featuresToDelete); Set reducedSignatures = Sets.newHashSet(Utils.toSignatures(reducedLicenses)); @@ -536,6 +523,7 @@ public class LicensesService extends AbstractLifecycleComponent } } + //Should not be exposed; used by testing only public void clear() { if (notificationScheduler != null) { notificationScheduler.cancel(true); diff --git a/src/main/java/org/elasticsearch/license/plugin/core/trial/TrialLicenseUtils.java b/src/main/java/org/elasticsearch/license/plugin/core/trial/TrialLicenseUtils.java index a0629e20634..f743896d189 100644 --- a/src/main/java/org/elasticsearch/license/plugin/core/trial/TrialLicenseUtils.java +++ b/src/main/java/org/elasticsearch/license/plugin/core/trial/TrialLicenseUtils.java @@ -48,7 +48,7 @@ public class TrialLicenseUtils { return TrialLicensesBuilder.trialLicenseBuilder() .uid(uid) .issuedTo(issuedTo) - .feature(ESLicenses.FeatureType.fromString(feature)) + .feature(feature) .maxNodes(maxNodes) .issueDate(issueDate) .expiryDate(expiryDate) @@ -57,8 +57,7 @@ public class TrialLicenseUtils { public static String toEncodedTrialLicense(TrialLicenses.TrialLicense trialLicense) { byte[] uidBytes = trialLicense.uid().getBytes(Charset.forName("UTF-8")); - String feature = trialLicense.feature().string(); - byte[] featureBytes = feature.getBytes(Charset.forName("UTF-8")); + byte[] featureBytes = trialLicense.feature().getBytes(Charset.forName("UTF-8")); byte[] issuedToBytes = trialLicense.issuedTo().getBytes(Charset.forName("UTF-8")); // uid len + uid bytes + issuedTo len + issuedTo bytes + feature bytes length + feature bytes + maxNodes + issueDate + expiryDate @@ -134,7 +133,7 @@ public class TrialLicenseUtils { builder.put(TrialLicenseFields.TYPE, ESLicenses.Type.TRIAL.string()); builder.put(TrialLicenseFields.SUBSCRIPTION_TYPE, ESLicenses.SubscriptionType.NONE.string()); builder.put(TrialLicenseFields.ISSUE_DATE, trialLicense.issueDate()); - builder.put(TrialLicenseFields.FEATURE, trialLicense.feature().string()); + builder.put(TrialLicenseFields.FEATURE, trialLicense.feature()); builder.put(TrialLicenseFields.EXPIRY_DATE, trialLicense.expiryDate()); builder.put(TrialLicenseFields.MAX_NODES, trialLicense.maxNodes()); builder.put(TrialLicenseFields.ISSUED_TO, trialLicense.issuedTo()); @@ -146,7 +145,7 @@ public class TrialLicenseUtils { .uid((String) map.get(TrialLicenseFields.UID)) .issuedTo((String) map.get(TrialLicenseFields.ISSUED_TO)) .maxNodes((int) map.get(TrialLicenseFields.MAX_NODES)) - .feature(ESLicenses.FeatureType.fromString((String) map.get(TrialLicenseFields.FEATURE))) + .feature((String) map.get(TrialLicenseFields.FEATURE)) .issueDate((long) map.get(TrialLicenseFields.ISSUE_DATE)) .expiryDate((long) map.get(TrialLicenseFields.EXPIRY_DATE)) .build(); diff --git a/src/main/java/org/elasticsearch/license/plugin/core/trial/TrialLicenses.java b/src/main/java/org/elasticsearch/license/plugin/core/trial/TrialLicenses.java index 11c8243572b..35c2d003657 100644 --- a/src/main/java/org/elasticsearch/license/plugin/core/trial/TrialLicenses.java +++ b/src/main/java/org/elasticsearch/license/plugin/core/trial/TrialLicenses.java @@ -7,19 +7,17 @@ package org.elasticsearch.license.plugin.core.trial; import java.util.Collection; -import static org.elasticsearch.license.core.ESLicenses.FeatureType; - public interface TrialLicenses extends Iterable { public Collection trialLicenses(); - public TrialLicense getTrialLicense(FeatureType featureType); + public TrialLicense getTrialLicense(String feature); public interface TrialLicense { public String issuedTo(); - public FeatureType feature(); + public String feature(); public long issueDate(); diff --git a/src/main/java/org/elasticsearch/license/plugin/core/trial/TrialLicensesBuilder.java b/src/main/java/org/elasticsearch/license/plugin/core/trial/TrialLicensesBuilder.java index 3d7f88aaab6..3d33ad638fe 100644 --- a/src/main/java/org/elasticsearch/license/plugin/core/trial/TrialLicensesBuilder.java +++ b/src/main/java/org/elasticsearch/license/plugin/core/trial/TrialLicensesBuilder.java @@ -7,7 +7,6 @@ package org.elasticsearch.license.plugin.core.trial; import org.elasticsearch.common.collect.ImmutableMap; import org.elasticsearch.license.core.DateUtils; -import org.elasticsearch.license.core.ESLicenses; import java.util.*; @@ -41,7 +40,7 @@ public class TrialLicensesBuilder { } } - private final ImmutableMap.Builder licenseBuilder; + private final ImmutableMap.Builder licenseBuilder; public TrialLicensesBuilder() { licenseBuilder = ImmutableMap.builder(); @@ -64,7 +63,7 @@ public class TrialLicensesBuilder { } public TrialLicenses build() { - final ImmutableMap licenseMap = licenseBuilder.build(); + final ImmutableMap licenseMap = licenseBuilder.build(); return new TrialLicenses() { @Override @@ -73,8 +72,8 @@ public class TrialLicensesBuilder { } @Override - public TrialLicense getTrialLicense(ESLicenses.FeatureType featureType) { - return licenseMap.get(featureType); + public TrialLicense getTrialLicense(String feature) { + return licenseMap.get(feature); } @Override @@ -85,7 +84,7 @@ public class TrialLicensesBuilder { } public static class TrialLicenseBuilder { - private ESLicenses.FeatureType featureType; + private String featureType; private long expiryDate = -1; private long issueDate = -1; private int durationInDays = -1; @@ -111,7 +110,7 @@ public class TrialLicensesBuilder { return this; } - public TrialLicenseBuilder feature(ESLicenses.FeatureType featureType) { + public TrialLicenseBuilder feature(String featureType) { this.featureType = featureType; return this; } @@ -148,7 +147,7 @@ public class TrialLicensesBuilder { } @Override - public ESLicenses.FeatureType feature() { + public String feature() { return featureType; } diff --git a/src/main/java/org/elasticsearch/license/plugin/rest/RestDeleteLicenseAction.java b/src/main/java/org/elasticsearch/license/plugin/rest/RestDeleteLicenseAction.java index ff03ee696b2..926256ebca6 100644 --- a/src/main/java/org/elasticsearch/license/plugin/rest/RestDeleteLicenseAction.java +++ b/src/main/java/org/elasticsearch/license/plugin/rest/RestDeleteLicenseAction.java @@ -19,10 +19,6 @@ import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.action.support.AcknowledgedRestListener; -import java.util.HashSet; -import java.util.Set; - -import static org.elasticsearch.license.core.ESLicenses.FeatureType; import static org.elasticsearch.rest.RestRequest.Method.DELETE; public class RestDeleteLicenseAction extends BaseRestHandler { @@ -38,25 +34,10 @@ public class RestDeleteLicenseAction extends BaseRestHandler { public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) { final String[] features = Strings.splitStringByCommaToArray(request.param("features")); if (features.length == 0) { - throw new ElasticsearchIllegalArgumentException("no features specified for license deletion"); + throw new ElasticsearchIllegalArgumentException("no feature specified for license deletion"); } - DeleteLicenseRequest deleteLicenseRequest = new DeleteLicenseRequest(getFeaturesToDelete(features)); + DeleteLicenseRequest deleteLicenseRequest = new DeleteLicenseRequest(features); deleteLicenseRequest.listenerThreaded(false); client.admin().cluster().execute(DeleteLicenseAction.INSTANCE, deleteLicenseRequest, new AcknowledgedRestListener(channel)); } - - private static String[] getFeaturesToDelete(String[] features) { - Set result = new HashSet<>(); - for (String feature : features) { - if (feature.equalsIgnoreCase("_all")) { - for (FeatureType featureType : FeatureType.values()) { - result.add(featureType.string()); - } - break; - } else { - result.add(FeatureType.fromString(feature).string()); - } - } - return result.toArray(new String[result.size()]); - } } diff --git a/src/test/java/org/elasticsearch/license/AbstractLicensingTestBase.java b/src/test/java/org/elasticsearch/license/AbstractLicensingTestBase.java index 2ae1001967d..fa21f3f084e 100644 --- a/src/test/java/org/elasticsearch/license/AbstractLicensingTestBase.java +++ b/src/test/java/org/elasticsearch/license/AbstractLicensingTestBase.java @@ -31,7 +31,7 @@ public class AbstractLicensingTestBase { return url.toURI().getPath(); } - public String generateSignedLicenses(Map map) throws IOException { + public String generateSignedLicenses(Map map) throws IOException { String licenseString = TestUtils.generateESLicenses(map); return TestUtils.runLicenseGenerationTool(licenseString, pubKeyPath, priKeyPath); } diff --git a/src/test/java/org/elasticsearch/license/TestUtils.java b/src/test/java/org/elasticsearch/license/TestUtils.java index ab29a571044..127a147dc2e 100644 --- a/src/test/java/org/elasticsearch/license/TestUtils.java +++ b/src/test/java/org/elasticsearch/license/TestUtils.java @@ -21,8 +21,10 @@ import static org.junit.Assert.assertTrue; public class TestUtils { + public final static String SHIELD = "shield"; + public final static String MARVEL = "marvel"; - public static String generateESLicenses(Map featureAttributes) { + public static String generateESLicenses(Map featureAttributes) { StringBuilder licenseBuilder = new StringBuilder(); int size = featureAttributes.values().size(); int i = 0; @@ -70,17 +72,17 @@ public class TestUtils { return FileUtils.readFileToString(temp); } - public static void verifyESLicenses(ESLicenses esLicenses, Map featureAttributes) throws ParseException { + public static void verifyESLicenses(ESLicenses esLicenses, Map featureAttributes) throws ParseException { assertTrue("Number of feature licenses should be " + featureAttributes.size(), esLicenses.features().size() == featureAttributes.size()); - for (Map.Entry featureAttrTuple : featureAttributes.entrySet()) { - ESLicenses.FeatureType featureType = featureAttrTuple.getKey(); + for (Map.Entry featureAttrTuple : featureAttributes.entrySet()) { + String featureType = featureAttrTuple.getKey(); FeatureAttributes attributes = featureAttrTuple.getValue(); final ESLicenses.ESLicense esLicense = esLicenses.get(featureType); - assertTrue("license for " + featureType.string() + " should be present", esLicense != null); + assertTrue("license for " + featureType + " should be present", esLicense != null); assertTrue("expected value for issuedTo was: " + attributes.issuedTo + " but got: " + esLicense.issuedTo(), esLicense.issuedTo().equals(attributes.issuedTo)); assertTrue("expected value for type was: " + attributes.type + " but got: " + esLicense.type().string(), esLicense.type().string().equals(attributes.type)); assertTrue("expected value for subscriptionType was: " + attributes.subscriptionType + " but got: " + esLicense.subscriptionType().string(), esLicense.subscriptionType().string().equals(attributes.subscriptionType)); - assertTrue("expected value for feature was: " + attributes.featureType + " but got: " + esLicense.feature().string(), esLicense.feature().string().equals(attributes.featureType)); + assertTrue("expected value for feature was: " + attributes.featureType + " but got: " + esLicense.feature(), esLicense.feature().equals(attributes.featureType)); assertTrue("expected value for issueDate was: " + DateUtils.longFromDateString(attributes.issueDate) + " but got: " + esLicense.issueDate(), esLicense.issueDate() == DateUtils.longFromDateString(attributes.issueDate)); assertTrue("expected value for expiryDate: " + DateUtils.longExpiryDateFromString(attributes.expiryDate) + " but got: " + esLicense.expiryDate(), esLicense.expiryDate() == DateUtils.longExpiryDateFromString(attributes.expiryDate)); assertTrue("expected value for maxNodes: " + attributes.maxNodes + " but got: " + esLicense.maxNodes(), esLicense.maxNodes() == attributes.maxNodes); @@ -102,7 +104,7 @@ public class TestUtils { // for every feature license, check if all the attributes are the same - for (ESLicenses.FeatureType featureType : licenses1.features()) { + for (String featureType : licenses1.features()) { ESLicenses.ESLicense license1 = licenses1.get(featureType); ESLicenses.ESLicense license2 = licenses2.get(featureType); @@ -114,7 +116,7 @@ public class TestUtils { public static void isSame(ESLicenses.ESLicense license1, ESLicenses.ESLicense license2) { assertTrue("Should have same uid; got: " + license1.uid() + " and " + license2.uid(), license1.uid().equals(license2.uid())); - assertTrue("Should have same feature; got: " + license1.feature().string() + " and " + license2.feature().string(), license1.feature().string().equals(license2.feature().string())); + assertTrue("Should have same feature; got: " + license1.feature() + " and " + license2.feature(), license1.feature().equals(license2.feature())); assertTrue("Should have same subscriptType; got: " + license1.subscriptionType().string() + " and " + license2.subscriptionType().string(), license1.subscriptionType().string().equals(license2.subscriptionType().string())); assertTrue("Should have same type; got: " + license1.type().string() + " and " + license2.type().string(), license1.type().string().equals(license2.type().string())); assertTrue("Should have same issuedTo; got: " + license1.issuedTo() + " and " + license2.issuedTo(), license1.issuedTo().equals(license2.issuedTo())); diff --git a/src/test/java/org/elasticsearch/license/licensor/LicenseGenerationTests.java b/src/test/java/org/elasticsearch/license/licensor/LicenseGenerationTests.java index 753cc2c6a3e..1ae94307481 100644 --- a/src/test/java/org/elasticsearch/license/licensor/LicenseGenerationTests.java +++ b/src/test/java/org/elasticsearch/license/licensor/LicenseGenerationTests.java @@ -16,7 +16,6 @@ import java.text.ParseException; import java.util.HashMap; import java.util.Map; -import static org.elasticsearch.license.core.ESLicenses.FeatureType; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -24,10 +23,10 @@ public class LicenseGenerationTests extends AbstractLicensingTestBase { @Test public void testSimpleLicenseGeneration() throws ParseException, IOException { - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes featureAttributes = new TestUtils.FeatureAttributes("shield", "subscription", "platinum", "foo bar Inc.", "elasticsearch", 2, "2014-12-13", "2015-12-13"); - map.put(FeatureType.SHIELD, featureAttributes); + map.put(TestUtils.SHIELD, featureAttributes); String licenseOutput = generateSignedLicenses(map); @@ -37,15 +36,15 @@ public class LicenseGenerationTests extends AbstractLicensingTestBase { } @Test - public void testMultipleFeatureTypes() throws ParseException, IOException { + public void testMultipleStrings() throws ParseException, IOException { - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes shildFeatureAttributes = new TestUtils.FeatureAttributes("shield", "trial", "none", "foo bar Inc.", "elasticsearch", 2, "2014-12-13", "2015-12-13"); TestUtils.FeatureAttributes marvelFeatureAttributes = new TestUtils.FeatureAttributes("marvel", "subscription", "silver", "foo1 bar Inc.", "elasticsearc3h", 10, "2014-01-13", "2014-12-13"); - map.put(FeatureType.SHIELD, shildFeatureAttributes); - map.put(FeatureType.MARVEL, marvelFeatureAttributes); + map.put(TestUtils.SHIELD, shildFeatureAttributes); + map.put(TestUtils.MARVEL, marvelFeatureAttributes); String licenseOutput = generateSignedLicenses(map); @@ -57,10 +56,10 @@ public class LicenseGenerationTests extends AbstractLicensingTestBase { @Test public void testMissingCLTArgs() throws ParseException, IOException { - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes featureAttributes = new TestUtils.FeatureAttributes("shiedgdsld", "internal", "none", "foo bar Inc.", "elasticsearch", 23, "2014-12-13", "2015-12-13"); - map.put(FeatureType.SHIELD, featureAttributes); + map.put(TestUtils.SHIELD, featureAttributes); String licenseString = TestUtils.generateESLicenses(map); @@ -80,38 +79,12 @@ public class LicenseGenerationTests extends AbstractLicensingTestBase { } } - @Test - public void testInvalidFeatureType() throws ParseException, IOException { - - Map map = new HashMap<>(); - TestUtils.FeatureAttributes featureAttributes = - new TestUtils.FeatureAttributes("shiedgdsld", "internal", "none", "foo bar Inc.", "elasticsearch", 23, "2014-12-13", "2015-12-13"); - map.put(FeatureType.SHIELD, featureAttributes); - - String licenseString = TestUtils.generateESLicenses(map); - - String[] args = new String[6]; - args[0] = "--license"; - args[1] = licenseString; - args[2] = "--publicKeyPath"; - args[3] = pubKeyPath; - args[4] = "--privateKeyPath"; - args[5] = priKeyPath; - - try { - String licenseOutput = TestUtils.runLicenseGenerationTool(args); - fail(); - } catch (IllegalArgumentException e) { - assertTrue("Exception should indicate invalid FeatureType, got: " + e.getMessage(), e.getMessage().contains("Invalid FeatureType")); - } - } - @Test public void testInvalidSubscriptionType() throws ParseException, IOException { - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes featureAttributes = new TestUtils.FeatureAttributes("shield", "trial", "nodavne", "foo bar Inc.", "elasticsearch", 25, "2014-12-13", "2015-12-13"); - map.put(FeatureType.SHIELD, featureAttributes); + map.put(TestUtils.SHIELD, featureAttributes); String licenseString = TestUtils.generateESLicenses(map); @@ -134,10 +107,10 @@ public class LicenseGenerationTests extends AbstractLicensingTestBase { @Test public void testInvalidType() throws ParseException, IOException { - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes featureAttributes = new TestUtils.FeatureAttributes("shield", "inininternal", "gold", "foo bar Inc.", "elasticsearch", 12, "2014-12-13", "2015-12-13"); - map.put(FeatureType.SHIELD, featureAttributes); + map.put(TestUtils.SHIELD, featureAttributes); String licenseString = TestUtils.generateESLicenses(map); diff --git a/src/test/java/org/elasticsearch/license/licensor/LicenseVerificationToolTests.java b/src/test/java/org/elasticsearch/license/licensor/LicenseVerificationToolTests.java index 04dcba40de0..66eeacdeb62 100644 --- a/src/test/java/org/elasticsearch/license/licensor/LicenseVerificationToolTests.java +++ b/src/test/java/org/elasticsearch/license/licensor/LicenseVerificationToolTests.java @@ -23,17 +23,17 @@ public class LicenseVerificationToolTests extends AbstractLicensingTestBase { @Test public void testEffectiveLicenseGeneration() throws Exception { - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes featureWithLongerExpiryDate = new TestUtils.FeatureAttributes("shield", "subscription", "platinum", "foo bar Inc.", "elasticsearch", 10, "2014-12-13", "2015-12-13"); - map.put(ESLicenses.FeatureType.SHIELD, featureWithLongerExpiryDate); + map.put(TestUtils.SHIELD, featureWithLongerExpiryDate); String signedLicense = runLicenseGenerationTool(TestUtils.generateESLicenses(map)); String firstLicenseFile = getAsFilePath(signedLicense); TestUtils.FeatureAttributes featureWithShorterExpiryDate = new TestUtils.FeatureAttributes("shield", "trial", "none", "foo bar Inc.", "elasticsearch", 2, "2014-12-13", "2015-01-13"); - map.put(ESLicenses.FeatureType.SHIELD, featureWithShorterExpiryDate); + map.put(TestUtils.SHIELD, featureWithShorterExpiryDate); signedLicense = runLicenseGenerationTool(TestUtils.generateESLicenses(map)); String secondLicenseFile = getAsFilePath(signedLicense); @@ -41,7 +41,7 @@ public class LicenseVerificationToolTests extends AbstractLicensingTestBase { String effectiveLicenseStr = runLicenseVerificationTool(new String[]{firstLicenseFile, secondLicenseFile}); ESLicenses effectiveLicense = LicenseUtils.readLicensesFromString(effectiveLicenseStr); - map.put(ESLicenses.FeatureType.SHIELD, featureWithLongerExpiryDate); + map.put(TestUtils.SHIELD, featureWithLongerExpiryDate); // verify that the effective license strips out license for the same feature with earlier expiry dates TestUtils.verifyESLicenses(effectiveLicense, map); @@ -49,17 +49,17 @@ public class LicenseVerificationToolTests extends AbstractLicensingTestBase { @Test public void testEffectiveLicenseForMultiFeatures() throws Exception { - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes shieldFeatureWithLongerExpiryDate = new TestUtils.FeatureAttributes("shield", "subscription", "platinum", "foo bar Inc.", "elasticsearch", 10, "2014-12-13", "2015-12-13"); - map.put(ESLicenses.FeatureType.SHIELD, shieldFeatureWithLongerExpiryDate); + map.put(TestUtils.SHIELD, shieldFeatureWithLongerExpiryDate); String signedLicense = runLicenseGenerationTool(TestUtils.generateESLicenses(map)); String firstLicenseFile = getAsFilePath(signedLicense); TestUtils.FeatureAttributes marvelFeatureWithShorterExpiryDate = new TestUtils.FeatureAttributes("marvel", "trial", "none", "foo bar Inc.", "elasticsearch", 2, "2014-12-13", "2015-01-13"); - map.put(ESLicenses.FeatureType.MARVEL, marvelFeatureWithShorterExpiryDate); + map.put(TestUtils.MARVEL, marvelFeatureWithShorterExpiryDate); signedLicense = runLicenseGenerationTool(TestUtils.generateESLicenses(map)); String secondLicenseFile = getAsFilePath(signedLicense); @@ -73,15 +73,15 @@ public class LicenseVerificationToolTests extends AbstractLicensingTestBase { @Test public void testEffectiveLicenseForMultiFeatures2() throws Exception { - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes shieldFeatureWithLongerExpiryDate = new TestUtils.FeatureAttributes("shield", "subscription", "platinum", "foo bar Inc.", "elasticsearch", 10, "2014-12-13", "2015-12-13"); TestUtils.FeatureAttributes marvelFeatureWithShorterExpiryDate = new TestUtils.FeatureAttributes("marvel", "trial", "none", "foo bar Inc.", "elasticsearch", 2, "2014-12-13", "2015-01-13"); - map.put(ESLicenses.FeatureType.SHIELD, shieldFeatureWithLongerExpiryDate); - map.put(ESLicenses.FeatureType.MARVEL, marvelFeatureWithShorterExpiryDate); + map.put(TestUtils.SHIELD, shieldFeatureWithLongerExpiryDate); + map.put(TestUtils.MARVEL, marvelFeatureWithShorterExpiryDate); String signedLicense = runLicenseGenerationTool(TestUtils.generateESLicenses(map)); String firstLicenseFile = getAsFilePath(signedLicense); @@ -91,8 +91,8 @@ public class LicenseVerificationToolTests extends AbstractLicensingTestBase { TestUtils.FeatureAttributes marvelFeatureWithLongerExpiryDate = new TestUtils.FeatureAttributes("marvel", "trial", "none", "foo bar Inc.", "elasticsearch", 2, "2014-12-13", "2015-11-13"); - map.put(ESLicenses.FeatureType.SHIELD, shieldFeatureWithShorterExpiryDate); - map.put(ESLicenses.FeatureType.MARVEL, marvelFeatureWithLongerExpiryDate); + map.put(TestUtils.SHIELD, shieldFeatureWithShorterExpiryDate); + map.put(TestUtils.MARVEL, marvelFeatureWithLongerExpiryDate); signedLicense = runLicenseGenerationTool(TestUtils.generateESLicenses(map)); String secondLicenseFile = getAsFilePath(signedLicense); @@ -100,8 +100,8 @@ public class LicenseVerificationToolTests extends AbstractLicensingTestBase { String effectiveLicenseStr = runLicenseVerificationTool(new String[]{firstLicenseFile, secondLicenseFile}); ESLicenses effectiveLicense = LicenseUtils.readLicensesFromString(effectiveLicenseStr); - map.put(ESLicenses.FeatureType.SHIELD, shieldFeatureWithLongerExpiryDate); - map.put(ESLicenses.FeatureType.MARVEL, marvelFeatureWithLongerExpiryDate); + map.put(TestUtils.SHIELD, shieldFeatureWithLongerExpiryDate); + map.put(TestUtils.MARVEL, marvelFeatureWithLongerExpiryDate); // verify that the generated effective license is generated from choosing individual licences from multiple files TestUtils.verifyESLicenses(effectiveLicense, map); diff --git a/src/test/java/org/elasticsearch/license/manager/LicenseVerificationTests.java b/src/test/java/org/elasticsearch/license/manager/LicenseVerificationTests.java index d11749fc20f..2a587ab3d67 100644 --- a/src/test/java/org/elasticsearch/license/manager/LicenseVerificationTests.java +++ b/src/test/java/org/elasticsearch/license/manager/LicenseVerificationTests.java @@ -19,7 +19,6 @@ import org.junit.Test; import java.text.ParseException; import java.util.*; -import static org.elasticsearch.license.core.ESLicenses.FeatureType; import static org.elasticsearch.license.core.LicenseUtils.readLicensesFromString; import static org.junit.Assert.*; @@ -49,10 +48,10 @@ public class LicenseVerificationTests extends AbstractLicensingTestBase { Date issueDate = new Date(); String issueDateStr = DateUtils.dateStringFromLongDate(issueDate.getTime()); String expiryDateStr = DateUtils.dateStringFromLongDate(DateUtils.longExpiryDateFromDate(issueDate.getTime() + 24 * 60 * 60l)); - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes featureAttributes = new TestUtils.FeatureAttributes("shield", "subscription", "platinum", "foo bar Inc.", "elasticsearch", 2, issueDateStr, expiryDateStr); - map.put(FeatureType.SHIELD, featureAttributes); + map.put(TestUtils.SHIELD, featureAttributes); ESLicenses esLicensesOutput = readLicensesFromString(generateSignedLicenses(map)); @@ -70,13 +69,13 @@ public class LicenseVerificationTests extends AbstractLicensingTestBase { String issueDateStr = DateUtils.dateStringFromLongDate(issueDate.getTime()); String expiryDateStr = DateUtils.dateStringFromLongDate(DateUtils.longExpiryDateFromDate(issueDate.getTime() + 24 * 60 * 60 * 1000l)); - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes shildFeatureAttributes = new TestUtils.FeatureAttributes("shield", "trial", "none", "foo bar Inc.", "elasticsearch", 2, issueDateStr, expiryDateStr); TestUtils.FeatureAttributes marvelFeatureAttributes = new TestUtils.FeatureAttributes("marvel", "subscription", "silver", "foo1 bar Inc.", "elasticsearc3h", 10, issueDateStr, expiryDateStr); - map.put(FeatureType.SHIELD, shildFeatureAttributes); - map.put(FeatureType.MARVEL, marvelFeatureAttributes); + map.put(TestUtils.SHIELD, shildFeatureAttributes); + map.put(TestUtils.MARVEL, marvelFeatureAttributes); ESLicenses esLicensesOutput = readLicensesFromString(generateSignedLicenses(map)); @@ -127,22 +126,23 @@ public class LicenseVerificationTests extends AbstractLicensingTestBase { assert longExpiryDateFromDate < System.currentTimeMillis(); String expiredExpiryDateStr = DateUtils.dateStringFromLongDate(longExpiryDateFromDate); - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes shildFeatureAttributes = new TestUtils.FeatureAttributes("shield", "trial", "none", "foo bar Inc.", "elasticsearch", 2, issueDateStr, expiryDateStr); TestUtils.FeatureAttributes marvelFeatureAttributes = new TestUtils.FeatureAttributes("marvel", "internal", "silver", "foo1 bar Inc.", "elasticsearc3h", 10, issueDateStr, expiredExpiryDateStr); - map.put(FeatureType.SHIELD, shildFeatureAttributes); - map.put(FeatureType.MARVEL, marvelFeatureAttributes); + map.put(TestUtils.SHIELD, shildFeatureAttributes); + map.put(TestUtils.MARVEL, marvelFeatureAttributes); ESLicenses esLicensesOutput = readLicensesFromString(generateSignedLicenses(map)); esLicenseProvider.setLicenses(esLicensesOutput); // All validation for shield license should be normal as expected - verifyLicenseManager(esLicenseManager, Collections.singletonMap(FeatureType.SHIELD, shildFeatureAttributes)); + + verifyLicenseManager(esLicenseManager, Collections.singletonMap(TestUtils.SHIELD, shildFeatureAttributes)); - assertFalse("license for marvel should not be valid due to expired expiry date", esLicenseManager.hasLicenseForFeature(FeatureType.MARVEL)); + assertFalse("license for marvel should not be valid due to expired expiry date", esLicenseManager.hasLicenseForFeature(TestUtils.MARVEL)); } @Test @@ -151,20 +151,20 @@ public class LicenseVerificationTests extends AbstractLicensingTestBase { Date issueDate = new Date(); String issueDateStr = DateUtils.dateStringFromLongDate(issueDate.getTime()); String expiryDateStr = DateUtils.dateStringFromLongDate(DateUtils.longExpiryDateFromDate(issueDate.getTime() + 24 * 60 * 60l)); - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes featureAttributes = new TestUtils.FeatureAttributes("shield", "subscription", "platinum", "foo bar Inc.", "elasticsearch", 2, issueDateStr, expiryDateStr); - map.put(FeatureType.SHIELD, featureAttributes); + map.put(TestUtils.SHIELD, featureAttributes); ESLicenses esLicensesOutput = readLicensesFromString(generateSignedLicenses(map)); - ESLicenses.ESLicense esLicense = esLicensesOutput.get(FeatureType.SHIELD); + ESLicenses.ESLicense esLicense = esLicensesOutput.get(TestUtils.SHIELD); long originalExpiryDate = esLicense.expiryDate(); final ESLicenses.ESLicense tamperedLicense = LicenseBuilders.licenseBuilder(true) .fromLicense(esLicense) .expiryDate(esLicense.expiryDate() + 10 * 24 * 60 * 60 * 1000l) - .feature(FeatureType.SHIELD) + .feature(TestUtils.SHIELD) .issuer("elasticsqearch") .build(); @@ -172,7 +172,7 @@ public class LicenseVerificationTests extends AbstractLicensingTestBase { try { esLicenseProvider.setLicenses(tamperedLicenses); - assertTrue("License manager should always report the original (signed) expiry date of: " + originalExpiryDate + " but got: " + esLicenseManager.getExpiryDateForLicense(FeatureType.SHIELD), esLicenseManager.getExpiryDateForLicense(FeatureType.SHIELD) == originalExpiryDate); + assertTrue("License manager should always report the original (signed) expiry date of: " + originalExpiryDate + " but got: " + esLicenseManager.getExpiryDateForLicense(TestUtils.SHIELD), esLicenseManager.getExpiryDateForLicense(TestUtils.SHIELD) == originalExpiryDate); esLicenseManager.verifyLicenses(); fail(); } catch (InvalidLicenseException e) { @@ -180,11 +180,11 @@ public class LicenseVerificationTests extends AbstractLicensingTestBase { } } - public static void verifyLicenseManager(ESLicenseManager esLicenseManager, Map featureAttributeMap) throws ParseException { + public static void verifyLicenseManager(ESLicenseManager esLicenseManager, Map featureAttributeMap) throws ParseException { - for (Map.Entry entry : featureAttributeMap.entrySet()) { + for (Map.Entry entry : featureAttributeMap.entrySet()) { TestUtils.FeatureAttributes featureAttributes = entry.getValue(); - FeatureType featureType = entry.getKey(); + String featureType = entry.getKey(); assertTrue("License should have issuedTo of " + featureAttributes.issuedTo, esLicenseManager.getIssuedToForLicense(featureType).equals(featureAttributes.issuedTo)); assertTrue("License should have issuer of " + featureAttributes.issuer, esLicenseManager.getIssuerForLicense(featureType).equals(featureAttributes.issuer)); assertTrue("License should have issue date of " + DateUtils.longFromDateString(featureAttributes.issueDate), esLicenseManager.getIssueDateForLicense(featureType) == DateUtils.longFromDateString(featureAttributes.issueDate)); @@ -193,7 +193,7 @@ public class LicenseVerificationTests extends AbstractLicensingTestBase { assertTrue("License should have subscription type of " + featureAttributes.subscriptionType, esLicenseManager.getSubscriptionTypeForLicense(featureType) == ESLicenses.SubscriptionType.fromString(featureAttributes.subscriptionType)); - assertTrue("License should be valid for " + featureType.string(), esLicenseManager.hasLicenseForFeature(featureType)); + assertTrue("License should be valid for " + featureType, esLicenseManager.hasLicenseForFeature(featureType)); assertTrue("License should be valid for maxNodes = " + (featureAttributes.maxNodes - 1), esLicenseManager.hasLicenseForNodes(featureType, featureAttributes.maxNodes - 1)); assertTrue("License should be valid for maxNodes = " + (featureAttributes.maxNodes), esLicenseManager.hasLicenseForNodes(featureType, featureAttributes.maxNodes)); assertFalse("License should not be valid for maxNodes = " + (featureAttributes.maxNodes + 1), esLicenseManager.hasLicenseForNodes(featureType, featureAttributes.maxNodes + 1)); diff --git a/src/test/java/org/elasticsearch/license/plugin/LicenseTransportTests.java b/src/test/java/org/elasticsearch/license/plugin/LicenseTransportTests.java index 5d9c2a8d3a8..d891226e448 100644 --- a/src/test/java/org/elasticsearch/license/plugin/LicenseTransportTests.java +++ b/src/test/java/org/elasticsearch/license/plugin/LicenseTransportTests.java @@ -88,10 +88,10 @@ public class LicenseTransportTests extends ElasticsearchIntegrationTest { @Test public void testPutLicense() throws ParseException, ExecutionException, InterruptedException, IOException { - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes featureAttributes = new TestUtils.FeatureAttributes("shield", "subscription", "platinum", "foo bar Inc.", "elasticsearch", 2, "2014-12-13", "2015-12-13"); - map.put(ESLicenses.FeatureType.SHIELD, featureAttributes); + map.put(TestUtils.SHIELD, featureAttributes); String licenseString = TestUtils.generateESLicenses(map); String licenseOutput = TestUtils.runLicenseGenerationTool(licenseString, pubKeyPath, priKeyPath); @@ -129,16 +129,16 @@ public class LicenseTransportTests extends ElasticsearchIntegrationTest { @Test public void testPutInvalidLicense() throws Exception { - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes featureAttributes = new TestUtils.FeatureAttributes("shield", "subscription", "platinum", "foo bar Inc.", "elasticsearch", 2, "2014-12-13", "2015-12-13"); - map.put(ESLicenses.FeatureType.SHIELD, featureAttributes); + map.put(TestUtils.SHIELD, featureAttributes); String licenseString = TestUtils.generateESLicenses(map); String licenseOutput = TestUtils.runLicenseGenerationTool(licenseString, pubKeyPath, priKeyPath); ESLicenses esLicenses = readLicensesFromString(licenseOutput); - ESLicenses.ESLicense esLicense = esLicenses.get(ESLicenses.FeatureType.SHIELD); + ESLicenses.ESLicense esLicense = esLicenses.get(TestUtils.SHIELD); ESLicenses.ESLicense tamperedLicense = LicenseBuilders.licenseBuilder(true) .fromLicense(esLicense) .expiryDate(esLicense.expiryDate() + 10 * 24 * 60 * 60 * 1000l) diff --git a/src/test/java/org/elasticsearch/license/plugin/LicensesPluginIntegrationTests.java b/src/test/java/org/elasticsearch/license/plugin/LicensesPluginIntegrationTests.java new file mode 100644 index 00000000000..197ef5bdc90 --- /dev/null +++ b/src/test/java/org/elasticsearch/license/plugin/LicensesPluginIntegrationTests.java @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.license.plugin; + +import org.elasticsearch.common.settings.ImmutableSettings; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.plugin.core.LicensesManagerService; +import org.elasticsearch.test.ElasticsearchIntegrationTest; +import org.elasticsearch.test.InternalTestCluster; +import org.junit.Test; + + +import static org.elasticsearch.test.ElasticsearchIntegrationTest.*; +import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope.SUITE; + +@ClusterScope(scope = SUITE, numDataNodes = 10) +public class LicensesPluginIntegrationTests extends ElasticsearchIntegrationTest { + + @Override + protected Settings nodeSettings(int nodeOrdinal) { + return ImmutableSettings.settingsBuilder() + .put("plugins.load_classpath_plugins", false) + .put("plugin.types", LicensePlugin.class.getName() + "," + TestConsumerPlugin.class.getName()) + .build(); + } + + @Override + protected Settings transportClientSettings() { + // Plugin should be loaded on the transport client as well + return nodeSettings(0); + } + + @Test + public void testLicenseRegistration() throws Exception { + LicensesManagerService managerService = licensesManagerService(); + assertTrue(managerService.enabledFeatures().contains(TestPluginService.FEATURE_NAME)); + } + + @Test + public void testFeatureActivation() throws Exception { + TestPluginService pluginService = consumerPluginService(); + assertTrue(pluginService.enabled()); + } + + private TestPluginService consumerPluginService() { + final InternalTestCluster clients = internalCluster(); + return clients.getInstance(TestPluginService.class, clients.getMasterName()); + } + + private LicensesManagerService licensesManagerService() { + final InternalTestCluster clients = internalCluster(); + return clients.getInstance(LicensesManagerService.class, clients.getMasterName()); + } +} diff --git a/src/test/java/org/elasticsearch/license/plugin/LicensesServiceTests.java b/src/test/java/org/elasticsearch/license/plugin/LicensesServiceTests.java index 0b8225c4957..53eeb7544e0 100644 --- a/src/test/java/org/elasticsearch/license/plugin/LicensesServiceTests.java +++ b/src/test/java/org/elasticsearch/license/plugin/LicensesServiceTests.java @@ -25,6 +25,7 @@ import org.elasticsearch.test.ElasticsearchIntegrationTest; import org.elasticsearch.test.InternalTestCluster; import org.junit.After; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import java.io.IOException; @@ -32,6 +33,7 @@ import java.net.URISyntaxException; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; +import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; @@ -89,6 +91,8 @@ public class LicensesServiceTests extends ElasticsearchIntegrationTest { }); latch.await(); clear(); + masterClusterService().remove(licensesService()); + masterClusterService().add(licensesService()); } @@ -102,10 +106,10 @@ public class LicensesServiceTests extends ElasticsearchIntegrationTest { public void testInvalidSignedLicenseCheck() throws Exception { LicensesManagerService licensesManagerService = licensesManagerService(); - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes featureAttributes = new TestUtils.FeatureAttributes("shield", "subscription", "platinum", "foo bar Inc.", "elasticsearch", 2, "2014-12-13", "2015-12-13"); - map.put(ESLicenses.FeatureType.SHIELD, featureAttributes); + map.put(TestUtils.SHIELD, featureAttributes); String licenseString = TestUtils.generateESLicenses(map); String licenseOutput = TestUtils.runLicenseGenerationTool(licenseString, pubKeyPath, priKeyPath); ESLicenses licenses = LicenseUtils.readLicensesFromString(licenseOutput); @@ -113,8 +117,8 @@ public class LicensesServiceTests extends ElasticsearchIntegrationTest { assertTrue(LicensesStatus.VALID == licensesManagerService.checkLicenses(licenses)); ESLicenses.ESLicense tamperedLicense = LicenseBuilders.licenseBuilder(true) - .fromLicense(licenses.get(ESLicenses.FeatureType.SHIELD)) - .expiryDate(licenses.get(ESLicenses.FeatureType.SHIELD).expiryDate() + 5 * 24 * 60 * 60 * 1000l) + .fromLicense(licenses.get(TestUtils.SHIELD)) + .expiryDate(licenses.get(TestUtils.SHIELD).expiryDate() + 5 * 24 * 60 * 60 * 1000l) .issuer("elasticsearch") .build(); @@ -125,10 +129,10 @@ public class LicensesServiceTests extends ElasticsearchIntegrationTest { @Test public void testStoringLicenses() throws Exception { - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes featureAttributes1 = new TestUtils.FeatureAttributes("shield", "subscription", "platinum", "foo bar Inc.", "elasticsearch", 2, "2014-12-13", "2015-12-13"); - map.put(ESLicenses.FeatureType.SHIELD, featureAttributes1); + map.put(TestUtils.SHIELD, featureAttributes1); String licenseString = TestUtils.generateESLicenses(map); String licenseOutput = TestUtils.runLicenseGenerationTool(licenseString, pubKeyPath, priKeyPath); ESLicenses licenses = LicenseUtils.readLicensesFromString(licenseOutput); @@ -158,7 +162,7 @@ public class LicensesServiceTests extends ElasticsearchIntegrationTest { TestUtils.FeatureAttributes featureAttributes2 = new TestUtils.FeatureAttributes("shield", "subscription", "platinum", "foo bar Inc.", "elasticsearch", 2, "2014-12-13", "2016-12-13"); - map.put(ESLicenses.FeatureType.SHIELD, featureAttributes2); + map.put(TestUtils.SHIELD, featureAttributes2); licenseString = TestUtils.generateESLicenses(map); licenseOutput = TestUtils.runLicenseGenerationTool(licenseString, pubKeyPath, priKeyPath); ESLicenses licenses2 = LicenseUtils.readLicensesFromString(licenseOutput); @@ -209,18 +213,20 @@ public class LicensesServiceTests extends ElasticsearchIntegrationTest { private class TestLicenseClientListener implements LicensesClientService.Listener { AtomicBoolean shouldBeEnabled = new AtomicBoolean(false); - CountDownLatch latch = new CountDownLatch(2); AtomicBoolean processed = new AtomicBoolean(false); private TestLicenseClientListener(boolean shouldBeEnabled) { this.shouldBeEnabled.getAndSet(shouldBeEnabled); } + private void reset() { + processed.set(false); + } + @Override public void onEnabled() { if (this.shouldBeEnabled.get()) { - latch.countDown(); - processed.getAndSet(true); + processed.set(true); } else { fail("onEnabled should not have been called"); } @@ -230,12 +236,10 @@ public class LicensesServiceTests extends ElasticsearchIntegrationTest { @Override public void onDisabled() { if (!this.shouldBeEnabled.get()) { - latch.countDown(); - processed.getAndSet(true); + processed.set(true); } else { fail("onDisabled should not have been called"); } - } } @@ -247,18 +251,22 @@ public class LicensesServiceTests extends ElasticsearchIntegrationTest { // feature should be onEnabled LicensesClientService clientService = licensesClientService(); + LicensesManagerService managerService = licensesManagerService(); final TestLicenseClientListener testLicenseClientListener = new TestLicenseClientListener(false); clientService.register("shield", null, testLicenseClientListener); - while(!testLicenseClientListener.processed.get()) {} + for (String enabledFeature : managerService.enabledFeatures()) { + assertFalse(enabledFeature.equals("shield")); + } + logger.info("pass initial check"); - testLicenseClientListener.shouldBeEnabled.getAndSet(true); - testLicenseClientListener.processed.getAndSet(false); + assertFalse(testLicenseClientListener.processed.get()); + testLicenseClientListener.shouldBeEnabled.set(true); - Map map = new HashMap<>(); + Map map = new HashMap<>(); TestUtils.FeatureAttributes featureAttributes1 = new TestUtils.FeatureAttributes("shield", "subscription", "platinum", "foo bar Inc.", "elasticsearch", 2, "2014-12-13", "2015-12-13"); - map.put(ESLicenses.FeatureType.SHIELD, featureAttributes1); + map.put(TestUtils.SHIELD, featureAttributes1); String licenseString = TestUtils.generateESLicenses(map); String licenseOutput = TestUtils.runLicenseGenerationTool(licenseString, pubKeyPath, priKeyPath); ESLicenses licenses = LicenseUtils.readLicensesFromString(licenseOutput); @@ -281,13 +289,17 @@ public class LicensesServiceTests extends ElasticsearchIntegrationTest { latch1.await(); - testLicenseClientListener.latch.await(); + logger.info("waiting for onEnabled"); + while(!testLicenseClientListener.processed.get()) {} + + Set enabledFeatures = licensesManagerService.enabledFeatures(); + assertTrue(enabledFeatures.contains("shield")); + } @Test public void testFeatureWithoutLicense() throws Exception { LicensesClientService clientService = licensesClientService(); - final CountDownLatch latch = new CountDownLatch(1); clientService.register("marvel", null, new LicensesClientService.Listener() { @Override public void onEnabled() { @@ -296,10 +308,16 @@ public class LicensesServiceTests extends ElasticsearchIntegrationTest { @Override public void onDisabled() { - latch.countDown(); } }); - latch.await(); + + LicensesManagerService managerService = licensesManagerService(); + assertFalse("feature should not be enabled: no licenses registered", managerService.enabledFeatures().contains("marvel")); + } + + @Test @Ignore + public void testLicenseExpiry() throws Exception { + //TODO, first figure out how to generate a license with a quick expiry in matter of seconds } @@ -313,6 +331,11 @@ public class LicensesServiceTests extends ElasticsearchIntegrationTest { return clients.getInstance(LicensesClientService.class, clients.getMasterName()); } + private LicensesService licensesService() { + final InternalTestCluster clients = internalCluster(); + return clients.getInstance(LicensesService.class, clients.getMasterName()); + } + private ClusterService masterClusterService() { final InternalTestCluster clients = internalCluster(); return clients.getInstance(ClusterService.class, clients.getMasterName()); @@ -324,4 +347,5 @@ public class LicensesServiceTests extends ElasticsearchIntegrationTest { service.clear(); } + } diff --git a/src/test/java/org/elasticsearch/license/plugin/TestConsumerPlugin.java b/src/test/java/org/elasticsearch/license/plugin/TestConsumerPlugin.java new file mode 100644 index 00000000000..cce629b1751 --- /dev/null +++ b/src/test/java/org/elasticsearch/license/plugin/TestConsumerPlugin.java @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.license.plugin; + +import org.elasticsearch.common.collect.ImmutableSet; +import org.elasticsearch.common.component.LifecycleComponent; +import org.elasticsearch.common.inject.Module; +import org.elasticsearch.plugins.AbstractPlugin; + +import java.util.Collection; + +public class TestConsumerPlugin extends AbstractPlugin { + + public TestConsumerPlugin() { + } + + @Override + public String name() { + return "test_plugin"; + } + + @Override + public String description() { + return "test licensing consumer plugin"; + } + + + @Override + public Collection> services() { + return ImmutableSet.>of(TestPluginService.class); + } + + /* + @Override + public Collection> modules() { + return ImmutableSet.>of(TestPluginServiceModule.class); + } + + public class TestPluginServiceModule extends AbstractModule { + @Override + protected void configure() { + bind(TestPluginService.class).in(Scopes.SINGLETON); + } + } + */ +} diff --git a/src/test/java/org/elasticsearch/license/plugin/TestPluginService.java b/src/test/java/org/elasticsearch/license/plugin/TestPluginService.java new file mode 100644 index 00000000000..6854f58baa4 --- /dev/null +++ b/src/test/java/org/elasticsearch/license/plugin/TestPluginService.java @@ -0,0 +1,70 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.license.plugin; + +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.common.component.AbstractLifecycleComponent; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.inject.Singleton; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.plugin.core.LicensesClientService; +import org.elasticsearch.license.plugin.core.LicensesService; + +import java.util.concurrent.atomic.AtomicBoolean; + +@Singleton +public class TestPluginService extends AbstractLifecycleComponent { + + private LicensesClientService licensesClientService; + + // should be the same string used by the license Manger to generate + // signed license + static final String FEATURE_NAME = "shield"; + + // specify the trial license spec for the feature + // example: 30 day trial on 1000 nodes + final LicensesService.TrialLicenseOptions trialLicenseOptions = new LicensesService.TrialLicenseOptions(30, 1000); + + private AtomicBoolean enabled = new AtomicBoolean(false); + + @Inject + public TestPluginService(Settings settings, LicensesClientService licensesClientService) { + super(settings); + this.licensesClientService = licensesClientService; + } + + // check if feature is enabled + public boolean enabled() { + return enabled.get(); + } + + protected void doStart() throws ElasticsearchException { + licensesClientService.register(FEATURE_NAME, + trialLicenseOptions, + new LicensingClientListener()); + } + + @Override + protected void doStop() throws ElasticsearchException { + } + + @Override + protected void doClose() throws ElasticsearchException { + } + + private class LicensingClientListener implements LicensesClientService.Listener { + + @Override + public void onEnabled() { + enabled.set(true); + } + + @Override + public void onDisabled() { + enabled.set(false); + } + } +}