diff --git a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/Graph.java b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/Graph.java index c5c037d7653..23363ce9452 100644 --- a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/Graph.java +++ b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/Graph.java @@ -46,9 +46,6 @@ public class Graph extends Plugin implements ActionPlugin { public Collection<Module> createGuiceModules() { return Collections.singletonList(b -> { XPackPlugin.bindFeatureSet(b, GraphFeatureSet.class); - if (transportClientMode) { - b.bind(GraphLicensee.class).toProvider(Providers.of(null)); - } }); } diff --git a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/GraphFeatureSet.java b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/GraphFeatureSet.java index 2cba904304c..6f350bd9ceb 100644 --- a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/GraphFeatureSet.java +++ b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/GraphFeatureSet.java @@ -10,6 +10,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.XPackFeatureSet; import java.io.IOException; @@ -20,12 +21,12 @@ import java.io.IOException; public class GraphFeatureSet implements XPackFeatureSet { private final boolean enabled; - private final GraphLicensee licensee; + private final XPackLicenseState licenseState; @Inject - public GraphFeatureSet(Settings settings, @Nullable GraphLicensee licensee, NamedWriteableRegistry namedWriteableRegistry) { + public GraphFeatureSet(Settings settings, @Nullable XPackLicenseState licenseState, NamedWriteableRegistry namedWriteableRegistry) { this.enabled = Graph.enabled(settings); - this.licensee = licensee; + this.licenseState = licenseState; namedWriteableRegistry.register(Usage.class, Usage.writeableName(Graph.NAME), Usage::new); } @@ -41,7 +42,7 @@ public class GraphFeatureSet implements XPackFeatureSet { @Override public boolean available() { - return licensee != null && licensee.isAvailable(); + return licenseState != null && licenseState.isGraphAllowed(); } @Override diff --git a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/GraphLicensee.java b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/GraphLicensee.java deleted file mode 100644 index 1468b63acbd..00000000000 --- a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/GraphLicensee.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.graph; - -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.core.License.OperationMode; -import org.elasticsearch.license.plugin.core.AbstractLicenseeComponent; - -public class GraphLicensee extends AbstractLicenseeComponent { - - public static final String ID = Graph.NAME; - - public GraphLicensee(Settings settings) { - super(settings, ID); - } - - @Override - public String[] expirationMessages() { - return new String[] { - "Graph explore APIs are disabled" - }; - } - - @Override - public String[] acknowledgmentMessages(OperationMode currentMode, OperationMode newMode) { - switch (newMode) { - case BASIC: - case STANDARD: - case GOLD: - switch (currentMode) { - case TRIAL: - case PLATINUM: - return new String[] { "Graph will be disabled" }; - } - break; - } - return Strings.EMPTY_ARRAY; - } - - /** - * Determine if Graph Exploration should be enabled. - * <p> - * Exploration is only disabled when the license has expired or if the mode is not: - * <ul> - * <li>{@link OperationMode#PLATINUM}</li> - * <li>{@link OperationMode#TRIAL}</li> - * </ul> - * - * @return {@code true} as long as the license is valid. Otherwise {@code false}. - */ - public boolean isAvailable() { - // status is volatile - Status localStatus = status; - OperationMode operationMode = localStatus.getMode(); - - boolean licensed = operationMode == OperationMode.TRIAL || operationMode == OperationMode.PLATINUM; - - return licensed && localStatus.isActive(); - } -} diff --git a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/action/TransportGraphExploreAction.java b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/action/TransportGraphExploreAction.java index 2d58ac38282..8312c23f519 100644 --- a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/action/TransportGraphExploreAction.java +++ b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/action/TransportGraphExploreAction.java @@ -24,6 +24,7 @@ import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.license.plugin.core.LicenseUtils; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.AggregationBuilder; import org.elasticsearch.search.aggregations.bucket.sampler.DiversifiedAggregationBuilder; @@ -37,7 +38,7 @@ import org.elasticsearch.search.aggregations.bucket.terms.support.IncludeExclude import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; -import org.elasticsearch.xpack.graph.GraphLicensee; +import org.elasticsearch.xpack.graph.Graph; import org.elasticsearch.xpack.graph.action.Connection.ConnectionId; import org.elasticsearch.xpack.graph.action.GraphExploreRequest.TermBoost; import org.elasticsearch.xpack.graph.action.Vertex.VertexId; @@ -58,7 +59,7 @@ import java.util.concurrent.atomic.AtomicBoolean; public class TransportGraphExploreAction extends HandledTransportAction<GraphExploreRequest, GraphExploreResponse> { private final TransportSearchAction searchAction; - protected final GraphLicensee licensee; + protected final XPackLicenseState licenseState; static class VertexPriorityQueue extends PriorityQueue<Vertex> { @@ -76,19 +77,19 @@ public class TransportGraphExploreAction extends HandledTransportAction<GraphExp @Inject public TransportGraphExploreAction(Settings settings, ThreadPool threadPool, TransportSearchAction transportSearchAction, TransportService transportService, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver, - GraphLicensee licensee) { + XPackLicenseState licenseState) { super(settings, GraphExploreAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver, GraphExploreRequest::new); this.searchAction = transportSearchAction; - this.licensee = licensee; + this.licenseState = licenseState; } @Override protected void doExecute(GraphExploreRequest request, ActionListener<GraphExploreResponse> listener) { - if (licensee.isAvailable()) { + if (licenseState.isGraphAllowed()) { new AsyncGraphAction(request, listener).start(); } else { - listener.onFailure(LicenseUtils.newComplianceException(GraphLicensee.ID)); + listener.onFailure(LicenseUtils.newComplianceException(Graph.NAME)); } } diff --git a/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/GraphFeatureSetTests.java b/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/GraphFeatureSetTests.java index 56d3b949bbe..8c612d17c57 100644 --- a/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/GraphFeatureSetTests.java +++ b/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/GraphFeatureSetTests.java @@ -7,9 +7,8 @@ package org.elasticsearch.xpack.graph; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.xpack.graph.GraphFeatureSet; -import org.elasticsearch.xpack.graph.GraphLicensee; import org.junit.Before; import static org.hamcrest.core.Is.is; @@ -24,24 +23,24 @@ import static org.mockito.Mockito.when; */ public class GraphFeatureSetTests extends ESTestCase { - private GraphLicensee licensee; + private XPackLicenseState licenseState; private NamedWriteableRegistry namedWriteableRegistry; @Before public void init() throws Exception { - licensee = mock(GraphLicensee.class); + licenseState = mock(XPackLicenseState.class); namedWriteableRegistry = mock(NamedWriteableRegistry.class); } public void testWritableRegistration() throws Exception { - new GraphFeatureSet(Settings.EMPTY, licensee, namedWriteableRegistry); + new GraphFeatureSet(Settings.EMPTY, licenseState, namedWriteableRegistry); verify(namedWriteableRegistry).register(eq(GraphFeatureSet.Usage.class), eq("xpack.usage.graph"), anyObject()); } public void testAvailable() throws Exception { - GraphFeatureSet featureSet = new GraphFeatureSet(Settings.EMPTY, licensee, namedWriteableRegistry); + GraphFeatureSet featureSet = new GraphFeatureSet(Settings.EMPTY, licenseState, namedWriteableRegistry); boolean available = randomBoolean(); - when(licensee.isAvailable()).thenReturn(available); + when(licenseState.isGraphAllowed()).thenReturn(available); assertThat(featureSet.available(), is(available)); } @@ -55,7 +54,7 @@ public class GraphFeatureSetTests extends ESTestCase { } else { settings.put("xpack.graph.enabled", enabled); } - GraphFeatureSet featureSet = new GraphFeatureSet(settings.build(), licensee, namedWriteableRegistry); + GraphFeatureSet featureSet = new GraphFeatureSet(settings.build(), licenseState, namedWriteableRegistry); assertThat(featureSet.enabled(), is(enabled)); } diff --git a/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/license/LicenseTests.java b/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/license/LicenseTests.java deleted file mode 100644 index d68c5195402..00000000000 --- a/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/license/LicenseTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.graph.license; - -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.core.License.OperationMode; -import org.elasticsearch.license.plugin.core.AbstractLicenseeTestCase; -import org.elasticsearch.xpack.graph.GraphLicensee; - -import static org.hamcrest.Matchers.is; - -public class LicenseTests extends AbstractLicenseeTestCase { - - GraphLicensee graphLicensee = new GraphLicensee(Settings.EMPTY); - - public void testPlatinumTrialLicenseCanDoEverything() throws Exception { - setOperationMode(graphLicensee, randomTrialOrPlatinumMode()); - assertLicensePlatinumTrialBehaviour(graphLicensee); - } - - public void testBasicLicenseIsDisabled() throws Exception { - setOperationMode(graphLicensee, OperationMode.BASIC); - assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee); - } - - public void testStandardLicenseIsDisabled() throws Exception { - setOperationMode(graphLicensee, OperationMode.STANDARD); - assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee); - } - - public void testNoLicenseDoesNotWork() { - setOperationMode(graphLicensee, OperationMode.BASIC); - disable(graphLicensee); - assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee); - } - - public void testExpiredPlatinumTrialLicenseIsRestricted() throws Exception { - setOperationMode(graphLicensee, randomTrialOrPlatinumMode()); - disable(graphLicensee); - assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee); - } - - public void testUpgradingFromBasicLicenseWorks() { - setOperationMode(graphLicensee, OperationMode.BASIC); - assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee); - - setOperationMode(graphLicensee, randomTrialOrPlatinumMode()); - assertLicensePlatinumTrialBehaviour(graphLicensee); - } - - public void testDowngradingToBasicLicenseWorks() { - setOperationMode(graphLicensee, randomTrialOrPlatinumMode()); - assertLicensePlatinumTrialBehaviour(graphLicensee); - - setOperationMode(graphLicensee, OperationMode.BASIC); - assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee); - } - - public void testUpgradingFromStandardLicenseWorks() { - setOperationMode(graphLicensee, OperationMode.STANDARD); - assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee); - - setOperationMode(graphLicensee, randomTrialOrPlatinumMode()); - assertLicensePlatinumTrialBehaviour(graphLicensee); - } - - public void testDowngradingToStandardLicenseWorks() { - setOperationMode(graphLicensee, randomTrialOrPlatinumMode()); - assertLicensePlatinumTrialBehaviour(graphLicensee); - - setOperationMode(graphLicensee, OperationMode.STANDARD); - assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee); - } - - public void testDowngradingToGoldLicenseWorks() { - setOperationMode(graphLicensee, randomTrialOrPlatinumMode()); - assertLicensePlatinumTrialBehaviour(graphLicensee); - - setOperationMode(graphLicensee, OperationMode.GOLD); - assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee); - } - - public void testUpgradingExpiredLicenseWorks() { - setOperationMode(graphLicensee, randomTrialOrPlatinumMode()); - disable(graphLicensee); - assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(graphLicensee); - - setOperationMode(graphLicensee, randomTrialOrPlatinumMode()); - assertLicensePlatinumTrialBehaviour(graphLicensee); - } - - private void assertLicensePlatinumTrialBehaviour(GraphLicensee graphLicensee) { - assertThat("Expected graph exploration to be allowed", graphLicensee.isAvailable(), is(true)); - } - - private void assertLicenseBasicOrStandardGoldOrNoneOrExpiredBehaviour(GraphLicensee graphLicensee) { - assertThat("Expected graph exploration not to be allowed", graphLicensee.isAvailable(), is(false)); - } -} diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/Licensing.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/Licensing.java index 8fcc604d28f..aeaca77fbeb 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/Licensing.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/Licensing.java @@ -5,6 +5,11 @@ */ package org.elasticsearch.license.plugin; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.cluster.metadata.MetaData; @@ -21,23 +26,14 @@ import org.elasticsearch.license.plugin.action.put.PutLicenseAction; import org.elasticsearch.license.plugin.action.put.TransportPutLicenseAction; import org.elasticsearch.license.plugin.core.LicensesMetaData; import org.elasticsearch.license.plugin.core.LicenseService; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.license.plugin.rest.RestDeleteLicenseAction; import org.elasticsearch.license.plugin.rest.RestGetLicenseAction; import org.elasticsearch.license.plugin.rest.RestPutLicenseAction; import org.elasticsearch.plugins.ActionPlugin; import org.elasticsearch.rest.RestHandler; import org.elasticsearch.watcher.ResourceWatcherService; -import org.elasticsearch.xpack.graph.GraphLicensee; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; -import org.elasticsearch.xpack.security.SecurityLicenseState; -import org.elasticsearch.xpack.security.SecurityLicensee; import org.elasticsearch.xpack.support.clock.Clock; -import org.elasticsearch.xpack.watcher.WatcherLicensee; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; import static java.util.Collections.emptyList; import static org.elasticsearch.xpack.XPackPlugin.isTribeNode; @@ -87,16 +83,10 @@ public class Licensing implements ActionPlugin { public Collection<Object> createComponents(ClusterService clusterService, Clock clock, Environment environment, ResourceWatcherService resourceWatcherService, - SecurityLicenseState securityLicenseState) { - SecurityLicensee securityLicensee = new SecurityLicensee(settings, securityLicenseState); - WatcherLicensee watcherLicensee = new WatcherLicensee(settings); - MonitoringLicensee monitoringLicensee = new MonitoringLicensee(settings); - GraphLicensee graphLicensee = new GraphLicensee(settings); + XPackLicenseState licenseState) { LicenseService licenseService = new LicenseService(settings, clusterService, clock, - environment, resourceWatcherService, - Arrays.asList(securityLicensee, watcherLicensee, monitoringLicensee, graphLicensee)); - - return Arrays.asList(licenseService, securityLicenseState, securityLicensee, watcherLicensee, monitoringLicensee, graphLicensee); + environment, resourceWatcherService, licenseState); + return Arrays.asList(licenseService, licenseState); } public List<Setting<?>> getSettings() { diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/AbstractLicenseeComponent.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/AbstractLicenseeComponent.java deleted file mode 100644 index 5857f603ef8..00000000000 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/AbstractLicenseeComponent.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.license.plugin.core; - -import org.elasticsearch.common.component.AbstractComponent; -import org.elasticsearch.common.component.AbstractLifecycleComponent; -import org.elasticsearch.common.settings.Settings; - -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -/** - * A supporting base class for injectable Licensee components. - */ -public abstract class AbstractLicenseeComponent extends AbstractComponent implements Licensee { - - private final String id; - private final List<Listener> listeners = new CopyOnWriteArrayList<>(); - - // we initialize the licensee state to enabled with trial operation mode - protected volatile Status status = Status.ENABLED; - - protected AbstractLicenseeComponent(Settings settings, String id) { - super(settings); - this.id = id; - } - - @Override - public final String id() { - return id; - } - - /** - * @return the current status of this licensee (can never be null) - */ - public Status getStatus() { - return status; - } - - public void add(Listener listener) { - listeners.add(listener); - } - - @Override - public void onChange(Status status) { - this.status = status; - logger.trace("[{}] is running in [{}] mode", id(), status); - for (Listener listener : listeners) { - listener.onChange(status); - } - } - - public interface Listener { - void onChange(Status status); - } - -} diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicenseService.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicenseService.java index 5f36131bac6..322bd925537 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicenseService.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicenseService.java @@ -44,18 +44,13 @@ import java.util.Locale; import java.util.Map; import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Collectors; /** - * Service responsible for managing {@link LicensesMetaData} - * Interfaces through which this is exposed are: - * - LicensesClientService - responsible for listener registration of consumer plugin(s) + * Service responsible for managing {@link LicensesMetaData}. * <p> - * Notification Scheme: - * <p> - * All registered listeners are notified of the current license upon registration or when a new license is installed in the cluster state. - * When a new license is notified as enabled to the registered listener, a notification is scheduled at the time of license expiry. - * Registered listeners are notified using {@link #onUpdate(LicensesMetaData)} + * On the master node, the service handles updating the cluster state when a new license is registered. + * It also listens on all nodes for cluster state updates, and updates {@link XPackLicenseState} when + * the license changes are detected in the cluster state. */ public class LicenseService extends AbstractLifecycleComponent implements ClusterStateListener, SchedulerEngine.Listener { @@ -65,14 +60,12 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste /** * Duration of grace period after a license has expired */ - public static final TimeValue GRACE_PERIOD_DURATION = days(7); + static final TimeValue GRACE_PERIOD_DURATION = days(7); private final ClusterService clusterService; - /** - * Currently active consumers to notify to - */ - private final List<InternalLicensee> registeredLicensees; + /** The xpack feature state to update when license changes are made. */ + private final XPackLicenseState licenseState; /** * Currently active license @@ -104,115 +97,70 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste "please read the following messages and update the license again, this time with the \"acknowledge=true\" parameter:"; public LicenseService(Settings settings, ClusterService clusterService, Clock clock, Environment env, - ResourceWatcherService resourceWatcherService, List<Licensee> registeredLicensees) { + ResourceWatcherService resourceWatcherService, XPackLicenseState licenseState) { super(settings); this.clusterService = clusterService; this.clock = clock; this.scheduler = new SchedulerEngine(clock); - this.registeredLicensees = registeredLicensees.stream().map(InternalLicensee::new).collect(Collectors.toList()); + this.licenseState = licenseState; this.operationModeFileWatcher = new OperationModeFileWatcher(resourceWatcherService, - XPackPlugin.resolveConfigFile(env, "license_mode"), logger, () -> notifyLicensees(getLicense())); + XPackPlugin.resolveConfigFile(env, "license_mode"), logger, () -> updateLicenseState(getLicense())); this.scheduler.register(this); populateExpirationCallbacks(); } + private void logExpirationWarning(long expirationMillis, boolean expired) { + String expiredMsg = expired ? "will expire" : "expired"; + String general = LoggerMessageFormat.format(null, "\n" + + "#\n" + + "# License [{}] on [{}]. If you have a new license, please update it.\n" + + "# Otherwise, please reach out to your support contact.\n" + + "# ", expiredMsg, DATE_FORMATTER.printer().print(expirationMillis)); + if (expired) { + general = general.toUpperCase(Locale.ROOT); + } + StringBuilder builder = new StringBuilder(general); + builder.append(System.lineSeparator()); + if (expired) { + builder.append("# COMMERCIAL PLUGINS OPERATING WITH REDUCED FUNCTIONALITY"); + } else { + builder.append("# Commercial plugins operate with reduced functionality on license expiration:"); + } + XPackLicenseState.EXPIRATION_MESSAGES.forEach((feature, messages) -> { + if (messages.length > 0) { + builder.append(System.lineSeparator()); + builder.append("# - "); + builder.append(feature); + for (String message : messages) { + builder.append(System.lineSeparator()); + builder.append("# - "); + builder.append(message); + } + } + }); + logger.warn("{}", builder); + } + private void populateExpirationCallbacks() { expirationCallbacks.add(new ExpirationCallback.Pre(days(7), days(25), days(1)) { - @Override - public void on(License license) { - String general = LoggerMessageFormat.format(null, "\n" + - "#\n" + - "# License will expire on [{}]. If you have a new license, please update it.\n" + - "# Otherwise, please reach out to your support contact.\n" + - "# ", DATE_FORMATTER.printer().print(license.expiryDate())); - if (!registeredLicensees.isEmpty()) { - StringBuilder builder = new StringBuilder(general); - builder.append(System.lineSeparator()); - builder.append("# Commercial plugins operate with reduced functionality on license " + - "expiration:"); - for (InternalLicensee licensee : registeredLicensees) { - if (licensee.expirationMessages().length > 0) { - builder.append(System.lineSeparator()); - builder.append("# - "); - builder.append(licensee.id()); - for (String message : licensee.expirationMessages()) { - builder.append(System.lineSeparator()); - builder.append("# - "); - builder.append(message); - } - } - } - logger.warn("{}", builder); - } else { - logger.warn("{}", general); - } - } - } - ); + @Override + public void on(License license) { + logExpirationWarning(license.expiryDate(), false); + } + }); expirationCallbacks.add(new ExpirationCallback.Pre(days(0), days(7), TimeValue.timeValueMinutes(10)) { - @Override - public void on(License license) { - String general = LoggerMessageFormat.format(null, "\n" + - "#\n" + - "# License will expire on [{}]. If you have a new license, please update it.\n" + - "# Otherwise, please reach out to your support contact.\n" + - "# ", DATE_FORMATTER.printer().print(license.expiryDate())); - if (!registeredLicensees.isEmpty()) { - StringBuilder builder = new StringBuilder(general); - builder.append(System.lineSeparator()); - builder.append("# Commercial plugins operate with reduced functionality on license " + - "expiration:"); - for (InternalLicensee licensee : registeredLicensees) { - if (licensee.expirationMessages().length > 0) { - builder.append(System.lineSeparator()); - builder.append("# - "); - builder.append(licensee.id()); - for (String message : licensee.expirationMessages()) { - builder.append(System.lineSeparator()); - builder.append("# - "); - builder.append(message); - } - } - } - logger.warn("{}", builder.toString()); - } else { - logger.warn("{}", general); - } - } - } - ); + @Override + public void on(License license) { + logExpirationWarning(license.expiryDate(), false); + } + }); expirationCallbacks.add(new ExpirationCallback.Post(days(0), null, TimeValue.timeValueMinutes(10)) { - @Override - public void on(License license) { - // logged when grace period begins - String general = LoggerMessageFormat.format(null, "\n" + - "#\n" + - "# LICENSE EXPIRED ON [{}]. IF YOU HAVE A NEW LICENSE, PLEASE\n" + - "# UPDATE IT. OTHERWISE, PLEASE REACH OUT TO YOUR SUPPORT CONTACT.\n" + - "# ", DATE_FORMATTER.printer().print(license.expiryDate())); - if (!registeredLicensees.isEmpty()) { - StringBuilder builder = new StringBuilder(general); - builder.append(System.lineSeparator()); - builder.append("# COMMERCIAL PLUGINS OPERATING WITH REDUCED FUNCTIONALITY"); - for (InternalLicensee licensee : registeredLicensees) { - if (licensee.expirationMessages().length > 0) { - builder.append(System.lineSeparator()); - builder.append("# - "); - builder.append(licensee.id()); - for (String message : licensee.expirationMessages()) { - builder.append(System.lineSeparator()); - builder.append("# - "); - builder.append(message); - } - } - } - logger.warn("{}", builder.toString()); - } else { - logger.warn("{}", general); - } - } - } - ); + @Override + public void on(License license) { + // logged when grace period begins + logExpirationWarning(license.expiryDate(), true); + } + }); } /** @@ -228,23 +176,23 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste listener.onResponse(new PutLicenseResponse(true, LicensesStatus.EXPIRED)); } else { if (!request.acknowledged()) { + // TODO: ack messages should be generated on the master, since another node's cluster state may be behind... final License currentLicense = getLicense(); if (currentLicense != null) { - Map<String, String[]> acknowledgeMessages = new HashMap<>(registeredLicensees.size() + 1); + Map<String, String[]> acknowledgeMessages = new HashMap<>(); if (!License.isAutoGeneratedLicense(currentLicense.signature()) // current license is not auto-generated && currentLicense.issueDate() > newLicense.issueDate()) { // and has a later issue date - acknowledgeMessages.put("license", - new String[]{"The new license is older than the currently installed license. Are you sure you want to " + - "override the current license?"}); + acknowledgeMessages.put("license", new String[]{ + "The new license is older than the currently installed license. " + + "Are you sure you want to override the current license?"}); } - for (InternalLicensee licensee : registeredLicensees) { - String[] listenerAcknowledgeMessages = licensee.acknowledgmentMessages( - currentLicense.operationMode(), newLicense.operationMode()); - if (listenerAcknowledgeMessages.length > 0) { - acknowledgeMessages.put(licensee.id(), listenerAcknowledgeMessages); + XPackLicenseState.ACKNOWLEDGMENT_MESSAGES.forEach((feature, ackMessages) -> { + String[] messages = ackMessages.apply(currentLicense.operationMode(), newLicense.operationMode()); + if (messages.length > 0) { + acknowledgeMessages.put(feature, messages); } - } - if (!acknowledgeMessages.isEmpty()) { + }); + if (acknowledgeMessages.isEmpty() == false) { // needs acknowledgement listener.onResponse(new PutLicenseResponse(false, LicensesStatus.VALID, ACKNOWLEDGEMENT_HEADER, acknowledgeMessages)); @@ -280,7 +228,7 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste if (licensesMetaData != null) { final License license = licensesMetaData.getLicense(); if (event.getJobName().equals(LICENSE_JOB)) { - notifyLicensees(license); + updateLicenseState(license); } else if (event.getJobName().startsWith(ExpirationCallback.EXPIRATION_JOB_PREFIX)) { expirationCallbacks.stream() .filter(expirationCallback -> expirationCallback.getId().equals(event.getJobName())) @@ -315,17 +263,6 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste }); } - public Licensee.Status licenseeStatus(License license) { - if (license == null) { - return new Licensee.Status(License.OperationMode.MISSING, false); - } - long time = clock.millis(); - boolean active = time >= license.issueDate() && - time < license.expiryDate() + GRACE_PERIOD_DURATION.getMillis(); - - return new Licensee.Status(license.operationMode(), active); - } - public License getLicense() { final License license = getLicense(clusterService.state().metaData().custom(LicensesMetaData.TYPE)); return license == LicensesMetaData.LICENSE_TOMBSTONE ? null : license; @@ -379,15 +316,25 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste protected void doStart() throws ElasticsearchException { clusterService.add(this); scheduler.start(Collections.emptyList()); - registeredLicensees.forEach(x -> initLicensee(x.licensee)); + logger.debug("initializing license state"); + final ClusterState clusterState = clusterService.state(); + if (clusterService.lifecycleState() == Lifecycle.State.STARTED + && clusterState.blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK) == false + && clusterState.nodes().getMasterNode() != null) { + final LicensesMetaData currentMetaData = clusterState.metaData().custom(LicensesMetaData.TYPE); + if (clusterState.getNodes().isLocalNodeElectedMaster() && + (currentMetaData == null || currentMetaData.getLicense() == null)) { + // triggers a cluster changed event + // eventually notifying the current licensee + registerTrialLicense(); + } + } } @Override protected void doStop() throws ElasticsearchException { clusterService.remove(this); scheduler.stop(); - // clear all handlers - registeredLicensees.clear(); // clear current license currentLicense.set(null); } @@ -432,23 +379,18 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste } } - private void notifyLicensees(final License license) { + protected void updateLicenseState(final License license) { if (license == LicensesMetaData.LICENSE_TOMBSTONE) { // implies license has been explicitly deleted - // update licensee states - registeredLicensees.forEach(InternalLicensee::onRemove); + licenseState.update(License.OperationMode.MISSING, false); return; } if (license != null) { - logger.debug("notifying [{}] listeners", registeredLicensees.size()); long time = clock.millis(); boolean active = time >= license.issueDate() && time < license.expiryDate() + GRACE_PERIOD_DURATION.getMillis(); + licenseState.update(license.operationMode(), active); - Licensee.Status status = new Licensee.Status(license.operationMode(), active); - for (InternalLicensee licensee : registeredLicensees) { - licensee.onChange(status); - } if (active) { if (time < license.expiryDate()) { logger.debug("license [{}] - valid", license.uid()); @@ -487,7 +429,7 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste previousLicense.removeOperationModeFileWatcher(); } } - notifyLicensees(license); + updateLicenseState(license); } } @@ -510,24 +452,6 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste }; } - private void initLicensee(Licensee licensee) { - logger.debug("initializing licensee [{}]", licensee.id()); - final ClusterState clusterState = clusterService.state(); - if (clusterService.lifecycleState() == Lifecycle.State.STARTED - && clusterState.blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK) == false - && clusterState.nodes().getMasterNode() != null) { - final LicensesMetaData currentMetaData = clusterState.metaData().custom(LicensesMetaData.TYPE); - if (clusterState.getNodes().isLocalNodeElectedMaster() && - (currentMetaData == null || currentMetaData.getLicense() == null)) { - // triggers a cluster changed event - // eventually notifying the current licensee - registerTrialLicense(); - } else { - notifyLicensees(currentMetaData.getLicense()); - } - } - } - License getLicense(final LicensesMetaData metaData) { if (metaData != null) { License license = metaData.getLicense(); @@ -543,48 +467,4 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste } return null; } - - /** - * Stores acknowledgement, expiration and license notification callbacks - * for a registered listener - */ - private final class InternalLicensee { - volatile Licensee.Status currentStatus = Licensee.Status.MISSING; - - private final Licensee licensee; - - private InternalLicensee(Licensee licensee) { - this.licensee = licensee; - } - - @Override - public String toString() { - return "(listener: " + licensee.id() + ", state: " + currentStatus + ")"; - } - - public String id() { - return licensee.id(); - } - - public String[] expirationMessages() { - return licensee.expirationMessages(); - } - - public String[] acknowledgmentMessages(License.OperationMode currentMode, License.OperationMode newMode) { - return licensee.acknowledgmentMessages(currentMode, newMode); - } - - public synchronized void onChange(final Licensee.Status status) { - if (currentStatus == null // not yet initialized - || !currentStatus.equals(status)) { // current license has changed - logger.debug("licensee [{}] notified", licensee.id()); - licensee.onChange(status); - currentStatus = status; - } - } - - public void onRemove() { - onChange(Licensee.Status.MISSING); - } - } } \ No newline at end of file diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/Licensee.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/Licensee.java deleted file mode 100644 index 1fcc12e6976..00000000000 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/Licensee.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.license.plugin.core; - -import org.elasticsearch.license.core.License.OperationMode; - -import java.util.Locale; -import java.util.Objects; - -public interface Licensee { - - /** - * Unique id used to log expiry and - * acknowledgment messages - */ - String id(); - - /** - * Messages to be printed when - * logging license expiry warnings - */ - String[] expirationMessages(); - - /** - * Messages to be returned when - * changing from current operation mode - * to new operation mode - */ - String[] acknowledgmentMessages(OperationMode currentMode, OperationMode newMode); - - /** - * Notifies when a new license is activated - * or when a license state change has occurred - */ - void onChange(Status status); - - /** - * {@code Status} represents both the type and state of a license. - * <p> - * Most places in the code are expected to use {@code volatile} {@code Status} fields. It's important to follow use a local reference - * whenever checking different parts of the {@code Status}: - * <pre> - * Status status = this.status; - * return status.isActive() && - * (status.getMode() == OperationMode.TRIAL || status.getMode == OperationMode.PLATINUM); - * </pre> - * Otherwise the license has the potential to change in-between both checks. - */ - class Status { - - public static Status ENABLED = new Status(OperationMode.TRIAL, true); - public static Status MISSING = new Status(OperationMode.MISSING, false); - - private final OperationMode mode; - private final boolean active; - - public Status(OperationMode mode, boolean active) { - this.mode = mode; - this.active = active; - } - - /** - * Returns the operation mode of the license - * responsible for the current <code>licenseState</code> - * <p> - * Note: Knowing the mode does not indicate whether the license is active. If that matters (e.g., - * disabling services when a license becomes disabled), then check {@link #isActive()}. - */ - public OperationMode getMode() { - return mode; - } - - /** Returns true if the license is within the issue date and grace period, or false otherwise */ - public boolean isActive() { - return active; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Status status = (Status) o; - return active == status.active && - mode == status.mode; - } - - @Override - public int hashCode() { - return Objects.hash(mode, active); - } - - @Override - public String toString() { - if (active) { - return mode.name().toLowerCase(Locale.ROOT); - } else { - return "disabled " + mode.name().toLowerCase(Locale.ROOT); - } - } - } -} diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicenseTribeTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicenseTribeTests.java index 29d0f7766b5..663c57b8166 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicenseTribeTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicenseTribeTests.java @@ -15,7 +15,7 @@ import org.elasticsearch.license.plugin.action.put.PutLicenseAction; import org.elasticsearch.license.plugin.action.put.PutLicenseRequest; import org.elasticsearch.xpack.TribeTransportTestCase; -import static org.elasticsearch.license.plugin.TestUtils.generateSignedLicense; +import static org.elasticsearch.license.plugin.core.TestUtils.generateSignedLicense; public class LicenseTribeTests extends TribeTransportTestCase { diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicensesTransportTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicensesTransportTests.java index a184dc50570..0c83cfc45a4 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicensesTransportTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicensesTransportTests.java @@ -19,6 +19,7 @@ import org.elasticsearch.license.plugin.action.put.PutLicenseAction; import org.elasticsearch.license.plugin.action.put.PutLicenseRequestBuilder; import org.elasticsearch.license.plugin.action.put.PutLicenseResponse; import org.elasticsearch.license.plugin.core.LicensesStatus; +import org.elasticsearch.license.plugin.core.TestUtils; import org.elasticsearch.xpack.monitoring.Monitoring; import org.elasticsearch.node.Node; import org.elasticsearch.plugins.Plugin; @@ -30,9 +31,8 @@ import org.elasticsearch.xpack.watcher.Watcher; import java.util.Collection; import java.util.Collections; -import static org.elasticsearch.license.plugin.TestUtils.dateMath; -import static org.elasticsearch.license.plugin.TestUtils.generateExpiredLicense; -import static org.elasticsearch.license.plugin.TestUtils.generateSignedLicense; +import static org.elasticsearch.license.plugin.core.TestUtils.generateExpiredLicense; +import static org.elasticsearch.license.plugin.core.TestUtils.generateSignedLicense; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.not; diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/AbstractLicenseServiceTestCase.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/AbstractLicenseServiceTestCase.java index fc2977c8ff0..4b524c85c85 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/AbstractLicenseServiceTestCase.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/AbstractLicenseServiceTestCase.java @@ -5,8 +5,6 @@ */ package org.elasticsearch.license.plugin.core; -import java.util.Arrays; - import org.elasticsearch.Version; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterState; @@ -51,11 +49,11 @@ public abstract class AbstractLicenseServiceTestCase extends ESTestCase { environment = mock(Environment.class); } - protected void setInitialState(License license, Licensee... licensees) { + protected void setInitialState(License license, XPackLicenseState licenseState) { Path tempDir = createTempDir(); when(environment.configFile()).thenReturn(tempDir); licenseService = new LicenseService(Settings.EMPTY, clusterService, clock, environment, - resourceWatcherService, Arrays.asList(licensees)); + resourceWatcherService, licenseState); ClusterState state = mock(ClusterState.class); final ClusterBlocks noBlock = ClusterBlocks.builder().build(); when(state.blocks()).thenReturn(noBlock); diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/AbstractLicenseeTestCase.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/AbstractLicenseeTestCase.java deleted file mode 100644 index 7390fa8c40a..00000000000 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/AbstractLicenseeTestCase.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.license.plugin.core; - -import org.elasticsearch.common.component.AbstractComponent; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.core.License.OperationMode; -import org.elasticsearch.test.ESTestCase; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -import static org.hamcrest.Matchers.equalTo; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * Provides helper methods for {@link Licensee} implementations. - * <p> - * Note: This requires that this class be on the classpath for those implementations. - */ -public abstract class AbstractLicenseeTestCase extends ESTestCase { - /** - * Ensure when going from {@code fromMode} to {@code toMode}, nothing gets reported. - * <p> - * This will randomly {@code null}-out the {@code fromMode} license. - * - * @param fromMode Original / current license - * @param toMode New license - * @param licensee The licensee to test - */ - public static void assertEmptyAck(OperationMode fromMode, OperationMode toMode, Licensee licensee) { - // test it - String[] messages = licensee.acknowledgmentMessages(fromMode, toMode); - - assertThat(fromToMessage(fromMode, toMode), messages.length, equalTo(0)); - } - - /** - * Ensure when going from {@code fromMode} to {@code toMode}, nothing gets reported. - * <p> - * This will randomly {@code null}-out the {@code fromMode} license. - * - * @param fromMode Original / current license - * @param toMode New license - * @param licenseeSupplier Supplies the licensee to test - */ - public static void assertEmptyAck(OperationMode fromMode, OperationMode toMode, Supplier<Licensee> licenseeSupplier) { - assertEmptyAck(fromMode, toMode, licenseeSupplier.get()); - } - - /** - * Get the ack when changing {@code fromMode} to {@code toMode}. - * <p> - * This just serves to remove a lot of duplicated code. - * - * @param fromMode Original / current license - * @param toMode New license - * @param licensee The licensee to test - */ - public static String[] ackLicenseChange(OperationMode fromMode, OperationMode toMode, Licensee licensee) { - return licensee.acknowledgmentMessages(fromMode, toMode); - } - - /** - * Ensure when going from {@code fromMode} to {@code toMode}, nothing gets reported. - * <p> - * This just serves to remove a lot of duplicated code. - * - * @param fromMode Original / current license - * @param toMode New license - * @param licenseeSupplier Supplies the licensee to test - */ - public static String[] ackLicenseChange(OperationMode fromMode, OperationMode toMode, Supplier<Licensee> licenseeSupplier) { - return ackLicenseChange(fromMode, toMode, licenseeSupplier.get()); - } - - /** - * Randomly get {@link OperationMode#TRIAL} or {@link OperationMode#PLATINUM}. - * - * @return Never {@code null}. - */ - public static OperationMode randomTrialOrPlatinumMode() { - return randomFrom(OperationMode.TRIAL, OperationMode.PLATINUM); - } - - /** - * Randomly get {@link OperationMode#TRIAL}, {@link OperationMode#STANDARD}, {@link OperationMode#GOLD}, or - * {@link OperationMode#PLATINUM}. - * - * @return Never {@code null}. - */ - public static OperationMode randomTrialStandardGoldOrPlatinumMode() { - return randomFrom(OperationMode.TRIAL, OperationMode.STANDARD, OperationMode.GOLD, OperationMode.PLATINUM); - } - - /** - * Randomly get any {@link OperationMode}. - * - * @return Never {@code null}. - */ - public static OperationMode randomMode() { - return randomFrom(OperationMode.values()); - } - - /** - * Get any {@link #randomMode() mode}, except the selected {@code mode}. - * - * @param mode The mode to exclude. - * @return Never {@code null}. - */ - public static OperationMode randomModeExcept(OperationMode mode) { - return randomValueOtherThan(mode, AbstractLicenseeTestCase::randomMode); - } - - /** - * Get a random value from the {@code values} that passes {@code filter}. - * - * @param values The values to filter and randomly select from - * @param filter The filter to apply - * @return Never {@code null}. - * @throws IllegalArgumentException if nothing matches the {@code filter} - * @see #randomFrom(Object[]) - */ - public static <T> T randomFrom(T[] values, Predicate<T> filter) { - return randomFrom(Arrays.stream(values).filter(filter).collect(Collectors.toList())); - } - - /** - * Get a message to show with assertions for license transition. - * - * @param fromMode Coming "from" mode - * @param toMode Going "to" mode - * @return Never {@code null}. - */ - public static String fromToMessage(OperationMode fromMode, OperationMode toMode) { - return String.format(Locale.ROOT, "From [%s] to [%s]", fromMode, toMode); - } - - private OperationMode operationMode; - - public void setOperationMode(Licensee licensee, OperationMode operationMode) { - this.operationMode = operationMode; - enable(licensee); - } - - public void disable(Licensee licensee) { - licensee.onChange(new Licensee.Status(operationMode, false)); - } - - public void enable(Licensee licensee) { - licensee.onChange(new Licensee.Status(operationMode, true)); - } -} diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseClusterChangeTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseClusterChangeTests.java index 6af2c7ad787..1b4e6aac870 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseClusterChangeTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseClusterChangeTests.java @@ -16,7 +16,6 @@ import org.elasticsearch.cluster.node.DiscoveryNodes; import org.elasticsearch.common.transport.LocalTransportAddress; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.TestUtils; import org.junit.After; import org.junit.Before; import org.mockito.ArgumentCaptor; @@ -31,12 +30,12 @@ import static org.mockito.Mockito.when; public class LicenseClusterChangeTests extends AbstractLicenseServiceTestCase { - private TestUtils.AssertingLicensee licensee; + private TestUtils.AssertingLicenseState licenseState; @Before public void setup() { - licensee = new TestUtils.AssertingLicensee("LicenseClusterChangeTests", logger); - setInitialState(null, licensee); + licenseState = new TestUtils.AssertingLicenseState(); + setInitialState(null, licenseState); licenseService.start(); } @@ -52,8 +51,8 @@ public class LicenseClusterChangeTests extends AbstractLicenseServiceTestCase { MetaData metaData = MetaData.builder().putCustom(LicensesMetaData.TYPE, new LicensesMetaData(license)).build(); ClusterState newState = ClusterState.builder(new ClusterName("a")).metaData(metaData).build(); licenseService.clusterChanged(new ClusterChangedEvent("simulated", newState, oldState)); - assertThat(licensee.statuses.size(), equalTo(1)); - assertTrue(licensee.statuses.get(0).isActive()); + assertThat(licenseState.activeUpdates.size(), equalTo(1)); + assertTrue(licenseState.activeUpdates.get(0)); } public void testNoNotificationOnExistingLicense() throws Exception { @@ -62,7 +61,7 @@ public class LicenseClusterChangeTests extends AbstractLicenseServiceTestCase { ClusterState newState = ClusterState.builder(new ClusterName("a")).metaData(metaData).build(); ClusterState oldState = ClusterState.builder(newState).build(); licenseService.clusterChanged(new ClusterChangedEvent("simulated", newState, oldState)); - assertThat(licensee.statuses.size(), equalTo(0)); + assertThat(licenseState.activeUpdates.size(), equalTo(0)); } public void testTrialLicenseGeneration() throws Exception { diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseRegistrationTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseRegistrationTests.java index a4c49cf2837..577d2a6df01 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseRegistrationTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseRegistrationTests.java @@ -9,7 +9,6 @@ import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ClusterStateUpdateTask; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.license.plugin.TestUtils; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; @@ -21,9 +20,8 @@ import static org.mockito.Mockito.when; public class LicenseRegistrationTests extends AbstractLicenseServiceTestCase { public void testTrialLicenseRequestOnEmptyLicenseState() throws Exception { - TestUtils.AssertingLicensee licensee = new TestUtils.AssertingLicensee( - "testTrialLicenseRequestOnEmptyLicenseState", logger); - setInitialState(null, licensee); + XPackLicenseState licenseState = new XPackLicenseState(); + setInitialState(null, licenseState); when(discoveryNodes.isLocalNodeElectedMaster()).thenReturn(true); licenseService.start(); @@ -36,13 +34,4 @@ public class LicenseRegistrationTests extends AbstractLicenseServiceTestCase { assertNotNull(licenseMetaData.getLicense()); assertEquals(clock.millis() + LicenseService.TRIAL_LICENSE_DURATION.millis(), licenseMetaData.getLicense().expiryDate()); } - - public void testNotificationOnRegistration() throws Exception { - TestUtils.AssertingLicensee licensee = new TestUtils.AssertingLicensee( - "testNotificationOnRegistration", logger); - setInitialState(TestUtils.generateSignedLicense(TimeValue.timeValueHours(2)), licensee); - licenseService.start(); - assertThat(licensee.statuses.size(), equalTo(1)); - assertTrue(licensee.statuses.get(0).isActive()); - } } \ No newline at end of file diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseScheduleTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseScheduleTests.java index 06b2e41bbee..37113016360 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseScheduleTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseScheduleTests.java @@ -7,7 +7,6 @@ package org.elasticsearch.license.plugin.core; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.TestUtils; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.scheduler.SchedulerEngine; import org.junit.Before; diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicensesServiceClusterTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseServiceClusterTests.java similarity index 86% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicensesServiceClusterTests.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseServiceClusterTests.java index 62edd02f934..ffd83337399 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/LicensesServiceClusterTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicenseServiceClusterTests.java @@ -3,14 +3,15 @@ * 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; +package org.elasticsearch.license.plugin.core; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.env.Environment; import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.core.LicenseService; +import org.elasticsearch.license.plugin.AbstractLicensesIntegrationTestCase; +import org.elasticsearch.license.plugin.LicensingClient; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.xpack.MockNetty3Plugin; @@ -22,13 +23,13 @@ import java.nio.file.Path; import java.util.Arrays; import java.util.Collection; -import static org.elasticsearch.license.plugin.TestUtils.generateSignedLicense; +import static org.elasticsearch.license.plugin.core.TestUtils.generateSignedLicense; import static org.elasticsearch.test.ESIntegTestCase.Scope.TEST; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.nullValue; @ClusterScope(scope = TEST, numDataNodes = 0, numClientNodes = 0, maxNumDataNodes = 0, transportClientRatio = 0) -public class LicensesServiceClusterTests extends AbstractLicensesIntegrationTestCase { +public class LicenseServiceClusterTests extends AbstractLicensesIntegrationTestCase { @Override protected Settings transportClientSettings() { @@ -123,40 +124,40 @@ public class LicensesServiceClusterTests extends AbstractLicensesIntegrationTest wipeAllLicenses(); internalCluster().startNode(); ensureGreen(); - assertLicenseState(true); + assertLicenseActive(true); logger.info("--> restart node"); internalCluster().fullRestart(); ensureYellow(); logger.info("--> await node for enabled"); - assertLicenseState(true); + assertLicenseActive(true); } public void testClusterRestartWhileGrace() throws Exception { wipeAllLicenses(); internalCluster().startNode(); - assertLicenseState(true); + assertLicenseActive(true); putLicense(TestUtils.generateSignedLicense(TimeValue.timeValueMillis(0))); ensureGreen(); - assertLicenseState(true); + assertLicenseActive(true); logger.info("--> restart node"); internalCluster().fullRestart(); ensureYellow(); logger.info("--> await node for grace_period"); - assertLicenseState(true); + assertLicenseActive(true); } public void testClusterRestartWhileExpired() throws Exception { wipeAllLicenses(); internalCluster().startNode(); ensureGreen(); - assertLicenseState(true); + assertLicenseActive(true); putLicense(TestUtils.generateExpiredLicense(System.currentTimeMillis() - LicenseService.GRACE_PERIOD_DURATION.getMillis())); - assertLicenseState(false); + assertLicenseActive(false); logger.info("--> restart node"); internalCluster().fullRestart(); ensureYellow(); logger.info("--> await node for disabled"); - assertLicenseState(false); + assertLicenseActive(false); } public void testClusterNotRecovered() throws Exception { @@ -164,13 +165,13 @@ public class LicensesServiceClusterTests extends AbstractLicensesIntegrationTest internalCluster().startNode(nodeSettingsBuilder(0).put("discovery.zen.minimum_master_nodes", 2).put("node.master", true)); logger.info("--> start second master out of two [recovered state]"); internalCluster().startNode(nodeSettingsBuilder(1).put("discovery.zen.minimum_master_nodes", 2).put("node.master", true)); - assertLicenseState(true); + assertLicenseActive(true); } - private void assertLicenseState(boolean active) throws InterruptedException { + private void assertLicenseActive(boolean active) throws InterruptedException { boolean success = awaitBusy(() -> { - for (LicenseService service : internalCluster().getDataNodeInstances(LicenseService.class)) { - if (service.licenseeStatus(service.getLicense()).isActive() == active) { + for (XPackLicenseState licenseState : internalCluster().getDataNodeInstances(XPackLicenseState.class)) { + if (licenseState.isActive() == active) { return true; } } @@ -181,8 +182,8 @@ public class LicensesServiceClusterTests extends AbstractLicensesIntegrationTest private void assertOperationMode(License.OperationMode operationMode) throws InterruptedException { boolean success = awaitBusy(() -> { - for (LicenseService service : internalCluster().getDataNodeInstances(LicenseService.class)) { - if (service.licenseeStatus(service.getLicense()).getMode() == operationMode) { + for (XPackLicenseState licenseState : internalCluster().getDataNodeInstances(XPackLicenseState.class)) { + if (licenseState.getOperationMode() == operationMode) { return true; } } diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesAcknowledgementTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesAcknowledgementTests.java index 40cbd87d393..050c0a37eb4 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesAcknowledgementTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesAcknowledgementTests.java @@ -5,19 +5,14 @@ */ package org.elasticsearch.license.plugin.core; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - import org.elasticsearch.action.ActionListener; import org.elasticsearch.cluster.ClusterStateUpdateTask; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.TestUtils; import org.elasticsearch.license.plugin.action.put.PutLicenseRequest; import org.elasticsearch.license.plugin.action.put.PutLicenseResponse; -import static org.elasticsearch.license.plugin.TestUtils.generateSignedLicense; +import static org.elasticsearch.license.plugin.core.TestUtils.generateSignedLicense; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; import static org.mockito.Matchers.any; @@ -28,93 +23,40 @@ public class LicensesAcknowledgementTests extends AbstractLicenseServiceTestCase public void testAcknowledgment() throws Exception { - String id = "testAcknowledgment"; - String[] acknowledgeMessages = new String[] {"message"}; - TestUtils.AssertingLicensee licensee = new TestUtils.AssertingLicensee(id, logger); - setInitialState(TestUtils.generateSignedLicense("trial", TimeValue.timeValueHours(2)), licensee); - licenseService.start(); - licensee.setAcknowledgementMessages(acknowledgeMessages); - // try installing a signed license - License signedLicense = generateSignedLicense(TimeValue.timeValueHours(10)); - PutLicenseRequest putLicenseRequest = new PutLicenseRequest().license(signedLicense); - // ensure acknowledgement message was part of the response - licenseService.registerLicense(putLicenseRequest, new AssertingLicensesUpdateResponse(false, LicensesStatus.VALID, - Collections.singletonMap(id, acknowledgeMessages))); - assertThat(licensee.acknowledgementRequested.size(), equalTo(1)); - assertThat(licensee.acknowledgementRequested.get(0).v2(), equalTo(signedLicense.operationMode())); - assertThat(licenseService.getLicense(), not(signedLicense)); - - // try installing a signed license with acknowledgement - putLicenseRequest = new PutLicenseRequest().license(signedLicense).acknowledge(true); - // ensure license was installed and no acknowledgment message was returned - licensee.setAcknowledgementMessages(new String[0]); - licenseService.registerLicense(putLicenseRequest, new AssertingLicensesUpdateResponse(true, LicensesStatus.VALID, - Collections.<String, String[]>emptyMap())); - verify(clusterService, times(1)).submitStateUpdateTask(any(String.class), any(ClusterStateUpdateTask.class)); - assertThat(licensee.acknowledgementRequested.size(), equalTo(1)); - assertThat(licensee.acknowledgementRequested.get(0).v2(), equalTo(signedLicense.operationMode())); - } - - public void testAcknowledgementMultipleLicensee() throws Exception { - String id1 = "testAcknowledgementMultipleLicensee_1"; - String[] acknowledgeMessages1 = new String[] {"testAcknowledgementMultipleLicensee_1"}; - String id2 = "testAcknowledgementMultipleLicensee_2"; - String[] acknowledgeMessages2 = new String[] {"testAcknowledgementMultipleLicensee_2"}; - TestUtils.AssertingLicensee licensee1 = new TestUtils.AssertingLicensee(id1, logger); - licensee1.setAcknowledgementMessages(acknowledgeMessages1); - TestUtils.AssertingLicensee licensee2 = new TestUtils.AssertingLicensee(id2, logger); - licensee2.setAcknowledgementMessages(acknowledgeMessages2); - setInitialState(TestUtils.generateSignedLicense("trial", TimeValue.timeValueHours(2)), licensee1, licensee2); + XPackLicenseState licenseState = new XPackLicenseState(); + setInitialState(TestUtils.generateSignedLicense("trial", TimeValue.timeValueHours(2)), licenseState); licenseService.start(); // try installing a signed license License signedLicense = generateSignedLicense(TimeValue.timeValueHours(10)); PutLicenseRequest putLicenseRequest = new PutLicenseRequest().license(signedLicense); // ensure acknowledgement message was part of the response - final HashMap<String, String[]> expectedMessages = new HashMap<>(); - expectedMessages.put(id1, acknowledgeMessages1); - expectedMessages.put(id2, acknowledgeMessages2); - licenseService.registerLicense(putLicenseRequest, new AssertingLicensesUpdateResponse(false, LicensesStatus.VALID, - expectedMessages)); - verify(clusterService, times(0)).submitStateUpdateTask(any(String.class), any(ClusterStateUpdateTask.class)); - assertThat(licensee2.acknowledgementRequested.size(), equalTo(1)); - assertThat(licensee2.acknowledgementRequested.get(0).v2(), equalTo(signedLicense.operationMode())); - assertThat(licensee1.acknowledgementRequested.size(), equalTo(1)); - assertThat(licensee1.acknowledgementRequested.get(0).v2(), equalTo(signedLicense.operationMode())); + licenseService.registerLicense(putLicenseRequest, new AssertingLicensesUpdateResponse(false, LicensesStatus.VALID, true)); assertThat(licenseService.getLicense(), not(signedLicense)); // try installing a signed license with acknowledgement putLicenseRequest = new PutLicenseRequest().license(signedLicense).acknowledge(true); // ensure license was installed and no acknowledgment message was returned - licensee1.setAcknowledgementMessages(new String[0]); - licensee2.setAcknowledgementMessages(new String[0]); - licenseService.registerLicense(putLicenseRequest, new AssertingLicensesUpdateResponse(true, LicensesStatus.VALID, - Collections.<String, String[]>emptyMap())); - verify(clusterService, times(1)).submitStateUpdateTask(any(String.class), any(ClusterStateUpdateTask.class)); + licenseService.registerLicense(putLicenseRequest, new AssertingLicensesUpdateResponse(true, LicensesStatus.VALID, false)); + verify(clusterService, times(2)).submitStateUpdateTask(any(String.class), any(ClusterStateUpdateTask.class)); } private static class AssertingLicensesUpdateResponse implements ActionListener<PutLicenseResponse> { private final boolean expectedAcknowledgement; private final LicensesStatus expectedStatus; - private final Map<String, String[]> expectedAckMessages; + private final boolean expectAckMessages; public AssertingLicensesUpdateResponse(boolean expectedAcknowledgement, LicensesStatus expectedStatus, - Map<String, String[]> expectedAckMessages) { + boolean expectAckMessages) { this.expectedAcknowledgement = expectedAcknowledgement; this.expectedStatus = expectedStatus; - this.expectedAckMessages = expectedAckMessages; + this.expectAckMessages = expectAckMessages; } @Override public void onResponse(PutLicenseResponse licensesUpdateResponse) { assertThat(licensesUpdateResponse.isAcknowledged(), equalTo(expectedAcknowledgement)); assertThat(licensesUpdateResponse.status(), equalTo(expectedStatus)); - assertThat(licensesUpdateResponse.acknowledgeMessages().size(), equalTo(expectedAckMessages.size())); - for (Map.Entry<String, String[]> expectedEntry : expectedAckMessages.entrySet()) { - Map<String, String[]> actual = licensesUpdateResponse.acknowledgeMessages(); - assertThat(actual.containsKey(expectedEntry.getKey()), equalTo(true)); - String[] actualMessages = actual.get(expectedEntry.getKey()); - assertThat(actualMessages, equalTo(expectedEntry.getValue())); - } + assertEquals(licensesUpdateResponse.acknowledgeMessages().isEmpty(), expectAckMessages == false); } @Override diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesManagerServiceTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesManagerServiceTests.java index a63376a05e8..260135b764a 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesManagerServiceTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesManagerServiceTests.java @@ -16,7 +16,6 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.TestUtils; import org.elasticsearch.license.plugin.action.delete.DeleteLicenseRequest; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.test.ESSingleNodeTestCase; @@ -26,7 +25,7 @@ import org.elasticsearch.xpack.monitoring.Monitoring; import org.elasticsearch.xpack.security.Security; import org.elasticsearch.xpack.watcher.Watcher; -import static org.elasticsearch.license.plugin.TestUtils.generateSignedLicense; +import static org.elasticsearch.license.plugin.core.TestUtils.generateSignedLicense; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesMetaDataSerializationTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesMetaDataSerializationTests.java index 13337e5e29a..4748ab9c065 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesMetaDataSerializationTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesMetaDataSerializationTests.java @@ -22,7 +22,6 @@ import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.license.core.License; import org.elasticsearch.license.plugin.Licensing; -import org.elasticsearch.license.plugin.TestUtils; import org.elasticsearch.test.ESTestCase; import java.util.Base64; diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesNotificationTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesNotificationTests.java deleted file mode 100644 index 6111fe02bde..00000000000 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/LicensesNotificationTests.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.license.plugin.core; - -import java.util.List; - -import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.TestUtils; -import org.elasticsearch.license.plugin.TestUtils.AssertingLicensee; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; - -import static org.hamcrest.Matchers.equalTo; - -public class LicensesNotificationTests extends AbstractLicenseServiceTestCase { - - public void testLicenseNotification() throws Exception { - final License license = TestUtils.generateSignedLicense(TimeValue.timeValueHours(48)); - int nLicensee = randomIntBetween(1, 3); - AssertingLicensee[] assertingLicensees = new AssertingLicensee[nLicensee]; - for (int i = 0; i < assertingLicensees.length; i++) { - assertingLicensees[i] = new AssertingLicensee("testLicenseNotification" + i, logger); - } - setInitialState(license, assertingLicensees); - licenseService.start(); - for (int i = 0; i < assertingLicensees.length; i++) { - assertLicenseStates(assertingLicensees[i], true); - } - clock.fastForward(TimeValue.timeValueMillis(license.expiryDate() - clock.millis())); - final LicensesMetaData licensesMetaData = new LicensesMetaData(license); - licenseService.onUpdate(licensesMetaData); - for (AssertingLicensee assertingLicensee : assertingLicensees) { - assertLicenseStates(assertingLicensee, true); - } - clock.fastForward(TimeValue.timeValueMillis((license.expiryDate() + - LicenseService.GRACE_PERIOD_DURATION.getMillis()) - clock.millis())); - licenseService.onUpdate(licensesMetaData); - for (AssertingLicensee assertingLicensee : assertingLicensees) { - assertLicenseStates(assertingLicensee, true, false); - } - clock.setTime(new DateTime(DateTimeZone.UTC)); - final License newLicense = TestUtils.generateSignedLicense(TimeValue.timeValueHours(2)); - clock.fastForward(TimeValue.timeValueHours(1)); - LicensesMetaData licensesMetaData1 = new LicensesMetaData(newLicense); - licenseService.onUpdate(licensesMetaData1); - for (AssertingLicensee assertingLicensee : assertingLicensees) { - assertLicenseStates(assertingLicensee, true, false, true); - } - } - - private void assertLicenseStates(AssertingLicensee licensee, boolean... states) { - StringBuilder msg = new StringBuilder(); - msg.append("Actual: "); - msg.append(dumpLicensingStates(licensee.statuses)); - msg.append(" Expected: "); - msg.append(dumpLicensingStates(states)); - assertThat(msg.toString(), licensee.statuses.size(), equalTo(states.length)); - for (int i = 0; i < states.length; i++) { - assertThat(msg.toString(), licensee.statuses.get(i).isActive(), equalTo(states[i])); - } - } - - private String dumpLicensingStates(List<Licensee.Status> statuses) { - return dumpLicensingStates(statuses.toArray(new Licensee.Status[statuses.size()])); - } - - private String dumpLicensingStates(Licensee.Status... statuses) { - boolean[] states = new boolean[statuses.length]; - for (int i = 0; i < statuses.length; i++) { - states[i] = statuses[i].isActive(); - } - return dumpLicensingStates(states); - } - - private String dumpLicensingStates(boolean... states) { - StringBuilder sb = new StringBuilder(); - sb.append("["); - for (int i = 0; i < states.length; i++) { - sb.append(states[i]); - if (i != states.length - 1) { - sb.append(", "); - } - } - sb.append("]"); - return sb.toString(); - } -} diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/TestUtils.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/TestUtils.java similarity index 82% rename from elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/TestUtils.java rename to elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/TestUtils.java index 6ae7b4a70e5..2a1f6350adf 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/TestUtils.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/core/TestUtils.java @@ -3,7 +3,7 @@ * 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; +package org.elasticsearch.license.plugin.core; import org.elasticsearch.action.ActionListener; import org.elasticsearch.common.collect.Tuple; @@ -21,12 +21,10 @@ 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.action.put.PutLicenseResponse; -import org.elasticsearch.license.plugin.core.LicenseService; -import org.elasticsearch.license.plugin.core.Licensee; -import org.elasticsearch.license.plugin.core.LicensesStatus; import org.junit.Assert; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.UUID; import java.util.concurrent.Callable; @@ -171,44 +169,14 @@ public class TestUtils { assertThat(status.get(), equalTo(expectedStatus)); } - public static class AssertingLicensee implements Licensee { - public final ESLogger logger; - public final String id; - public final List<Licensee.Status> statuses = new CopyOnWriteArrayList<>(); - public final AtomicInteger expirationMessagesCalled = new AtomicInteger(0); - public final List<Tuple<License.OperationMode, License.OperationMode>> acknowledgementRequested = new CopyOnWriteArrayList<>(); - - private String[] acknowledgmentMessages = new String[0]; - - public AssertingLicensee(String id, ESLogger logger) { - this.logger = logger; - this.id = id; - } - - public void setAcknowledgementMessages(String[] acknowledgementMessages) { - this.acknowledgmentMessages = acknowledgementMessages; - } - @Override - public String id() { - return id; - } + public static class AssertingLicenseState extends XPackLicenseState { + public final List<License.OperationMode> modeUpdates = new ArrayList<>(); + public final List<Boolean> activeUpdates = new ArrayList<>(); @Override - public String[] expirationMessages() { - expirationMessagesCalled.incrementAndGet(); - return new String[0]; - } - - @Override - public String[] acknowledgmentMessages(License.OperationMode currentMode, License.OperationMode newMode) { - acknowledgementRequested.add(new Tuple<>(currentMode, newMode)); - return acknowledgmentMessages; - } - - @Override - public void onChange(Status status) { - assertNotNull(status); - statuses.add(status); + void update(License.OperationMode mode, boolean active) { + modeUpdates.add(mode); + activeUpdates.add(active); } } } diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringFeatureSet.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringFeatureSet.java index cef76ffd35a..e70dcd67713 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringFeatureSet.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringFeatureSet.java @@ -12,6 +12,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.XPackFeatureSet; import org.elasticsearch.xpack.monitoring.agent.exporter.Exporter; import org.elasticsearch.xpack.monitoring.agent.exporter.Exporters; @@ -26,14 +27,14 @@ import java.util.Map; public class MonitoringFeatureSet implements XPackFeatureSet { private final boolean enabled; - private final MonitoringLicensee licensee; + private final XPackLicenseState licenseState; private final Exporters exporters; @Inject - public MonitoringFeatureSet(Settings settings, @Nullable MonitoringLicensee licensee, @Nullable Exporters exporters, + public MonitoringFeatureSet(Settings settings, @Nullable XPackLicenseState licenseState, @Nullable Exporters exporters, NamedWriteableRegistry namedWriteableRegistry) { this.enabled = MonitoringSettings.ENABLED.get(settings); - this.licensee = licensee; + this.licenseState = licenseState; this.exporters = exporters; namedWriteableRegistry.register(Usage.class, Usage.writeableName(Monitoring.NAME), Usage::new); } @@ -50,7 +51,7 @@ public class MonitoringFeatureSet implements XPackFeatureSet { @Override public boolean available() { - return licensee != null && licensee.isAvailable(); + return licenseState != null && licenseState.isMonitoringAllowed(); } @Override diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringLicensee.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringLicensee.java deleted file mode 100644 index 5f0dd674eb4..00000000000 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringLicensee.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.monitoring; - -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.logging.LoggerMessageFormat; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.core.License.OperationMode; -import org.elasticsearch.license.plugin.core.AbstractLicenseeComponent; - -/** - * {@code MonitoringLicensee} determines whether certain features of Monitoring are enabled or disabled. - * <p> - * Once the license expires, the agent will stop: - * <ul> - * <li>Collecting and publishing new metrics.</li> - * <li>Cleaning up (deleting) older indices.</li> - * </ul> - */ -public class MonitoringLicensee extends AbstractLicenseeComponent { - - public MonitoringLicensee(Settings settings) { - super(settings, Monitoring.NAME); - } - - /** - * {@inheritDoc} - * - * @see #collectionEnabled() - * @see #cleaningEnabled() - */ - @Override - public String[] expirationMessages() { - return new String[] { - "The agent will stop collecting cluster and indices metrics", - "The agent will stop automatically cleaning indices older than [xpack.monitoring.history.duration]", - }; - } - - @Override - public String[] acknowledgmentMessages(OperationMode currentMode, OperationMode newMode) { - switch (newMode) { - case BASIC: - switch (currentMode) { - case TRIAL: - case STANDARD: - case GOLD: - case PLATINUM: - return new String[] { - LoggerMessageFormat.format( - "Multi-cluster support is disabled for clusters with [{}] license. If you are\n" + - "running multiple clusters, users won't be able to access the clusters with\n" + - "[{}] licenses from within a single X-Pack Kibana instance. You will have to deploy a\n" + - "separate and dedicated X-pack Kibana instance for each [{}] cluster you wish to monitor.", - newMode, newMode, newMode), - LoggerMessageFormat.format( - "Automatic index cleanup is locked to {} days for clusters with [{}] license.", - MonitoringSettings.HISTORY_DURATION.getDefault(Settings.EMPTY).days(), newMode) - }; - } - break; - } - return Strings.EMPTY_ARRAY; - } - - /** - * Monitoring is always available as long as there is a valid license - * - * @return true - */ - public boolean isAvailable() { - return status.isActive(); - } - - /** - * Determine if the index cleaning service is enabled. - * <p> - * Collection is only disabled <em>automatically</em> when the license expires. All modes are valid for collection. - * <p> - * Collection <em>can</em> be disabled explicitly by the user, although that's generally a temporary solution to unrelated issues - * (e.g., initial setup when the monitoring cluster doesn't actually exist). - * - * @return {@code true} as long as the license is valid. Otherwise {@code false}. - */ - public boolean collectionEnabled() { - return status.isActive(); - } - - /** - * Determine if the index cleaning service is enabled. - * <p> - * Index cleaning is only disabled when the license expires. All modes are valid for cleaning. - * - * @return {@code true} as long as the license is valid. Otherwise {@code false}. - */ - public boolean cleaningEnabled() { - return status.isActive(); - } - - /** - * Determine if the current license allows the retention of indices to be modified. - * <p> - * Only users with a non-{@link OperationMode#BASIC} license can update the retention period. - * <p> - * Note: This does not consider the <em>state</em> of the license so that any change is remembered for when they fix their license. - * - * @return {@code true} if the user is allowed to modify the retention. Otherwise {@code false}. - */ - public boolean allowUpdateRetention() { - final OperationMode mode = status.getMode(); - return mode != OperationMode.BASIC && mode != OperationMode.MISSING; - } -} diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringModule.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringModule.java index 2f7162bd808..6c7908b82c3 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringModule.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringModule.java @@ -29,8 +29,6 @@ public class MonitoringModule extends AbstractModule { bind(MonitoringSettings.class).asEagerSingleton(); bind(AgentService.class).asEagerSingleton(); bind(CleanerService.class).asEagerSingleton(); - } else if (transportClientMode) { - bind(MonitoringLicensee.class).toProvider(Providers.of(null)); } } } diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/AbstractCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/AbstractCollector.java index 2d8ee861298..fccfc22e57f 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/AbstractCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/AbstractCollector.java @@ -12,8 +12,8 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoredSystem; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; @@ -25,16 +25,16 @@ public abstract class AbstractCollector extends AbstractLifecycleComponent imple protected final ClusterService clusterService; protected final MonitoringSettings monitoringSettings; - protected final MonitoringLicensee licensee; + protected final XPackLicenseState licenseState; @Inject public AbstractCollector(Settings settings, String name, ClusterService clusterService, - MonitoringSettings monitoringSettings, MonitoringLicensee licensee) { + MonitoringSettings monitoringSettings, XPackLicenseState licenseState) { super(settings); this.name = name; this.clusterService = clusterService; this.monitoringSettings = monitoringSettings; - this.licensee = licensee; + this.licenseState = licenseState; } @Override @@ -61,7 +61,7 @@ public abstract class AbstractCollector extends AbstractLifecycleComponent imple * Indicates if the current collector is allowed to collect data */ protected boolean shouldCollect() { - if (!licensee.collectionEnabled()) { + if (licenseState.isMonitoringAllowed() == false) { logger.trace("collector [{}] can not collect data due to invalid license", name()); return false; } diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollector.java index 8c3db642714..938a728c6ca 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollector.java @@ -13,7 +13,7 @@ import org.elasticsearch.cluster.node.DiscoveryNodes; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; @@ -38,8 +38,8 @@ public class ClusterStateCollector extends AbstractCollector { @Inject public ClusterStateCollector(Settings settings, ClusterService clusterService, - MonitoringSettings monitoringSettings, MonitoringLicensee licensee, InternalClient client) { - super(settings, NAME, clusterService, monitoringSettings, licensee); + MonitoringSettings monitoringSettings, XPackLicenseState licenseState, InternalClient client) { + super(settings, NAME, clusterService, monitoringSettings, licenseState); this.client = client; } diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollector.java index b9819159c62..4eee2aa63a0 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollector.java @@ -13,9 +13,9 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.plugin.core.LicenseUtils; import org.elasticsearch.license.plugin.core.LicenseService; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; +import org.elasticsearch.license.plugin.core.LicenseUtils; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; @@ -45,9 +45,9 @@ public class ClusterStatsCollector extends AbstractCollector { @Inject public ClusterStatsCollector(Settings settings, ClusterService clusterService, - MonitoringSettings monitoringSettings, MonitoringLicensee licensee, InternalClient client, + MonitoringSettings monitoringSettings, XPackLicenseState licenseState, InternalClient client, LicenseService licenseService) { - super(settings, NAME, clusterService, monitoringSettings, licensee); + super(settings, NAME, clusterService, monitoringSettings, licenseState); this.client = client; this.licenseService = licenseService; } diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollector.java index fcf9fd65e66..14b866b17b0 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollector.java @@ -13,7 +13,7 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexNotFoundException; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; @@ -40,8 +40,8 @@ public class IndexRecoveryCollector extends AbstractCollector { @Inject public IndexRecoveryCollector(Settings settings, ClusterService clusterService, - MonitoringSettings monitoringSettings, MonitoringLicensee licensee, InternalClient client) { - super(settings, NAME, clusterService, monitoringSettings, licensee); + MonitoringSettings monitoringSettings, XPackLicenseState licenseState, InternalClient client) { + super(settings, NAME, clusterService, monitoringSettings, licenseState); this.client = client; } diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollector.java index 0e76ed66a04..b2c2821ff59 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollector.java @@ -15,7 +15,7 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexNotFoundException; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; @@ -42,8 +42,8 @@ public class IndexStatsCollector extends AbstractCollector { @Inject public IndexStatsCollector(Settings settings, ClusterService clusterService, - MonitoringSettings monitoringSettings, MonitoringLicensee licensee, InternalClient client) { - super(settings, NAME, clusterService, monitoringSettings, licensee); + MonitoringSettings monitoringSettings, XPackLicenseState licenseState, InternalClient client) { + super(settings, NAME, clusterService, monitoringSettings, licenseState); this.client = client; } diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollector.java index 2f6c538ea20..446517166ef 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollector.java @@ -13,7 +13,7 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexNotFoundException; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; @@ -37,8 +37,8 @@ public class IndicesStatsCollector extends AbstractCollector { @Inject public IndicesStatsCollector(Settings settings, ClusterService clusterService, - MonitoringSettings monitoringSettings, MonitoringLicensee licensee, InternalClient client) { - super(settings, NAME, clusterService, monitoringSettings, licensee); + MonitoringSettings monitoringSettings, XPackLicenseState licenseState, InternalClient client) { + super(settings, NAME, clusterService, monitoringSettings, licenseState); this.client = client; } diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollector.java index cbbeefb0836..5b855284c41 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollector.java @@ -17,7 +17,7 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.NodeEnvironment; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; @@ -43,9 +43,9 @@ public class NodeStatsCollector extends AbstractCollector { @Inject public NodeStatsCollector(Settings settings, ClusterService clusterService, MonitoringSettings monitoringSettings, - MonitoringLicensee licensee, InternalClient client, + XPackLicenseState licenseState, InternalClient client, NodeEnvironment nodeEnvironment, DiskThresholdDecider diskThresholdDecider) { - super(settings, NAME, clusterService, monitoringSettings, licensee); + super(settings, NAME, clusterService, monitoringSettings, licenseState); this.client = client; this.nodeEnvironment = nodeEnvironment; this.diskThresholdDecider = diskThresholdDecider; diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollector.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollector.java index 58ffd7097ac..c712d029267 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollector.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollector.java @@ -13,7 +13,7 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; @@ -36,8 +36,8 @@ public class ShardsCollector extends AbstractCollector { @Inject public ShardsCollector(Settings settings, ClusterService clusterService, - MonitoringSettings monitoringSettings, MonitoringLicensee licensee) { - super(settings, NAME, clusterService, monitoringSettings, licensee); + MonitoringSettings monitoringSettings, XPackLicenseState licenseState) { + super(settings, NAME, clusterService, monitoringSettings, licenseState); } @Override diff --git a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/cleaner/CleanerService.java b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/cleaner/CleanerService.java index 524f494900f..c951efbc474 100644 --- a/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/cleaner/CleanerService.java +++ b/elasticsearch/x-pack/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/cleaner/CleanerService.java @@ -13,8 +13,8 @@ import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.AbstractLifecycleRunnable; import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; import org.elasticsearch.common.util.concurrent.FutureUtils; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.joda.time.DateTime; import org.joda.time.chrono.ISOChronology; @@ -28,7 +28,7 @@ import java.util.concurrent.ScheduledFuture; */ public class CleanerService extends AbstractLifecycleComponent { - private final MonitoringLicensee licensee; + private final XPackLicenseState licenseState; private final ThreadPool threadPool; private final ExecutionScheduler executionScheduler; private final List<Listener> listeners = new CopyOnWriteArrayList<>(); @@ -36,10 +36,10 @@ public class CleanerService extends AbstractLifecycleComponent { private volatile TimeValue globalRetention; - CleanerService(Settings settings, ClusterSettings clusterSettings, MonitoringLicensee licensee, ThreadPool threadPool, + CleanerService(Settings settings, ClusterSettings clusterSettings, XPackLicenseState licenseState, ThreadPool threadPool, ExecutionScheduler executionScheduler) { super(settings); - this.licensee = licensee; + this.licenseState = licenseState; this.threadPool = threadPool; this.executionScheduler = executionScheduler; this.globalRetention = MonitoringSettings.HISTORY_DURATION.get(settings); @@ -50,8 +50,8 @@ public class CleanerService extends AbstractLifecycleComponent { } @Inject - public CleanerService(Settings settings, ClusterSettings clusterSettings, ThreadPool threadPool, MonitoringLicensee licensee) { - this(settings, clusterSettings, licensee,threadPool, new DefaultExecutionScheduler()); + public CleanerService(Settings settings, ClusterSettings clusterSettings, ThreadPool threadPool, XPackLicenseState licenseState) { + this(settings, clusterSettings, licenseState, threadPool, new DefaultExecutionScheduler()); } @Override @@ -85,11 +85,11 @@ public class CleanerService extends AbstractLifecycleComponent { * This will ignore the global retention if the license does not allow retention updates. * * @return Never {@code null} - * @see MonitoringLicensee#allowUpdateRetention() + * @see XPackLicenseState#isUpdateRetentionAllowed() */ public TimeValue getRetention() { // we only care about their value if they are allowed to set it - if (licensee.allowUpdateRetention() && globalRetention != null) { + if (licenseState.isUpdateRetentionAllowed() && globalRetention != null) { return globalRetention; } else { @@ -107,7 +107,7 @@ public class CleanerService extends AbstractLifecycleComponent { */ public void setGlobalRetention(TimeValue globalRetention) { // notify the user that their setting will be ignored until they get the right license - if (licensee.allowUpdateRetention() == false) { + if (licenseState.isUpdateRetentionAllowed() == false) { logger.warn("[{}] setting will be ignored until an appropriate license is applied", MonitoringSettings.HISTORY_DURATION.getKey()); } @@ -165,7 +165,7 @@ public class CleanerService extends AbstractLifecycleComponent { @Override protected void doRunInLifecycle() throws Exception { - if (licensee.cleaningEnabled() == false) { + if (licenseState.isMonitoringAllowed() == false) { logger.debug("cleaning service is disabled due to invalid license"); return; } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringFeatureSetTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringFeatureSetTests.java index 457ddd951a5..fa3a417a852 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringFeatureSetTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringFeatureSetTests.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.monitoring; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.XPackFeatureSet; import org.elasticsearch.xpack.monitoring.agent.exporter.Exporter; @@ -33,26 +34,26 @@ import static org.mockito.Mockito.when; */ public class MonitoringFeatureSetTests extends ESTestCase { - private MonitoringLicensee licensee; + private XPackLicenseState licenseState; private NamedWriteableRegistry namedWriteableRegistry; private Exporters exporters; @Before public void init() throws Exception { - licensee = mock(MonitoringLicensee.class); + licenseState = mock(XPackLicenseState.class); exporters = mock(Exporters.class); namedWriteableRegistry = mock(NamedWriteableRegistry.class); } public void testWritableRegistration() throws Exception { - new MonitoringFeatureSet(Settings.EMPTY, licensee, exporters, namedWriteableRegistry); + new MonitoringFeatureSet(Settings.EMPTY, licenseState, exporters, namedWriteableRegistry); verify(namedWriteableRegistry).register(eq(MonitoringFeatureSet.Usage.class), eq("xpack.usage.monitoring"), anyObject()); } public void testAvailable() throws Exception { - MonitoringFeatureSet featureSet = new MonitoringFeatureSet(Settings.EMPTY, licensee, exporters, namedWriteableRegistry); + MonitoringFeatureSet featureSet = new MonitoringFeatureSet(Settings.EMPTY, licenseState, exporters, namedWriteableRegistry); boolean available = randomBoolean(); - when(licensee.isAvailable()).thenReturn(available); + when(licenseState.isMonitoringAllowed()).thenReturn(available); assertThat(featureSet.available(), is(available)); } @@ -60,12 +61,12 @@ public class MonitoringFeatureSetTests extends ESTestCase { boolean enabled = randomBoolean(); Settings.Builder settings = Settings.builder(); settings.put("xpack.monitoring.enabled", enabled); - MonitoringFeatureSet featureSet = new MonitoringFeatureSet(settings.build(), licensee, exporters, namedWriteableRegistry); + MonitoringFeatureSet featureSet = new MonitoringFeatureSet(settings.build(), licenseState, exporters, namedWriteableRegistry); assertThat(featureSet.enabled(), is(enabled)); } public void testEnabledDefault() throws Exception { - MonitoringFeatureSet featureSet = new MonitoringFeatureSet(Settings.EMPTY, licensee, exporters, namedWriteableRegistry); + MonitoringFeatureSet featureSet = new MonitoringFeatureSet(Settings.EMPTY, licenseState, exporters, namedWriteableRegistry); assertThat(featureSet.enabled(), is(true)); } @@ -102,7 +103,7 @@ public class MonitoringFeatureSetTests extends ESTestCase { } when(exporters.iterator()).thenReturn(exporterList.iterator()); - MonitoringFeatureSet featureSet = new MonitoringFeatureSet(Settings.EMPTY, licensee, exporters, namedWriteableRegistry); + MonitoringFeatureSet featureSet = new MonitoringFeatureSet(Settings.EMPTY, licenseState, exporters, namedWriteableRegistry); XPackFeatureSet.Usage usage = featureSet.usage(); assertThat(usage.name(), is(featureSet.name())); assertThat(usage.enabled(), is(featureSet.enabled())); diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/AbstractCollectorTestCase.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/AbstractCollectorTestCase.java index b5a72d9cf03..aa4cdddba20 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/AbstractCollectorTestCase.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/AbstractCollectorTestCase.java @@ -5,55 +5,20 @@ */ package org.elasticsearch.xpack.monitoring.agent.collector; -import java.io.IOException; -import java.util.Arrays; import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.concurrent.TimeUnit; -import com.carrotsearch.randomizedtesting.RandomizedTest; -import com.carrotsearch.randomizedtesting.SysGlobals; -import org.elasticsearch.action.ActionRequest; -import org.elasticsearch.action.ActionResponse; import org.elasticsearch.cluster.block.ClusterBlocks; -import org.elasticsearch.cluster.service.ClusterService; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.env.Environment; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.Licensing; -import org.elasticsearch.license.plugin.core.LicenseService; -import org.elasticsearch.license.plugin.core.Licensee; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.rest.RestHandler; import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; -import org.elasticsearch.watcher.ResourceWatcherService; -import org.elasticsearch.xpack.XPackPlugin; -import org.elasticsearch.xpack.graph.GraphLicensee; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.test.MonitoringIntegTestCase; import org.elasticsearch.xpack.security.InternalClient; -import org.elasticsearch.xpack.security.SecurityLicenseState; -import org.elasticsearch.xpack.support.clock.Clock; -import org.elasticsearch.xpack.watcher.WatcherLicensee; -import org.junit.Before; - -import static java.util.Collections.emptyList; -import static org.elasticsearch.common.unit.TimeValue.timeValueMinutes; @ClusterScope(scope = ESIntegTestCase.Scope.SUITE, randomDynamicTemplates = false, transportClientRatio = 0.0) public abstract class AbstractCollectorTestCase extends MonitoringIntegTestCase { - @Override - protected Collection<Class<? extends Plugin>> nodePlugins() { - return Arrays.asList(InternalXPackPlugin.class); - } - @Override protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() @@ -62,11 +27,6 @@ public abstract class AbstractCollectorTestCase extends MonitoringIntegTestCase .build(); } - @Before - public void ensureLicenseIsEnabled() { - enableLicense(); - } - public InternalClient securedClient() { return internalCluster().getInstance(InternalClient.class); } @@ -82,83 +42,6 @@ public abstract class AbstractCollectorTestCase extends MonitoringIntegTestCase assertNotNull(results); } - protected void assertCannotCollect(AbstractCollector collector) { - assertNotNull(collector); - assertFalse("collector [" + collector.name() + "] should not be able to collect data", collector.shouldCollect()); - Collection results = collector.collect(); - assertTrue(results == null || results.isEmpty()); - } - - private static License createTestingLicense(long issueDate, long expiryDate) { - return License.builder() - .expiryDate(expiryDate) - .issueDate(issueDate) - .issuedTo("AbstractCollectorTestCase") - .issuer("test") - .maxNodes(Integer.MAX_VALUE) - .signature("_signature") - .type("trial") - .uid(String.valueOf(RandomizedTest.systemPropertyAsInt(SysGlobals.CHILDVM_SYSPROP_JVM_ID, 0)) + - System.identityHashCode(AbstractCollectorTestCase.class)) - .build(); - } - - protected static void enableLicense() { - long issueDate = System.currentTimeMillis(); - long expiryDate = issueDate + randomDaysInMillis(); - - final License license = createTestingLicense(issueDate, expiryDate); - for (LicenseServiceForCollectors service : internalCluster().getInstances(LicenseServiceForCollectors.class)) { - service.onChange(license.operationMode(), true); - } - for (LicenseServiceForCollectors service : internalCluster().getInstances(LicenseServiceForCollectors.class)) { - service.update(license); - } - } - - protected static void beginGracefulPeriod() { - long expiryDate = System.currentTimeMillis() + timeValueMinutes(10).millis(); - long issueDate = expiryDate - randomDaysInMillis(); - - final License license = createTestingLicense(issueDate, expiryDate); - for (LicenseServiceForCollectors service : internalCluster().getInstances(LicenseServiceForCollectors.class)) { - service.onChange(license.operationMode(), true); - } - for (LicenseServiceForCollectors service : internalCluster().getInstances(LicenseServiceForCollectors.class)) { - service.update(license); - } - } - - protected static void endGracefulPeriod() { - long expiryDate = System.currentTimeMillis() - MonitoringSettings.MAX_LICENSE_GRACE_PERIOD.millis() - timeValueMinutes(10).millis(); - long issueDate = expiryDate - randomDaysInMillis(); - - final License license = createTestingLicense(issueDate, expiryDate); - for (LicenseServiceForCollectors service : internalCluster().getInstances(LicenseServiceForCollectors.class)) { - service.onChange(license.operationMode(), false); - } - for (LicenseServiceForCollectors service : internalCluster().getInstances(LicenseServiceForCollectors.class)) { - service.update(license); - } - } - - protected static void disableLicense() { - long expiryDate = System.currentTimeMillis() - MonitoringSettings.MAX_LICENSE_GRACE_PERIOD.millis() - randomDaysInMillis(); - long issueDate = expiryDate - randomDaysInMillis(); - - final License license = createTestingLicense(issueDate, expiryDate); - for (LicenseServiceForCollectors service : internalCluster().getInstances(LicenseServiceForCollectors.class)) { - service.onChange(license.operationMode(), false); - } - for (LicenseServiceForCollectors service : internalCluster().getInstances(LicenseServiceForCollectors.class)) { - service.update(license); - } - } - - private static long randomDaysInMillis() { - return TimeValue.timeValueHours(randomIntBetween(1, 30) * 24).millis(); - } - public void waitForNoBlocksOnNodes() throws Exception { assertBusy(new Runnable() { @Override @@ -182,85 +65,4 @@ public abstract class AbstractCollectorTestCase extends MonitoringIntegTestCase assertTrue(clusterBlocks.indices().values().isEmpty()); }, 30L, TimeUnit.SECONDS); } - - public static class InternalLicensing extends Licensing { - - public InternalLicensing() { - super(Settings.EMPTY); - } - - @Override - public Collection<Module> nodeModules() { - return Collections.singletonList(b -> b.bind(LicenseService.class).to(LicenseServiceForCollectors.class)); - } - - @Override - public Collection<Object> createComponents(ClusterService clusterService, Clock clock, Environment environment, - ResourceWatcherService resourceWatcherService, - SecurityLicenseState securityLicenseState) { - WatcherLicensee watcherLicensee = new WatcherLicensee(settings); - MonitoringLicensee monitoringLicensee = new MonitoringLicensee(settings); - GraphLicensee graphLicensee = new GraphLicensee(settings); - LicenseService licenseService = new LicenseServiceForCollectors(settings, environment, - resourceWatcherService, Arrays.asList(watcherLicensee, monitoringLicensee, graphLicensee)); - return Arrays.asList(licenseService, watcherLicensee, monitoringLicensee, graphLicensee); - } - - @Override - public List<ActionHandler<? extends ActionRequest<?>, ? extends ActionResponse>> getActions() { - return emptyList(); - } - - @Override - public List<Class<? extends RestHandler>> getRestHandlers() { - return emptyList(); - } - } - - public static class InternalXPackPlugin extends XPackPlugin { - - public InternalXPackPlugin(Settings settings) throws IOException { - super(settings); - licensing = new InternalLicensing(); - } - } - - public static class LicenseServiceForCollectors extends LicenseService { - - private final List<Licensee> licensees; - private volatile License license; - - @Inject - public LicenseServiceForCollectors(Settings settings, Environment env, - ResourceWatcherService resourceWatcherService, List<Licensee> licensees) { - super(settings, null, null, env, resourceWatcherService, licensees); - this.licensees = licensees; - } - - public void onChange(License.OperationMode operationMode, boolean active) { - for (Licensee licensee : licensees) { - licensee.onChange(new Licensee.Status(operationMode, active)); - } - } - - @Override - public Licensee.Status licenseeStatus(License license) { - return null; - } - - @Override - public License getLicense() { - return license; - } - - public synchronized void update(License license) { - this.license = license; - } - - @Override - protected void doStart() {} - - @Override - protected void doStop() {} - } } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollectorTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollectorTests.java index f7e92724ee5..0823b3ba3c3 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollectorTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStateCollectorTests.java @@ -10,8 +10,8 @@ import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoredSystem; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollectorTestCase; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; @@ -106,44 +106,6 @@ public class ClusterStateCollectorTests extends AbstractCollectorTestCase { } } - public void testClusterStateCollectorWithLicensing() { - try { - String[] nodes = internalCluster().getNodeNames(); - for (String node : nodes) { - logger.debug("--> creating a new instance of the collector"); - ClusterStateCollector collector = newClusterStateCollector(node); - assertNotNull(collector); - - logger.debug("--> enabling license and checks that the collector can collect data if node is master"); - enableLicense(); - if (node.equals(internalCluster().getMasterName())) { - assertCanCollect(collector); - } else { - assertCannotCollect(collector); - } - - logger.debug("--> starting graceful period and checks that the collector can still collect data if node is master"); - beginGracefulPeriod(); - if (node.equals(internalCluster().getMasterName())) { - assertCanCollect(collector); - } else { - assertCannotCollect(collector); - } - - logger.debug("--> ending graceful period and checks that the collector cannot collect data"); - endGracefulPeriod(); - assertCannotCollect(collector); - - logger.debug("--> disabling license and checks that the collector cannot collect data"); - disableLicense(); - assertCannotCollect(collector); - } - } finally { - // Ensure license is enabled before finishing the test - enableLicense(); - } - } - private ClusterStateCollector newClusterStateCollector() { // This collector runs on master node only return newClusterStateCollector(internalCluster().getMasterName()); @@ -154,7 +116,7 @@ public class ClusterStateCollectorTests extends AbstractCollectorTestCase { return new ClusterStateCollector(internalCluster().getInstance(Settings.class, nodeId), internalCluster().getInstance(ClusterService.class, nodeId), internalCluster().getInstance(MonitoringSettings.class, nodeId), - internalCluster().getInstance(MonitoringLicensee.class, nodeId), + internalCluster().getInstance(XPackLicenseState.class, nodeId), securedClient(nodeId)); } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollectorTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollectorTests.java index 52dacb48da7..370fa9f642a 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollectorTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/cluster/ClusterStatsCollectorTests.java @@ -12,8 +12,8 @@ import org.elasticsearch.Version; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.license.plugin.core.LicenseService; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoredSystem; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollectorTestCase; @@ -75,52 +75,6 @@ public class ClusterStatsCollectorTests extends AbstractCollectorTestCase { equalTo(internalCluster().getNodeNames().length)); } - public void testClusterStatsCollectorWithLicensing() { - try { - String[] nodes = internalCluster().getNodeNames(); - for (String node : nodes) { - logger.debug("--> creating a new instance of the collector"); - ClusterStatsCollector collector = newClusterStatsCollector(node); - assertNotNull(collector); - - logger.debug("--> enabling license and checks that the collector can collect data if node is master"); - enableLicense(); - if (node.equals(internalCluster().getMasterName())) { - assertCanCollect(collector, ClusterInfoMonitoringDoc.class, ClusterStatsMonitoringDoc.class); - } else { - assertCannotCollect(collector); - } - - logger.debug("--> starting graceful period and checks that the collector can still collect data if node is master"); - beginGracefulPeriod(); - if (node.equals(internalCluster().getMasterName())) { - assertCanCollect(collector, ClusterInfoMonitoringDoc.class, ClusterStatsMonitoringDoc.class); - } else { - assertCannotCollect(collector); - } - - logger.debug("--> ending graceful period and checks that the collector can still collect data (if node is master)"); - endGracefulPeriod(); - if (node.equals(internalCluster().getMasterName())) { - assertCanCollect(collector, ClusterInfoMonitoringDoc.class); - } else { - assertCannotCollect(collector); - } - - logger.debug("--> disabling license and checks that the collector can still collect data (if node is master)"); - disableLicense(); - if (node.equals(internalCluster().getMasterName())) { - assertCanCollect(collector, ClusterInfoMonitoringDoc.class); - } else { - assertCannotCollect(collector); - } - } - } finally { - // Ensure license is enabled before finishing the test - enableLicense(); - } - } - private ClusterStatsCollector newClusterStatsCollector() { // This collector runs on master node only return newClusterStatsCollector(internalCluster().getMasterName()); @@ -131,7 +85,7 @@ public class ClusterStatsCollectorTests extends AbstractCollectorTestCase { return new ClusterStatsCollector(internalCluster().getInstance(Settings.class, nodeId), internalCluster().getInstance(ClusterService.class, nodeId), internalCluster().getInstance(MonitoringSettings.class, nodeId), - internalCluster().getInstance(MonitoringLicensee.class, nodeId), + internalCluster().getInstance(XPackLicenseState.class, nodeId), securedClient(nodeId), internalCluster().getInstance(LicenseService.class, nodeId)); } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollectorTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollectorTests.java index 86c24fa2b25..fdd37852e3f 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollectorTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexRecoveryCollectorTests.java @@ -13,10 +13,10 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.indices.recovery.RecoveryState; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.test.hamcrest.ElasticsearchAssertions; import org.elasticsearch.xpack.monitoring.MonitoredSystem; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollectorTestCase; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; @@ -130,46 +130,6 @@ public class IndexRecoveryCollectorTests extends AbstractCollectorTestCase { } } - public void testIndexRecoveryCollectorWithLicensing() throws Exception { - List<String> nodesIds = internalCluster().startNodesAsync(randomIntBetween(2, 5)).get(); - waitForNoBlocksOnNodes(); - - try { - for (String node : nodesIds) { - logger.debug("--> creating a new instance of the collector"); - IndexRecoveryCollector collector = newIndexRecoveryCollector(node); - assertNotNull(collector); - - logger.debug("--> enabling license and checks that the collector can collect data if node is master"); - enableLicense(); - if (node.equals(internalCluster().getMasterName())) { - assertCanCollect(collector); - } else { - assertCannotCollect(collector); - } - - logger.debug("--> starting graceful period and checks that the collector can still collect data if node is master"); - beginGracefulPeriod(); - if (node.equals(internalCluster().getMasterName())) { - assertCanCollect(collector); - } else { - assertCannotCollect(collector); - } - - logger.debug("--> ending graceful period and checks that the collector cannot collect data"); - endGracefulPeriod(); - assertCannotCollect(collector); - - logger.debug("--> disabling license and checks that the collector cannot collect data"); - disableLicense(); - assertCannotCollect(collector); - } - } finally { - // Ensure license is enabled before finishing the test - enableLicense(); - } - } - public void testEmptyCluster() throws Exception { final String node = internalCluster().startNode(Settings.builder().put(MonitoringSettings.INDICES.getKey(), Strings.EMPTY_ARRAY)); @@ -211,7 +171,7 @@ public class IndexRecoveryCollectorTests extends AbstractCollectorTestCase { return new IndexRecoveryCollector(internalCluster().getInstance(Settings.class, nodeId), internalCluster().getInstance(ClusterService.class, nodeId), internalCluster().getInstance(MonitoringSettings.class, nodeId), - internalCluster().getInstance(MonitoringLicensee.class, nodeId), + internalCluster().getInstance(XPackLicenseState.class, nodeId), securedClient(nodeId)); } } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollectorTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollectorTests.java index bbfa57e01d4..3d7cd3bda92 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollectorTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndexStatsCollectorTests.java @@ -11,9 +11,9 @@ import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexNotFoundException; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.xpack.monitoring.MonitoredSystem; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollectorTestCase; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; @@ -181,55 +181,6 @@ public class IndexStatsCollectorTests extends AbstractCollectorTestCase { } } - public void testIndexStatsCollectorWithLicensing() throws Exception { - List<String> nodesIds = internalCluster().startNodesAsync(randomIntBetween(2, 5)).get(); - waitForNoBlocksOnNodes(); - - try { - final int nbDocs = randomIntBetween(1, 20); - for (int i = 0; i < nbDocs; i++) { - client().prepareIndex("test", "test").setSource("num", i).get(); - } - - securedFlush(); - securedRefresh(); - securedEnsureGreen("test"); - - for (String node : nodesIds) { - logger.debug("--> creating a new instance of the collector"); - IndexStatsCollector collector = newIndexStatsCollector(node); - assertNotNull(collector); - - logger.debug("--> enabling license and checks that the collector can collect data if node is master"); - enableLicense(); - if (node.equals(internalCluster().getMasterName())) { - assertCanCollect(collector); - } else { - assertCannotCollect(collector); - } - - logger.debug("--> starting graceful period and checks that the collector can still collect data if node is master"); - beginGracefulPeriod(); - if (node.equals(internalCluster().getMasterName())) { - assertCanCollect(collector); - } else { - assertCannotCollect(collector); - } - - logger.debug("--> ending graceful period and checks that the collector cannot collect data"); - endGracefulPeriod(); - assertCannotCollect(collector); - - logger.debug("--> disabling license and checks that the collector cannot collect data"); - disableLicense(); - assertCannotCollect(collector); - } - } finally { - // Ensure license is enabled before finishing the test - enableLicense(); - } - } - private IndexStatsCollector newIndexStatsCollector() { // This collector runs on master node only return newIndexStatsCollector(internalCluster().getMasterName()); @@ -240,7 +191,7 @@ public class IndexStatsCollectorTests extends AbstractCollectorTestCase { return new IndexStatsCollector(internalCluster().getInstance(Settings.class, nodeId), internalCluster().getInstance(ClusterService.class, nodeId), internalCluster().getInstance(MonitoringSettings.class, nodeId), - internalCluster().getInstance(MonitoringLicensee.class, nodeId), + internalCluster().getInstance(XPackLicenseState.class, nodeId), securedClient(nodeId)); } } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollectorTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollectorTests.java index bd4706ec065..8efc0ff1b11 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollectorTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/indices/IndicesStatsCollectorTests.java @@ -13,9 +13,9 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexNotFoundException; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.xpack.monitoring.MonitoredSystem; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollectorTestCase; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; @@ -155,55 +155,6 @@ public class IndicesStatsCollectorTests extends AbstractCollectorTestCase { assertThat(indicesStats.getIndices().keySet(), hasSize(nbIndices)); } - public void testIndicesStatsCollectorWithLicensing() throws Exception { - List<String> nodesIds = internalCluster().startNodesAsync(randomIntBetween(2, 5)).get(); - waitForNoBlocksOnNodes(); - - try { - final int nbDocs = randomIntBetween(1, 20); - for (int i = 0; i < nbDocs; i++) { - client().prepareIndex("test", "test").setSource("num", i).get(); - } - - securedFlush(); - securedRefresh(); - securedEnsureGreen("test"); - - for (String node : nodesIds) { - logger.debug("--> creating a new instance of the collector"); - IndicesStatsCollector collector = newIndicesStatsCollector(node); - assertNotNull(collector); - - logger.debug("--> enabling license and checks that the collector can collect data if node is master"); - enableLicense(); - if (node.equals(internalCluster().getMasterName())) { - assertCanCollect(collector); - } else { - assertCannotCollect(collector); - } - - logger.debug("--> starting graceful period and checks that the collector can still collect data if node is master"); - beginGracefulPeriod(); - if (node.equals(internalCluster().getMasterName())) { - assertCanCollect(collector); - } else { - assertCannotCollect(collector); - } - - logger.debug("--> ending graceful period and checks that the collector cannot collect data"); - endGracefulPeriod(); - assertCannotCollect(collector); - - logger.debug("--> disabling license and checks that the collector cannot collect data"); - disableLicense(); - assertCannotCollect(collector); - } - } finally { - // Ensure license is enabled before finishing the test - enableLicense(); - } - } - private IndicesStatsCollector newIndicesStatsCollector() { // This collector runs on master node only return newIndicesStatsCollector(internalCluster().getMasterName()); @@ -216,7 +167,7 @@ public class IndicesStatsCollectorTests extends AbstractCollectorTestCase { return new IndicesStatsCollector(internalCluster().getInstance(Settings.class, nodeId), internalCluster().getInstance(ClusterService.class, nodeId), internalCluster().getInstance(MonitoringSettings.class, nodeId), - internalCluster().getInstance(MonitoringLicensee.class, nodeId), + internalCluster().getInstance(XPackLicenseState.class, nodeId), securedClient(nodeId)); } } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollectorTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollectorTests.java index c2a9067f579..8d503b2b7be 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollectorTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/node/NodeStatsCollectorTests.java @@ -11,9 +11,9 @@ import org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.NodeEnvironment; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.xpack.monitoring.MonitoredSystem; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollectorTestCase; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; @@ -63,41 +63,11 @@ public class NodeStatsCollectorTests extends AbstractCollectorTestCase { } } - public void testNodeStatsCollectorWithLicensing() { - try { - String[] nodes = internalCluster().getNodeNames(); - for (String node : nodes) { - logger.debug("--> creating a new instance of the collector"); - NodeStatsCollector collector = newNodeStatsCollector(node); - assertNotNull(collector); - - logger.debug("--> enabling license and checks that the collector can collect data"); - enableLicense(); - assertCanCollect(collector); - - logger.debug("--> starting graceful period and checks that the collector can still collect data"); - beginGracefulPeriod(); - assertCanCollect(collector); - - logger.debug("--> ending graceful period and checks that the collector cannot collect data"); - endGracefulPeriod(); - assertCannotCollect(collector); - - logger.debug("--> disabling license and checks that the collector cannot collect data"); - disableLicense(); - assertCannotCollect(collector); - } - } finally { - // Ensure license is enabled before finishing the test - enableLicense(); - } - } - private NodeStatsCollector newNodeStatsCollector(final String nodeId) { return new NodeStatsCollector(internalCluster().getInstance(Settings.class, nodeId), internalCluster().getInstance(ClusterService.class, nodeId), internalCluster().getInstance(MonitoringSettings.class, nodeId), - internalCluster().getInstance(MonitoringLicensee.class, nodeId), + internalCluster().getInstance(XPackLicenseState.class, nodeId), internalCluster().getInstance(InternalClient.class, nodeId), internalCluster().getInstance(NodeEnvironment.class, nodeId), internalCluster().getInstance(DiskThresholdDecider.class, nodeId)); diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollectorTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollectorTests.java index 6ea921ed419..17aa341cffc 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollectorTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/agent/collector/shards/ShardsCollectorTests.java @@ -10,8 +10,8 @@ import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.routing.ShardRouting; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.monitoring.MonitoredSystem; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.agent.collector.AbstractCollectorTestCase; import org.elasticsearch.xpack.monitoring.agent.exporter.MonitoringDoc; @@ -160,44 +160,6 @@ public class ShardsCollectorTests extends AbstractCollectorTestCase { } } - public void testShardsCollectorWithLicensing() { - try { - String[] nodes = internalCluster().getNodeNames(); - for (String node : nodes) { - logger.debug("--> creating a new instance of the collector"); - ShardsCollector collector = newShardsCollector(node); - assertNotNull(collector); - - logger.debug("--> enabling license and checks that the collector can collect data if node is master"); - enableLicense(); - if (node.equals(internalCluster().getMasterName())) { - assertCanCollect(collector); - } else { - assertCannotCollect(collector); - } - - logger.debug("--> starting graceful period and checks that the collector can still collect data if node is master"); - beginGracefulPeriod(); - if (node.equals(internalCluster().getMasterName())) { - assertCanCollect(collector); - } else { - assertCannotCollect(collector); - } - - logger.debug("--> ending graceful period and checks that the collector cannot collect data"); - endGracefulPeriod(); - assertCannotCollect(collector); - - logger.debug("--> disabling license and checks that the collector cannot collect data"); - disableLicense(); - assertCannotCollect(collector); - } - } finally { - // Ensure license is enabled before finishing the test - enableLicense(); - } - } - private ShardsCollector newShardsCollector() { // This collector runs on master node only return newShardsCollector(internalCluster().getMasterName()); @@ -208,6 +170,6 @@ public class ShardsCollectorTests extends AbstractCollectorTestCase { return new ShardsCollector(internalCluster().getInstance(Settings.class, nodeId), internalCluster().getInstance(ClusterService.class, nodeId), internalCluster().getInstance(MonitoringSettings.class, nodeId), - internalCluster().getInstance(MonitoringLicensee.class, nodeId)); + internalCluster().getInstance(XPackLicenseState.class, nodeId)); } } diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/cleaner/CleanerServiceTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/cleaner/CleanerServiceTests.java index 89f2b72af5e..e9b0f4f62c8 100644 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/cleaner/CleanerServiceTests.java +++ b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/cleaner/CleanerServiceTests.java @@ -8,10 +8,10 @@ package org.elasticsearch.xpack.monitoring.cleaner; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.threadpool.TestThreadPool; import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; @@ -34,7 +34,7 @@ public class CleanerServiceTests extends ESTestCase { @Rule public ExpectedException expectedException = ExpectedException.none(); - private final MonitoringLicensee licensee = mock(MonitoringLicensee.class); + private final XPackLicenseState licenseState = mock(XPackLicenseState.class); private ClusterSettings clusterSettings; private ThreadPool threadPool; @@ -56,39 +56,39 @@ public class CleanerServiceTests extends ESTestCase { TimeValue expected = TimeValue.timeValueHours(1); Settings settings = Settings.builder().put(MonitoringSettings.HISTORY_DURATION.getKey(), expected.getStringRep()).build(); - new CleanerService(settings, clusterSettings, threadPool, licensee); + new CleanerService(settings, clusterSettings, threadPool, licenseState); } public void testGetRetentionWithSettingWithUpdatesAllowed() { TimeValue expected = TimeValue.timeValueHours(25); Settings settings = Settings.builder().put(MonitoringSettings.HISTORY_DURATION.getKey(), expected.getStringRep()).build(); - when(licensee.allowUpdateRetention()).thenReturn(true); + when(licenseState.isUpdateRetentionAllowed()).thenReturn(true); - assertEquals(expected, new CleanerService(settings, clusterSettings, threadPool, licensee).getRetention()); + assertEquals(expected, new CleanerService(settings, clusterSettings, threadPool, licenseState).getRetention()); - verify(licensee).allowUpdateRetention(); + verify(licenseState).isUpdateRetentionAllowed(); } public void testGetRetentionDefaultValueWithNoSettings() { - when(licensee.allowUpdateRetention()).thenReturn(true); + when(licenseState.isUpdateRetentionAllowed()).thenReturn(true); assertEquals(MonitoringSettings.HISTORY_DURATION.get(Settings.EMPTY), - new CleanerService(Settings.EMPTY, clusterSettings, threadPool, licensee).getRetention()); + new CleanerService(Settings.EMPTY, clusterSettings, threadPool, licenseState).getRetention()); - verify(licensee).allowUpdateRetention(); + verify(licenseState).isUpdateRetentionAllowed(); } public void testGetRetentionDefaultValueWithSettingsButUpdatesNotAllowed() { TimeValue notExpected = TimeValue.timeValueHours(25); Settings settings = Settings.builder().put(MonitoringSettings.HISTORY_DURATION.getKey(), notExpected.getStringRep()).build(); - when(licensee.allowUpdateRetention()).thenReturn(false); + when(licenseState.isUpdateRetentionAllowed()).thenReturn(false); assertEquals(MonitoringSettings.HISTORY_DURATION.get(Settings.EMPTY), - new CleanerService(settings, clusterSettings, threadPool, licensee).getRetention()); + new CleanerService(settings, clusterSettings, threadPool, licenseState).getRetention()); - verify(licensee).allowUpdateRetention(); + verify(licenseState).isUpdateRetentionAllowed(); } public void testSetGlobalRetention() { @@ -96,15 +96,15 @@ public class CleanerServiceTests extends ESTestCase { // only thing calling this method and it will use the settings object to validate the time value TimeValue expected = TimeValue.timeValueHours(2); - when(licensee.allowUpdateRetention()).thenReturn(true); + when(licenseState.isUpdateRetentionAllowed()).thenReturn(true); - CleanerService service = new CleanerService(Settings.EMPTY, clusterSettings, threadPool, licensee); + CleanerService service = new CleanerService(Settings.EMPTY, clusterSettings, threadPool, licenseState); service.setGlobalRetention(expected); assertEquals(expected, service.getRetention()); - verify(licensee, times(2)).allowUpdateRetention(); // once by set, once by get + verify(licenseState, times(2)).isUpdateRetentionAllowed(); // once by set, once by get } public void testSetGlobalRetentionAppliesEvenIfLicenseDisallows() { @@ -113,9 +113,9 @@ public class CleanerServiceTests extends ESTestCase { TimeValue expected = TimeValue.timeValueHours(2); // required to be true on the second call for it to see it take effect - when(licensee.allowUpdateRetention()).thenReturn(false).thenReturn(true); + when(licenseState.isUpdateRetentionAllowed()).thenReturn(false).thenReturn(true); - CleanerService service = new CleanerService(Settings.EMPTY, clusterSettings, threadPool, licensee); + CleanerService service = new CleanerService(Settings.EMPTY, clusterSettings, threadPool, licenseState); // uses allow=false service.setGlobalRetention(expected); @@ -123,7 +123,7 @@ public class CleanerServiceTests extends ESTestCase { // uses allow=true assertEquals(expected, service.getRetention()); - verify(licensee, times(2)).allowUpdateRetention(); + verify(licenseState, times(2)).isUpdateRetentionAllowed(); } public void testNextExecutionDelay() { @@ -151,9 +151,9 @@ public class CleanerServiceTests extends ESTestCase { CountDownLatch latch = new CountDownLatch(nbExecutions); logger.debug("--> creates a cleaner service that cleans every second"); - MonitoringLicensee licensee = mock(MonitoringLicensee.class); - when(licensee.cleaningEnabled()).thenReturn(true); - CleanerService service = new CleanerService(Settings.EMPTY, clusterSettings, licensee, threadPool, + XPackLicenseState licenseState = mock(XPackLicenseState.class); + when(licenseState.isMonitoringAllowed()).thenReturn(true); + CleanerService service = new CleanerService(Settings.EMPTY, clusterSettings, licenseState, threadPool, new TestExecutionScheduler(1_000)); logger.debug("--> registers cleaning listener"); diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/license/LicenseIntegrationTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/license/LicenseIntegrationTests.java deleted file mode 100644 index 422af9070af..00000000000 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/license/LicenseIntegrationTests.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.monitoring.license; - -import org.elasticsearch.action.ActionRequest; -import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.cluster.service.ClusterService; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.inject.Module; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.env.Environment; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.Licensing; -import org.elasticsearch.license.plugin.core.LicenseService; -import org.elasticsearch.license.plugin.core.Licensee; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.rest.RestHandler; -import org.elasticsearch.test.ESIntegTestCase.ClusterScope; -import org.elasticsearch.watcher.ResourceWatcherService; -import org.elasticsearch.xpack.XPackPlugin; -import org.elasticsearch.xpack.graph.GraphLicensee; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; -import org.elasticsearch.xpack.monitoring.test.MonitoringIntegTestCase; -import org.elasticsearch.xpack.security.SecurityLicenseState; -import org.elasticsearch.xpack.support.clock.Clock; -import org.elasticsearch.xpack.watcher.WatcherLicensee; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import static java.util.Collections.emptyList; -import static org.elasticsearch.test.ESIntegTestCase.Scope.SUITE; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; - -@ClusterScope(scope = SUITE, transportClientRatio = 0, numClientNodes = 0) -public class LicenseIntegrationTests extends MonitoringIntegTestCase { - @Override - protected Collection<Class<? extends Plugin>> nodePlugins() { - return Arrays.asList(InternalXPackPlugin.class); - } - - @Override - protected Settings nodeSettings(int nodeOrdinal) { - return Settings.builder() - .put(super.nodeSettings(nodeOrdinal)) - .build(); - } - - public void testEnableDisableLicense() { - assertTrue(getLicensee().getStatus().isActive()); - assertThat(getLicensee().collectionEnabled(), is(true)); - disableLicensing(); - - assertThat(getLicensee().getStatus().isActive(), equalTo(false)); - assertThat(getLicensee().collectionEnabled(), is(false)); - enableLicensing(); - - assertTrue(getLicensee().getStatus().isActive()); - assertThat(getLicensee().collectionEnabled(), is(true)); - } - - private MonitoringLicensee getLicensee() { - MonitoringLicensee licensee = internalCluster().getInstance(MonitoringLicensee.class); - assertNotNull(licensee); - return licensee; - } - - public static void disableLicensing() { - for (MockLicenseService service : internalCluster().getInstances(MockLicenseService.class)) { - service.disable(); - } - } - - public static void enableLicensing() { - for (MockLicenseService service : internalCluster().getInstances(MockLicenseService.class)) { - service.enable(); - } - } - - public static class MockLicensing extends Licensing { - - public MockLicensing() { - super(Settings.EMPTY); - } - - @Override - public Collection<Module> nodeModules() { - return Collections.singletonList(b -> b.bind(LicenseService.class).to(MockLicenseService.class)); - } - - @Override - public Collection<Object> createComponents(ClusterService clusterService, Clock clock, Environment environment, - ResourceWatcherService resourceWatcherService, - SecurityLicenseState securityLicenseState) { - WatcherLicensee watcherLicensee = new WatcherLicensee(settings); - MonitoringLicensee monitoringLicensee = new MonitoringLicensee(settings); - GraphLicensee graphLicensee = new GraphLicensee(settings); - LicenseService licenseService = new MockLicenseService(settings, environment, resourceWatcherService, - Arrays.asList(watcherLicensee, monitoringLicensee, graphLicensee)); - return Arrays.asList(licenseService, watcherLicensee, monitoringLicensee, graphLicensee); - } - - @Override - public List<ActionHandler<? extends ActionRequest<?>, ? extends ActionResponse>> getActions() { - return emptyList(); - } - - @Override - public List<Class<? extends RestHandler>> getRestHandlers() { - return emptyList(); - } - } - - public static class MockLicenseService extends LicenseService { - - private final List<Licensee> licensees; - - @Inject - public MockLicenseService(Settings settings, Environment environment, - ResourceWatcherService resourceWatcherService, List<Licensee> licensees) { - super(settings, null, null, environment, resourceWatcherService, licensees); - this.licensees = licensees; - enable(); - } - - public void enable() { - for (Licensee licensee : licensees) { - licensee.onChange(new Licensee.Status(License.OperationMode.BASIC, true)); - } - } - - public void disable() { - for (Licensee licensee : licensees) { - licensee.onChange(new Licensee.Status(License.OperationMode.BASIC, false)); - } - } - - @Override - public Licensee.Status licenseeStatus(License license) { - return null; - } - - @Override - public License getLicense() { - return null; - } - - @Override - protected void doStart() {} - - @Override - protected void doStop() {} - } - - public static class InternalXPackPlugin extends XPackPlugin { - public InternalXPackPlugin(Settings settings) throws IOException { - super(settings); - licensing = new MockLicensing(); - } - } -} diff --git a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/license/MonitoringLicenseeTests.java b/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/license/MonitoringLicenseeTests.java deleted file mode 100644 index b6844190c77..00000000000 --- a/elasticsearch/x-pack/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/license/MonitoringLicenseeTests.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.monitoring.license; - -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.core.License.OperationMode; -import org.elasticsearch.license.plugin.core.AbstractLicenseeTestCase; -import org.elasticsearch.license.plugin.core.Licensee.Status; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; - -import java.util.function.Predicate; - -import static org.hamcrest.Matchers.equalTo; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * Tests {@link MonitoringLicensee}. - * <p> - * If you change the behavior of these tests, then it means that licensing changes for Monitoring! - */ -public class MonitoringLicenseeTests extends AbstractLicenseeTestCase { - private final MonitoringLicensee licensee = new MonitoringLicensee(Settings.EMPTY); - - public void testAcknowledgementMessagesToAnyFromFreeIsNoOp() { - assertEmptyAck(OperationMode.BASIC, randomMode(), licensee); - } - - public void testAcknowledgementMessagesToTrialGoldOrPlatinumFromAnyIsNoOp() { - assertEmptyAck(randomMode(), randomTrialStandardGoldOrPlatinumMode(), licensee); - } - - public void testAcknowledgementMessagesToBasicFromNotBasicNotesLimits() { - OperationMode from = randomFrom(OperationMode.STANDARD, OperationMode.GOLD, OperationMode.PLATINUM, OperationMode.TRIAL); - OperationMode to = OperationMode.BASIC; - - String[] messages = ackLicenseChange(from, to, licensee); - - // leaving messages up to inspection - assertThat(fromToMessage(from, to), messages.length, equalTo(2)); - } - - public void testCollectionEnabledIsTrueForActiveState() { - assertEnabled(true, MonitoringLicensee::collectionEnabled, true); - } - - public void testCollectionEnabledIsFalseForInactiveState() { - assertEnabled(false, MonitoringLicensee::collectionEnabled, false); - } - - public void testCleaningEnabledIsTrueForActiveState() { - assertEnabled(true, MonitoringLicensee::cleaningEnabled, true); - } - - public void testCleaningEnabledIsFalseForInactiveState() { - assertEnabled(false, MonitoringLicensee::cleaningEnabled, false); - } - - public void testAllowUpdateRetentionIsTrueForNotBasic() { - OperationMode mode = randomFrom(OperationMode.STANDARD, OperationMode.GOLD, OperationMode.PLATINUM, OperationMode.TRIAL); - assertEnabled(mode, MonitoringLicensee::allowUpdateRetention, true); - } - - public void testAllowUpdateRetentionIsFalseForBasic() { - assertEnabled(OperationMode.BASIC, MonitoringLicensee::allowUpdateRetention, false); - } - - public void testAllowUpdateRetentionIsFalseForMissing() { - assertEnabled(OperationMode.MISSING, MonitoringLicensee::allowUpdateRetention, false); - } - - /** - * Assert that the {@link #licensee} is {@code predicate}d as {@code expected} when setting the {@code state}. - * - * @param active The state that should cause the {@code expected} {@code predicate}. - * @param predicate The method to invoke (expected to be an instance method). - * @param expected The expected outcome given the {@code state} and {@code predicate}. - */ - private void assertEnabled(boolean active, Predicate<MonitoringLicensee> predicate, boolean expected) { - Status status = mock(Status.class); - when(status.isActive()).thenReturn(active); - - licensee.onChange(status); - - assertThat(predicate.test(licensee), equalTo(expected)); - - verify(status).isActive(); - } - - /** - * Assert that the {@link #licensee} is {@code predicate}d as {@code expected} when setting the {@code mode}. - * - * @param mode The mode that should cause the {@code expected} {@code predicate}. - * @param predicate The method to invoke (expected to be an instance method). - * @param expected The expected outcome given the {@code mode} and {@code predicate}. - */ - private void assertEnabled(OperationMode mode, Predicate<MonitoringLicensee> predicate, boolean expected) { - Status status = mock(Status.class); - when(status.getMode()).thenReturn(mode); - - licensee.onChange(status); - - assertThat(predicate.test(licensee), equalTo(expected)); - - verify(status).getMode(); - } -} diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/Security.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/Security.java index 68c5dbfed0a..e9ef647a048 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/Security.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/Security.java @@ -40,6 +40,7 @@ import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.env.Environment; import org.elasticsearch.index.IndexModule; import org.elasticsearch.ingest.Processor; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.plugins.ActionPlugin; import org.elasticsearch.plugins.IngestPlugin; import org.elasticsearch.rest.RestHandler; @@ -89,10 +90,10 @@ import org.elasticsearch.xpack.security.authc.ldap.support.SessionFactory; import org.elasticsearch.xpack.security.authc.pki.PkiRealm; import org.elasticsearch.xpack.security.authc.support.SecuredString; import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken; -import org.elasticsearch.xpack.security.authz.AuthorizationService; -import org.elasticsearch.xpack.security.authz.accesscontrol.SetSecurityUserProcessor; import org.elasticsearch.xpack.security.authz.accesscontrol.OptOutQueryCache; import org.elasticsearch.xpack.security.authz.accesscontrol.SecurityIndexSearcherWrapper; +import org.elasticsearch.xpack.security.authz.accesscontrol.SetSecurityUserProcessor; +import org.elasticsearch.xpack.security.authz.AuthorizationService; import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore; import org.elasticsearch.xpack.security.authz.store.FileRolesStore; import org.elasticsearch.xpack.security.authz.store.NativeRolesStore; @@ -149,10 +150,10 @@ public class Security implements ActionPlugin, IngestPlugin { private final Environment env; private final boolean enabled; private final boolean transportClientMode; - private final SecurityLicenseState securityLicenseState; + private final XPackLicenseState licenseState; private final CryptoService cryptoService; - public Security(Settings settings, Environment env) throws IOException { + public Security(Settings settings, Environment env, XPackLicenseState licenseState) throws IOException { this.settings = settings; this.env = env; this.transportClientMode = XPackPlugin.transportClientMode(settings); @@ -163,17 +164,13 @@ public class Security implements ActionPlugin, IngestPlugin { } else { cryptoService = null; } - securityLicenseState = new SecurityLicenseState(); + this.licenseState = licenseState; } public CryptoService getCryptoService() { return cryptoService; } - public SecurityLicenseState getSecurityLicenseState() { - return securityLicenseState; - } - public boolean isEnabled() { return enabled; } @@ -203,7 +200,7 @@ public class Security implements ActionPlugin, IngestPlugin { b.bind(Realms.class).toProvider(Providers.of(null)); // for SecurityFeatureSet b.bind(CompositeRolesStore.class).toProvider(Providers.of(null)); // for SecurityFeatureSet b.bind(AuditTrailService.class) - .toInstance(new AuditTrailService(settings, Collections.emptyList(), securityLicenseState)); + .toInstance(new AuditTrailService(settings, Collections.emptyList(), licenseState)); }); modules.add(new SecurityTransportModule(settings)); return modules; @@ -259,7 +256,7 @@ public class Security implements ActionPlugin, IngestPlugin { } } } - final Realms realms = new Realms(settings, env, realmFactories, securityLicenseState, reservedRealm); + final Realms realms = new Realms(settings, env, realmFactories, licenseState, reservedRealm); components.add(nativeUsersStore); components.add(realms); @@ -288,7 +285,7 @@ public class Security implements ActionPlugin, IngestPlugin { } } final AuditTrailService auditTrailService = - new AuditTrailService(settings, auditTrails.stream().collect(Collectors.toList()), securityLicenseState); + new AuditTrailService(settings, auditTrails.stream().collect(Collectors.toList()), licenseState); components.add(auditTrailService); AuthenticationFailureHandler failureHandler = null; @@ -425,12 +422,13 @@ public class Security implements ActionPlugin, IngestPlugin { return; } - assert securityLicenseState != null; + assert licenseState != null; if (flsDlsEnabled(settings)) { - module.setSearcherWrapper((indexService) -> new SecurityIndexSearcherWrapper(indexService.getIndexSettings(), - indexService.newQueryShardContext(), indexService.mapperService(), - indexService.cache().bitsetFilterCache(), indexService.getIndexServices().getThreadPool().getThreadContext(), - securityLicenseState, indexService.getIndexServices().getScriptService())); + module.setSearcherWrapper(indexService -> + new SecurityIndexSearcherWrapper(indexService.getIndexSettings(), indexService.newQueryShardContext(), + indexService.mapperService(), indexService.cache().bitsetFilterCache(), + indexService.getIndexServices().getThreadPool().getThreadContext(), licenseState, + indexService.getIndexServices().getScriptService())); } if (transportClientMode == false) { /* We need to forcefully overwrite the query cache implementation to use security's opt out query cache implementation. diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/SecurityFeatureSet.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/SecurityFeatureSet.java index 871615149fd..14fb4070264 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/SecurityFeatureSet.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/SecurityFeatureSet.java @@ -13,6 +13,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.security.audit.AuditTrailService; import org.elasticsearch.xpack.security.authc.Realm; import org.elasticsearch.xpack.security.authc.Realms; @@ -40,7 +41,7 @@ public class SecurityFeatureSet implements XPackFeatureSet { private final Settings settings; private final boolean enabled; - private final SecurityLicenseState licenseState; + private final XPackLicenseState licenseState; @Nullable private final Realms realms; @Nullable @@ -53,7 +54,7 @@ public class SecurityFeatureSet implements XPackFeatureSet { private final CryptoService cryptoService; @Inject - public SecurityFeatureSet(Settings settings, @Nullable SecurityLicenseState licenseState, @Nullable Realms realms, + public SecurityFeatureSet(Settings settings, @Nullable XPackLicenseState licenseState, @Nullable Realms realms, NamedWriteableRegistry namedWriteableRegistry, @Nullable CompositeRolesStore rolesStore, @Nullable IPFilter ipFilter, @Nullable AuditTrailService auditTrailService, @Nullable CryptoService cryptoService) { @@ -80,7 +81,7 @@ public class SecurityFeatureSet implements XPackFeatureSet { @Override public boolean available() { - return licenseState != null && licenseState.authenticationAndAuthorizationEnabled(); + return licenseState != null && licenseState.isAuthAllowed(); } @Override diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/SecurityLicenseState.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/SecurityLicenseState.java deleted file mode 100644 index 19e76e230f5..00000000000 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/SecurityLicenseState.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.security; - -import org.elasticsearch.license.core.License.OperationMode; -import org.elasticsearch.license.plugin.core.Licensee.Status; - - -/** - * This class serves to decouple security code that needs to check the license state from the {@link SecurityLicensee} as the - * tight coupling causes issues with guice injection and circular dependencies - */ -public class SecurityLicenseState { - - // we initialize the licensee status to enabled with trial operation mode to ensure no - // legitimate requests are blocked before initial license plugin notification - protected volatile Status status = Status.ENABLED; - - /** - * @return true if authentication and authorization should be enabled. this does not indicate what realms are available - * @see SecurityLicenseState#enabledRealmType() for the enabled realms - */ - public boolean authenticationAndAuthorizationEnabled() { - OperationMode mode = status.getMode(); - return mode == OperationMode.STANDARD || mode == OperationMode.GOLD || mode == OperationMode.PLATINUM - || mode == OperationMode.TRIAL; - } - - /** - * @return true if IP filtering should be enabled - */ - public boolean ipFilteringEnabled() { - OperationMode mode = status.getMode(); - return mode == OperationMode.GOLD || mode == OperationMode.PLATINUM || mode == OperationMode.TRIAL; - } - - /** - * @return true if auditing should be enabled - */ - public boolean auditingEnabled() { - OperationMode mode = status.getMode(); - return mode == OperationMode.GOLD || mode == OperationMode.PLATINUM || mode == OperationMode.TRIAL; - } - - /** - * Indicates whether the stats and health API calls should be allowed. If a license is expired and past the grace - * period then we deny these calls. - * - * @return true if the license allows for the stats and health APIs to be used. - */ - public boolean statsAndHealthEnabled() { - return status.isActive(); - } - - /** - * Determine if Document Level Security (DLS) and Field Level Security (FLS) should be enabled. - * <p> - * DLS and FLS are only disabled when the mode is not: - * <ul> - * <li>{@link OperationMode#PLATINUM}</li> - * <li>{@link OperationMode#TRIAL}</li> - * </ul> - * Note: This does not consider the <em>state</em> of the license so that Security does not suddenly leak information! - * - * @return {@code true} to enable DLS and FLS. Otherwise {@code false}. - */ - public boolean documentAndFieldLevelSecurityEnabled() { - Status status = this.status; - return status.getMode() == OperationMode.TRIAL || status.getMode() == OperationMode.PLATINUM; - } - - /** - * @return the type of realms that are enabled based on the license {@link OperationMode} - */ - public EnabledRealmType enabledRealmType() { - OperationMode mode = status.getMode(); - switch (mode) { - case PLATINUM: - case TRIAL: - return EnabledRealmType.ALL; - case GOLD: - return EnabledRealmType.DEFAULT; - case STANDARD: - return EnabledRealmType.NATIVE; - default: - return EnabledRealmType.NONE; - } - } - - void updateStatus(Status status) { - this.status = status; - } - - public enum EnabledRealmType { - NONE, - NATIVE, - DEFAULT, - ALL - } -} diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/SecurityLicensee.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/SecurityLicensee.java deleted file mode 100644 index 176d08addc1..00000000000 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/SecurityLicensee.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.security; - -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.core.AbstractLicenseeComponent; - -/** - * - */ -public class SecurityLicensee extends AbstractLicenseeComponent { - - private final SecurityLicenseState securityLicenseState; - - public SecurityLicensee(Settings settings, SecurityLicenseState securityLicenseState) { - super(settings, Security.NAME); - this.securityLicenseState = securityLicenseState; - } - - @Override - public void onChange(Status status) { - super.onChange(status); - securityLicenseState.updateStatus(status); - } - - @Override - public String[] expirationMessages() { - return new String[]{ - "Cluster health, cluster stats and indices stats operations are blocked", - "All data operations (read and write) continue to work" - }; - } - - @Override - public String[] acknowledgmentMessages(License.OperationMode currentMode, License.OperationMode newMode) { - switch (newMode) { - case BASIC: - switch (currentMode) { - case TRIAL: - case STANDARD: - case GOLD: - case PLATINUM: - return new String[] { - "The following X-Pack security functionality will be disabled: authentication, authorization, " + - "ip filtering, and auditing. Please restart your node after applying the license.", - "Field and document level access control will be disabled.", - "Custom realms will be ignored." - }; - } - break; - case GOLD: - switch (currentMode) { - case BASIC: - case STANDARD: - // ^^ though technically it was already disabled, it's not bad to remind them - case TRIAL: - case PLATINUM: - return new String[] { - "Field and document level access control will be disabled.", - "Custom realms will be ignored." - }; - } - break; - case STANDARD: - switch (currentMode) { - case BASIC: - // ^^ though technically it was already disabled, it's not bad to remind them - case GOLD: - case PLATINUM: - case TRIAL: - return new String[] { - "Authentication will be limited to the native realms.", - "IP filtering and auditing will be disabled.", - "Field and document level access control will be disabled.", - "Custom realms will be ignored." - }; - } - } - return Strings.EMPTY_ARRAY; - } -} diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilter.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilter.java index 10c0bf70ff1..0d87c1c3260 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilter.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilter.java @@ -33,7 +33,7 @@ import org.elasticsearch.xpack.security.audit.AuditTrail; import org.elasticsearch.xpack.security.authz.AuthorizationUtils; import org.elasticsearch.xpack.security.authz.privilege.HealthAndStatsPrivilege; import org.elasticsearch.xpack.security.crypto.CryptoService; -import org.elasticsearch.xpack.security.SecurityLicenseState; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; @@ -55,13 +55,13 @@ public class SecurityActionFilter extends AbstractComponent implements ActionFil private final AuditTrail auditTrail; private final SecurityActionMapper actionMapper; private final Set<RequestInterceptor> requestInterceptors; - private final SecurityLicenseState licenseState; + private final XPackLicenseState licenseState; private final ThreadContext threadContext; private final SecurityContext securityContext; @Inject public SecurityActionFilter(Settings settings, AuthenticationService authcService, AuthorizationService authzService, - CryptoService cryptoService, AuditTrailService auditTrail, SecurityLicenseState licenseState, + CryptoService cryptoService, AuditTrailService auditTrail, XPackLicenseState licenseState, SecurityActionMapper actionMapper, Set<RequestInterceptor> requestInterceptors, ThreadPool threadPool, SecurityContext securityContext) { super(settings); @@ -83,7 +83,7 @@ public class SecurityActionFilter extends AbstractComponent implements ActionFil A functional requirement - when the license of security is disabled (invalid/expires), security will continue to operate normally, except all read operations will be blocked. */ - if (!licenseState.statsAndHealthEnabled() && LICENSE_EXPIRATION_ACTION_MATCHER.test(action)) { + if (licenseState.isStatsAndHealthAllowed() == false && LICENSE_EXPIRATION_ACTION_MATCHER.test(action)) { logger.error("blocking [{}] operation due to expired license. Cluster health, cluster stats and indices stats \n" + "operations are blocked on license expiration. All data operations (read and write) continue to work. \n" + "If you have a new license, please update it. Otherwise, please reach out to your support contact.", action); @@ -95,7 +95,7 @@ public class SecurityActionFilter extends AbstractComponent implements ActionFil final ThreadContext.StoredContext original = threadContext.newStoredContext(); final boolean restoreOriginalContext = securityContext.getAuthentication() != null; try { - if (licenseState.authenticationAndAuthorizationEnabled()) { + if (licenseState.isAuthAllowed()) { if (AuthorizationUtils.shouldReplaceUserWithSystem(threadContext, action)) { try (ThreadContext.StoredContext ctx = threadContext.stashContext()) { applyInternal(task, action, request, new SigningListener(this, listener, original), chain); diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditTrailService.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditTrailService.java index 60a8307443d..e78d48ade51 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditTrailService.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditTrailService.java @@ -10,15 +10,13 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import org.elasticsearch.common.component.AbstractComponent; -import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.transport.TransportMessage; import org.elasticsearch.xpack.security.Security; -import org.elasticsearch.xpack.security.SecurityLicenseState; import org.elasticsearch.xpack.security.authc.AuthenticationToken; import org.elasticsearch.xpack.security.transport.filter.SecurityIpFilterRule; import org.elasticsearch.xpack.security.user.User; @@ -28,7 +26,7 @@ import org.elasticsearch.xpack.security.user.User; */ public class AuditTrailService extends AbstractComponent implements AuditTrail { - private final SecurityLicenseState securityLicenseState; + private final XPackLicenseState licenseState; final List<AuditTrail> auditTrails; @Override @@ -36,10 +34,10 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { return "service"; } - public AuditTrailService(Settings settings, List<AuditTrail> auditTrails, SecurityLicenseState licenseState) { + public AuditTrailService(Settings settings, List<AuditTrail> auditTrails, XPackLicenseState licenseState) { super(settings); this.auditTrails = Collections.unmodifiableList(auditTrails); - this.securityLicenseState = licenseState; + this.licenseState = licenseState; } /** Returns the audit trail implementations that this service delegates to. */ @@ -49,7 +47,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void anonymousAccessDenied(String action, TransportMessage message) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.anonymousAccessDenied(action, message); } @@ -58,7 +56,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void anonymousAccessDenied(RestRequest request) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.anonymousAccessDenied(request); } @@ -67,7 +65,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void authenticationFailed(RestRequest request) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.authenticationFailed(request); } @@ -76,7 +74,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void authenticationFailed(String action, TransportMessage message) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.authenticationFailed(action, message); } @@ -85,7 +83,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void authenticationFailed(AuthenticationToken token, String action, TransportMessage message) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.authenticationFailed(token, action, message); } @@ -94,7 +92,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void authenticationFailed(String realm, AuthenticationToken token, String action, TransportMessage message) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.authenticationFailed(realm, token, action, message); } @@ -103,7 +101,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void authenticationFailed(AuthenticationToken token, RestRequest request) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.authenticationFailed(token, request); } @@ -112,7 +110,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void authenticationFailed(String realm, AuthenticationToken token, RestRequest request) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.authenticationFailed(realm, token, request); } @@ -121,7 +119,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void accessGranted(User user, String action, TransportMessage message) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.accessGranted(user, action, message); } @@ -130,7 +128,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void accessDenied(User user, String action, TransportMessage message) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.accessDenied(user, action, message); } @@ -146,7 +144,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void tamperedRequest(String action, TransportMessage message) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.tamperedRequest(action, message); } @@ -155,7 +153,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void tamperedRequest(User user, String action, TransportMessage request) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.tamperedRequest(user, action, request); } @@ -164,7 +162,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void connectionGranted(InetAddress inetAddress, String profile, SecurityIpFilterRule rule) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.connectionGranted(inetAddress, profile, rule); } @@ -173,7 +171,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void connectionDenied(InetAddress inetAddress, String profile, SecurityIpFilterRule rule) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.connectionDenied(inetAddress, profile, rule); } @@ -182,7 +180,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void runAsGranted(User user, String action, TransportMessage message) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.runAsGranted(user, action, message); } @@ -191,7 +189,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void runAsDenied(User user, String action, TransportMessage message) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.runAsDenied(user, action, message); } @@ -200,7 +198,7 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { @Override public void runAsDenied(User user, RestRequest request) { - if (securityLicenseState.auditingEnabled()) { + if (licenseState.isAuditingAllowed()) { for (AuditTrail auditTrail : auditTrails) { auditTrail.runAsDenied(user, request); } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realms.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realms.java index 2fda12f8b42..d54e370a9ae 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realms.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authc/Realms.java @@ -5,22 +5,6 @@ */ package org.elasticsearch.xpack.security.authc; -import org.elasticsearch.ElasticsearchException; -import org.elasticsearch.common.component.AbstractLifecycleComponent; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.Property; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.env.Environment; -import org.elasticsearch.xpack.security.SecurityLicenseState.EnabledRealmType; -import org.elasticsearch.xpack.security.authc.activedirectory.ActiveDirectoryRealm; -import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm; -import org.elasticsearch.xpack.security.authc.esnative.NativeRealm; -import org.elasticsearch.xpack.security.authc.file.FileRealm; -import org.elasticsearch.xpack.security.SecurityLicenseState; -import org.elasticsearch.xpack.security.authc.ldap.LdapRealm; -import org.elasticsearch.xpack.security.authc.pki.PkiRealm; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -30,6 +14,21 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.common.component.AbstractLifecycleComponent; +import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.Property; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.env.Environment; +import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.plugin.core.XPackLicenseState.AllowedRealmType; +import org.elasticsearch.xpack.security.authc.activedirectory.ActiveDirectoryRealm; +import org.elasticsearch.xpack.security.authc.esnative.NativeRealm; +import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm; +import org.elasticsearch.xpack.security.authc.file.FileRealm; +import org.elasticsearch.xpack.security.authc.ldap.LdapRealm; +import org.elasticsearch.xpack.security.authc.pki.PkiRealm; + import static org.elasticsearch.xpack.security.Security.setting; /** @@ -44,7 +43,7 @@ public class Realms extends AbstractLifecycleComponent implements Iterable<Realm private final Environment env; private final Map<String, Realm.Factory> factories; - private final SecurityLicenseState securityLicenseState; + private final XPackLicenseState licenseState; private final ReservedRealm reservedRealm; protected List<Realm> realms = Collections.emptyList(); @@ -53,12 +52,12 @@ public class Realms extends AbstractLifecycleComponent implements Iterable<Realm // a list of realms that are considered native, that is they only interact with x-pack and no 3rd party auth sources protected List<Realm> nativeRealmsOnly = Collections.emptyList(); - public Realms(Settings settings, Environment env, Map<String, Realm.Factory> factories, SecurityLicenseState securityLicenseState, + public Realms(Settings settings, Environment env, Map<String, Realm.Factory> factories, XPackLicenseState licenseState, ReservedRealm reservedRealm) { super(settings); this.env = env; this.factories = factories; - this.securityLicenseState = securityLicenseState; + this.licenseState = licenseState; this.reservedRealm = reservedRealm; } @@ -105,12 +104,12 @@ public class Realms extends AbstractLifecycleComponent implements Iterable<Realm @Override public Iterator<Realm> iterator() { - if (securityLicenseState.authenticationAndAuthorizationEnabled() == false) { + if (licenseState.isAuthAllowed() == false) { return Collections.emptyIterator(); } - EnabledRealmType enabledRealmType = securityLicenseState.enabledRealmType(); - switch (enabledRealmType) { + AllowedRealmType allowedRealmType = licenseState.allowedRealmType(); + switch (allowedRealmType) { case ALL: return realms.iterator(); case DEFAULT: diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapper.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapper.java index 65aafbf46a3..4e0c25db6cc 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapper.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapper.java @@ -45,6 +45,7 @@ import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.index.shard.IndexSearcherWrapper; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.index.shard.ShardUtils; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptContext; @@ -52,7 +53,6 @@ import org.elasticsearch.script.ScriptService; import org.elasticsearch.xpack.security.authc.Authentication; import org.elasticsearch.xpack.security.authz.AuthorizationService; import org.elasticsearch.xpack.security.authz.accesscontrol.DocumentSubsetReader.DocumentSubsetDirectoryReader; -import org.elasticsearch.xpack.security.SecurityLicenseState; import org.elasticsearch.xpack.security.support.Exceptions; import org.elasticsearch.xpack.security.user.User; @@ -85,14 +85,14 @@ public class SecurityIndexSearcherWrapper extends IndexSearcherWrapper { private final Set<String> allowedMetaFields; private final QueryShardContext queryShardContext; private final BitsetFilterCache bitsetFilterCache; - private final SecurityLicenseState securityLicenseState; + private final XPackLicenseState licenseState; private final ThreadContext threadContext; private final ESLogger logger; private final ScriptService scriptService; public SecurityIndexSearcherWrapper(IndexSettings indexSettings, QueryShardContext queryShardContext, MapperService mapperService, BitsetFilterCache bitsetFilterCache, - ThreadContext threadContext, SecurityLicenseState securityLicenseState, + ThreadContext threadContext, XPackLicenseState licenseState, ScriptService scriptService) { this.scriptService = scriptService; this.logger = Loggers.getLogger(getClass(), indexSettings.getSettings()); @@ -100,7 +100,7 @@ public class SecurityIndexSearcherWrapper extends IndexSearcherWrapper { this.queryShardContext = queryShardContext; this.bitsetFilterCache = bitsetFilterCache; this.threadContext = threadContext; - this.securityLicenseState = securityLicenseState; + this.licenseState = licenseState; Set<String> allowedMetaFields = new HashSet<>(); allowedMetaFields.addAll(Arrays.asList(MapperService.getAllMetaFields())); @@ -114,7 +114,7 @@ public class SecurityIndexSearcherWrapper extends IndexSearcherWrapper { @Override protected DirectoryReader wrap(DirectoryReader reader) { - if (securityLicenseState.documentAndFieldLevelSecurityEnabled() == false) { + if (licenseState.isDocumentAndFieldLevelSecurityAllowed() == false) { return reader; } @@ -171,7 +171,7 @@ public class SecurityIndexSearcherWrapper extends IndexSearcherWrapper { @Override protected IndexSearcher wrap(IndexSearcher searcher) throws EngineException { - if (securityLicenseState.documentAndFieldLevelSecurityEnabled() == false) { + if (licenseState.isDocumentAndFieldLevelSecurityAllowed() == false) { return searcher; } diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/rest/SecurityRestFilter.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/rest/SecurityRestFilter.java index 9efe72db14e..a3796b60f09 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/rest/SecurityRestFilter.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/rest/SecurityRestFilter.java @@ -19,7 +19,7 @@ import org.elasticsearch.rest.RestFilterChain; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.xpack.security.authc.AuthenticationService; import org.elasticsearch.xpack.security.authc.pki.PkiRealm; -import org.elasticsearch.xpack.security.SecurityLicenseState; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.security.transport.netty3.SecurityNetty3HttpServerTransport; import org.elasticsearch.threadpool.ThreadPool; import org.jboss.netty.handler.ssl.SslHandler; @@ -35,13 +35,13 @@ public class SecurityRestFilter extends RestFilter { private final AuthenticationService service; private final ESLogger logger; - private final SecurityLicenseState licenseState; + private final XPackLicenseState licenseState; private final ThreadContext threadContext; private final boolean extractClientCertificate; @Inject public SecurityRestFilter(AuthenticationService service, RestController controller, Settings settings, - ThreadPool threadPool, SecurityLicenseState licenseState) { + ThreadPool threadPool, XPackLicenseState licenseState) { this.service = service; this.licenseState = licenseState; this.threadContext = threadPool.getThreadContext(); @@ -59,7 +59,7 @@ public class SecurityRestFilter extends RestFilter { @Override public void process(RestRequest request, RestChannel channel, NodeClient client, RestFilterChain filterChain) throws Exception { - if (licenseState.authenticationAndAuthorizationEnabled()) { + if (licenseState.isAuthAllowed()) { // CORS - allow for preflight unauthenticated OPTIONS request if (request.method() != RestRequest.Method.OPTIONS) { if (extractClientCertificate) { diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportService.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportService.java index 47eb2f99fe8..ea1911b9d90 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportService.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/SecurityServerTransportService.java @@ -14,7 +14,7 @@ import org.elasticsearch.xpack.security.authc.AuthenticationService; import org.elasticsearch.xpack.security.authz.AuthorizationService; import org.elasticsearch.xpack.security.authz.AuthorizationUtils; import org.elasticsearch.xpack.security.authz.accesscontrol.RequestContext; -import org.elasticsearch.xpack.security.SecurityLicenseState; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.security.transport.netty3.SecurityNetty3Transport; import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; @@ -46,7 +46,7 @@ public class SecurityServerTransportService extends TransportService { protected final AuthorizationService authzService; protected final SecurityActionMapper actionMapper; protected final ClientTransportFilter clientFilter; - protected final SecurityLicenseState licenseState; + protected final XPackLicenseState licenseState; protected final Map<String, ServerTransportFilter> profileFilters; @@ -56,7 +56,7 @@ public class SecurityServerTransportService extends TransportService { AuthorizationService authzService, SecurityActionMapper actionMapper, ClientTransportFilter clientTransportFilter, - SecurityLicenseState licenseState) { + XPackLicenseState licenseState) { super(settings, transport, threadPool); this.authcService = authcService; this.authzService = authzService; @@ -155,11 +155,11 @@ public class SecurityServerTransportService extends TransportService { protected final String action; protected final TransportRequestHandler<T> handler; private final Map<String, ServerTransportFilter> profileFilters; - private final SecurityLicenseState licenseState; + private final XPackLicenseState licenseState; private final ThreadContext threadContext; public ProfileSecuredRequestHandler(String action, TransportRequestHandler<T> handler, - Map<String, ServerTransportFilter> profileFilters, SecurityLicenseState licenseState, + Map<String, ServerTransportFilter> profileFilters, XPackLicenseState licenseState, ThreadContext threadContext) { this.action = action; this.handler = handler; @@ -171,7 +171,7 @@ public class SecurityServerTransportService extends TransportService { @Override public void messageReceived(T request, TransportChannel channel, Task task) throws Exception { try (ThreadContext.StoredContext ctx = threadContext.newStoredContext()) { - if (licenseState.authenticationAndAuthorizationEnabled()) { + if (licenseState.isAuthAllowed()) { String profile = channel.getProfileName(); ServerTransportFilter filter = profileFilters.get(profile); diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/filter/IPFilter.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/filter/IPFilter.java index 98d977dea9c..dc57434b81c 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/filter/IPFilter.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/filter/IPFilter.java @@ -17,7 +17,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.xpack.security.audit.AuditTrail; -import org.elasticsearch.xpack.security.SecurityLicenseState; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.transport.TransportSettings; import org.elasticsearch.xpack.security.audit.AuditTrailService; @@ -88,8 +88,8 @@ public class IPFilter { } }; - private final AuditTrail auditTrail; - private final SecurityLicenseState licenseState; + private final AuditTrailService auditTrail; + private final XPackLicenseState licenseState; private final boolean alwaysAllowBoundAddresses; private final ESLogger logger; @@ -107,7 +107,7 @@ public class IPFilter { @Inject public IPFilter(final Settings settings, AuditTrailService auditTrail, ClusterSettings clusterSettings, - SecurityLicenseState licenseState) { + XPackLicenseState licenseState) { this.logger = Loggers.getLogger(getClass(), settings); this.auditTrail = auditTrail; this.licenseState = licenseState; @@ -174,7 +174,7 @@ public class IPFilter { } public boolean accept(String profile, InetAddress peerAddress) { - if (licenseState.ipFilteringEnabled() == false) { + if (licenseState.isIpFilteringAllowed() == false) { return true; } diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/LicensingTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/LicensingTests.java deleted file mode 100644 index 13e0cd12b43..00000000000 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/integration/LicensingTests.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.integration; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.elasticsearch.ElasticsearchSecurityException; -import org.elasticsearch.action.ActionRequest; -import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; -import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse; -import org.elasticsearch.action.admin.cluster.stats.ClusterStatsIndices; -import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse; -import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse; -import org.elasticsearch.action.index.IndexResponse; -import org.elasticsearch.client.Client; -import org.elasticsearch.client.Response; -import org.elasticsearch.client.ResponseException; -import org.elasticsearch.client.transport.NoNodeAvailableException; -import org.elasticsearch.client.transport.TransportClient; -import org.elasticsearch.cluster.service.ClusterService; -import org.elasticsearch.common.inject.Module; -import org.elasticsearch.common.network.NetworkModule; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.util.concurrent.ThreadContext; -import org.elasticsearch.env.Environment; -import org.elasticsearch.license.core.License.OperationMode; -import org.elasticsearch.license.plugin.Licensing; -import org.elasticsearch.license.plugin.core.LicenseService; -import org.elasticsearch.license.plugin.core.Licensee; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.rest.RestHandler; -import org.elasticsearch.rest.RestStatus; -import org.elasticsearch.test.SecurityIntegTestCase; -import org.elasticsearch.test.SecuritySettingsSource; -import org.elasticsearch.transport.Transport; -import org.elasticsearch.watcher.ResourceWatcherService; -import org.elasticsearch.xpack.MockNetty3Plugin; -import org.elasticsearch.xpack.XPackPlugin; -import org.elasticsearch.xpack.graph.GraphLicensee; -import org.elasticsearch.xpack.monitoring.MonitoringLicensee; -import org.elasticsearch.xpack.XPackTransportClient; -import org.elasticsearch.xpack.security.Security; -import org.elasticsearch.xpack.security.SecurityLicenseState; -import org.elasticsearch.xpack.security.SecurityLicensee; -import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken; -import org.elasticsearch.xpack.support.clock.Clock; -import org.elasticsearch.xpack.watcher.WatcherLicensee; -import org.junit.After; - -import static java.util.Collections.emptyList; -import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; -import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures; -import static org.hamcrest.Matchers.greaterThanOrEqualTo; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; - -/** - * - */ -public class LicensingTests extends SecurityIntegTestCase { - public static final String ROLES = - SecuritySettingsSource.DEFAULT_ROLE + ":\n" + - " cluster: [ all ]\n" + - " indices:\n" + - " - names: '*'\n" + - " privileges: [manage]\n" + - " - names: '/.*/'\n" + - " privileges: [write]\n" + - " - names: 'test'\n" + - " privileges: [read]\n" + - " - names: 'test1'\n" + - " privileges: [read]\n" + - "\n" + - "role_a:\n" + - " indices:\n" + - " - names: 'a'\n" + - " privileges: [all]\n" + - "\n" + - "role_b:\n" + - " indices:\n" + - " - names: 'b'\n" + - " privileges: [all]\n"; - - public static final String USERS = - SecuritySettingsSource.CONFIG_STANDARD_USER + - "user_a:{plain}passwd\n" + - "user_b:{plain}passwd\n"; - - public static final String USERS_ROLES = - SecuritySettingsSource.CONFIG_STANDARD_USER_ROLES + - "role_a:user_a,user_b\n" + - "role_b:user_b\n"; - - @Override - protected String configRoles() { - return ROLES; - } - - @Override - protected String configUsers() { - return USERS; - } - - @Override - protected String configUsersRoles() { - return USERS_ROLES; - } - - @Override - public Settings nodeSettings(int nodeOrdinal) { - return Settings.builder().put(super.nodeSettings(nodeOrdinal)) - .put(NetworkModule.HTTP_ENABLED.getKey(), true) - .build(); - } - - @Override - protected Collection<Class<? extends Plugin>> nodePlugins() { - ArrayList<Class<? extends Plugin>> plugins = new ArrayList<>(super.nodePlugins()); - plugins.add(MockNetty3Plugin.class); // for http - return plugins; - } - - @Override - protected Class<? extends XPackPlugin> xpackPluginClass() { - return InternalXPackPlugin.class; - } - - @After - public void resetLicensing() { - enableLicensing(); - } - - public void testEnableDisableBehaviour() throws Exception { - IndexResponse indexResponse = index("test", "type", jsonBuilder() - .startObject() - .field("name", "value") - .endObject()); - assertThat(indexResponse.isCreated(), is(true)); - - - indexResponse = index("test1", "type", jsonBuilder() - .startObject() - .field("name", "value1") - .endObject()); - assertThat(indexResponse.isCreated(), is(true)); - - refresh(); - - Client client = internalCluster().transportClient(); - - disableLicensing(); - - assertElasticsearchSecurityException(() -> client.admin().indices().prepareStats().get()); - assertElasticsearchSecurityException(() -> client.admin().cluster().prepareClusterStats().get()); - assertElasticsearchSecurityException(() -> client.admin().cluster().prepareHealth().get()); - assertElasticsearchSecurityException(() -> client.admin().cluster().prepareNodesStats().get()); - - enableLicensing(randomFrom(OperationMode.values())); - - IndicesStatsResponse indicesStatsResponse = client.admin().indices().prepareStats().get(); - assertNoFailures(indicesStatsResponse); - - ClusterStatsResponse clusterStatsNodeResponse = client.admin().cluster().prepareClusterStats().get(); - assertThat(clusterStatsNodeResponse, notNullValue()); - ClusterStatsIndices indices = clusterStatsNodeResponse.getIndicesStats(); - assertThat(indices, notNullValue()); - assertThat(indices.getIndexCount(), greaterThanOrEqualTo(2)); - - ClusterHealthResponse clusterIndexHealth = client.admin().cluster().prepareHealth().get(); - assertThat(clusterIndexHealth, notNullValue()); - - NodesStatsResponse nodeStats = client.admin().cluster().prepareNodesStats().get(); - assertThat(nodeStats, notNullValue()); - } - - public void testRestAuthenticationByLicenseType() throws Exception { - Response response = getRestClient().performRequest("GET", "/"); - // the default of the licensing tests is basic - assertThat(response.getStatusLine().getStatusCode(), is(200)); - - // generate a new license with a mode that enables auth - OperationMode mode = randomFrom(OperationMode.GOLD, OperationMode.TRIAL, OperationMode.PLATINUM, OperationMode.STANDARD); - enableLicensing(mode); - try { - getRestClient().performRequest("GET", "/"); - fail("request should have failed"); - } catch(ResponseException e) { - assertThat(e.getResponse().getStatusLine().getStatusCode(), is(401)); - } - } - - public void testTransportClientAuthenticationByLicenseType() throws Exception { - Settings.Builder builder = Settings.builder() - .put(internalCluster().transportClient().settings()); - // remove user info - builder.remove(Security.USER_SETTING.getKey()); - builder.remove(ThreadContext.PREFIX + "." + UsernamePasswordToken.BASIC_AUTH_HEADER); - - // basic has no auth - try (TransportClient client = new XPackTransportClient(builder.build())) { - client.addTransportAddress(internalCluster().getDataNodeInstance(Transport.class).boundAddress().publishAddress()); - assertGreenClusterState(client); - } - - // enable a license that enables security - OperationMode mode = randomFrom(OperationMode.GOLD, OperationMode.TRIAL, OperationMode.PLATINUM, OperationMode.STANDARD); - enableLicensing(mode); - - try (TransportClient client = new XPackTransportClient(builder.build())) { - client.addTransportAddress(internalCluster().getDataNodeInstance(Transport.class).boundAddress().publishAddress()); - client.admin().cluster().prepareHealth().get(); - fail("should not have been able to connect to a node!"); - } catch (NoNodeAvailableException e) { - // expected - } - } - - private static void assertElasticsearchSecurityException(ThrowingRunnable runnable) { - ElasticsearchSecurityException ee = expectThrows(ElasticsearchSecurityException.class, runnable); - assertThat(ee.getHeader("es.license.expired.feature"), hasItem(Security.NAME)); - assertThat(ee.status(), is(RestStatus.FORBIDDEN)); - } - - public static void disableLicensing() { - disableLicensing(OperationMode.BASIC); - } - - public static void disableLicensing(OperationMode operationMode) { - for (TestLicenseService service : internalCluster().getInstances(TestLicenseService.class)) { - service.disable(operationMode); - } - } - - public static void enableLicensing() { - enableLicensing(OperationMode.BASIC); - } - - public static void enableLicensing(OperationMode operationMode) { - for (TestLicenseService service : internalCluster().getInstances(TestLicenseService.class)) { - service.enable(operationMode); - } - } - - public static class InternalLicensing extends Licensing { - - @Override - public Collection<Module> nodeModules() { - return Collections.singletonList(b -> b.bind(LicenseService.class).to(TestLicenseService.class)); - } - - @Override - public Collection<Object> createComponents(ClusterService clusterService, Clock clock, Environment environment, - ResourceWatcherService resourceWatcherService, - SecurityLicenseState securityLicenseState) { - SecurityLicensee securityLicensee = new SecurityLicensee(settings, securityLicenseState); - WatcherLicensee watcherLicensee = new WatcherLicensee(settings); - MonitoringLicensee monitoringLicensee = new MonitoringLicensee(settings); - GraphLicensee graphLicensee = new GraphLicensee(settings); - TestLicenseService licensesService = new TestLicenseService(settings, environment, resourceWatcherService, - Arrays.asList(securityLicensee, watcherLicensee, monitoringLicensee, graphLicensee)); - return Arrays.asList(securityLicensee, licensesService, watcherLicensee, monitoringLicensee, - graphLicensee, securityLicenseState); - } - - public InternalLicensing() { - super(Settings.EMPTY); - } - - @Override - public List<ActionHandler<? extends ActionRequest<?>, ? extends ActionResponse>> getActions() { - return emptyList(); - } - - @Override - public List<Class<? extends RestHandler>> getRestHandlers() { - return emptyList(); - } - } - - public static class InternalXPackPlugin extends XPackPlugin { - - public InternalXPackPlugin(Settings settings) throws IOException { - super(settings); - licensing = new InternalLicensing(); - } - } - - public static class TestLicenseService extends LicenseService { - - private final List<Licensee> licensees; - - public TestLicenseService(Settings settings, Environment env, ResourceWatcherService resourceWatcherService, - List<Licensee> licensees) { - super(settings, null, null, env, resourceWatcherService, Collections.emptyList()); - this.licensees = licensees; - enable(OperationMode.BASIC); - } - - void enable(OperationMode operationMode) { - for (Licensee licensee : licensees) { - licensee.onChange(new Licensee.Status(operationMode, true)); - } - } - - void disable(OperationMode operationMode) { - for (Licensee licensee : licensees) { - licensee.onChange(new Licensee.Status(operationMode, false)); - } - } - - @Override - protected void doStart() {} - - @Override - protected void doStop() {} - } -} diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/plugin/core/LicensingTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/plugin/core/LicensingTests.java new file mode 100644 index 00000000000..a60459d2b76 --- /dev/null +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/plugin/core/LicensingTests.java @@ -0,0 +1,222 @@ +/* + * 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.core; + +import java.util.ArrayList; +import java.util.Collection; + +import org.elasticsearch.ElasticsearchSecurityException; +import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse; +import org.elasticsearch.action.admin.cluster.stats.ClusterStatsIndices; +import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse; +import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse; +import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.client.Client; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.ResponseException; +import org.elasticsearch.client.transport.NoNodeAvailableException; +import org.elasticsearch.client.transport.TransportClient; +import org.elasticsearch.common.network.NetworkModule; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.concurrent.ThreadContext; +import org.elasticsearch.license.core.License; +import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.test.SecurityIntegTestCase; +import org.elasticsearch.test.SecuritySettingsSource; +import org.elasticsearch.transport.Transport; +import org.elasticsearch.xpack.MockNetty3Plugin; +import org.elasticsearch.xpack.XPackTransportClient; +import org.elasticsearch.xpack.security.Security; +import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken; +import org.junit.After; +import org.junit.Before; + +import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +public class LicensingTests extends SecurityIntegTestCase { + public static final String ROLES = + SecuritySettingsSource.DEFAULT_ROLE + ":\n" + + " cluster: [ all ]\n" + + " indices:\n" + + " - names: '*'\n" + + " privileges: [manage]\n" + + " - names: '/.*/'\n" + + " privileges: [write]\n" + + " - names: 'test'\n" + + " privileges: [read]\n" + + " - names: 'test1'\n" + + " privileges: [read]\n" + + "\n" + + "role_a:\n" + + " indices:\n" + + " - names: 'a'\n" + + " privileges: [all]\n" + + "\n" + + "role_b:\n" + + " indices:\n" + + " - names: 'b'\n" + + " privileges: [all]\n"; + + public static final String USERS = + SecuritySettingsSource.CONFIG_STANDARD_USER + + "user_a:{plain}passwd\n" + + "user_b:{plain}passwd\n"; + + public static final String USERS_ROLES = + SecuritySettingsSource.CONFIG_STANDARD_USER_ROLES + + "role_a:user_a,user_b\n" + + "role_b:user_b\n"; + + @Override + protected String configRoles() { + return ROLES; + } + + @Override + protected String configUsers() { + return USERS; + } + + @Override + protected String configUsersRoles() { + return USERS_ROLES; + } + + @Override + public Settings nodeSettings(int nodeOrdinal) { + return Settings.builder().put(super.nodeSettings(nodeOrdinal)) + .put(NetworkModule.HTTP_ENABLED.getKey(), true) + .build(); + } + + @Override + protected Collection<Class<? extends Plugin>> nodePlugins() { + ArrayList<Class<? extends Plugin>> plugins = new ArrayList<>(super.nodePlugins()); + plugins.add(MockNetty3Plugin.class); // for http + return plugins; + } + + @Before + public void resetLicensing() { + enableLicensing(); + } + + public void testEnableDisableBehaviour() throws Exception { + IndexResponse indexResponse = index("test", "type", jsonBuilder() + .startObject() + .field("name", "value") + .endObject()); + assertThat(indexResponse.isCreated(), is(true)); + + + indexResponse = index("test1", "type", jsonBuilder() + .startObject() + .field("name", "value1") + .endObject()); + assertThat(indexResponse.isCreated(), is(true)); + + refresh(); + + Client client = internalCluster().transportClient(); + + disableLicensing(); + + assertElasticsearchSecurityException(() -> client.admin().indices().prepareStats().get()); + assertElasticsearchSecurityException(() -> client.admin().cluster().prepareClusterStats().get()); + assertElasticsearchSecurityException(() -> client.admin().cluster().prepareHealth().get()); + assertElasticsearchSecurityException(() -> client.admin().cluster().prepareNodesStats().get()); + + enableLicensing(randomFrom(License.OperationMode.values())); + + IndicesStatsResponse indicesStatsResponse = client.admin().indices().prepareStats().get(); + assertNoFailures(indicesStatsResponse); + + ClusterStatsResponse clusterStatsNodeResponse = client.admin().cluster().prepareClusterStats().get(); + assertThat(clusterStatsNodeResponse, notNullValue()); + ClusterStatsIndices indices = clusterStatsNodeResponse.getIndicesStats(); + assertThat(indices, notNullValue()); + assertThat(indices.getIndexCount(), greaterThanOrEqualTo(2)); + + ClusterHealthResponse clusterIndexHealth = client.admin().cluster().prepareHealth().get(); + assertThat(clusterIndexHealth, notNullValue()); + + NodesStatsResponse nodeStats = client.admin().cluster().prepareNodesStats().get(); + assertThat(nodeStats, notNullValue()); + } + + public void testRestAuthenticationByLicenseType() throws Exception { + Response response = getRestClient().performRequest("GET", "/"); + // the default of the licensing tests is basic + assertThat(response.getStatusLine().getStatusCode(), is(200)); + + // generate a new license with a mode that enables auth + License.OperationMode mode = randomFrom(License.OperationMode.GOLD, License.OperationMode.TRIAL, + License.OperationMode.PLATINUM, License.OperationMode.STANDARD); + enableLicensing(mode); + ResponseException e = expectThrows(ResponseException.class, () -> getRestClient().performRequest("GET", "/")); + assertThat(e.getResponse().getStatusLine().getStatusCode(), is(401)); + } + + public void testTransportClientAuthenticationByLicenseType() throws Exception { + Settings.Builder builder = Settings.builder() + .put(internalCluster().transportClient().settings()); + // remove user info + builder.remove(Security.USER_SETTING.getKey()); + builder.remove(ThreadContext.PREFIX + "." + UsernamePasswordToken.BASIC_AUTH_HEADER); + + // basic has no auth + try (TransportClient client = new XPackTransportClient(builder.build())) { + client.addTransportAddress(internalCluster().getDataNodeInstance(Transport.class).boundAddress().publishAddress()); + assertGreenClusterState(client); + } + + // enable a license that enables security + License.OperationMode mode = randomFrom(License.OperationMode.GOLD, License.OperationMode.TRIAL, + License.OperationMode.PLATINUM, License.OperationMode.STANDARD); + enableLicensing(mode); + + try (TransportClient client = new XPackTransportClient(builder.build())) { + client.addTransportAddress(internalCluster().getDataNodeInstance(Transport.class).boundAddress().publishAddress()); + client.admin().cluster().prepareHealth().get(); + fail("should not have been able to connect to a node!"); + } catch (NoNodeAvailableException e) { + // expected + } + } + + private static void assertElasticsearchSecurityException(ThrowingRunnable runnable) { + ElasticsearchSecurityException ee = expectThrows(ElasticsearchSecurityException.class, runnable); + assertThat(ee.getHeader("es.license.expired.feature"), hasItem(Security.NAME)); + assertThat(ee.status(), is(RestStatus.FORBIDDEN)); + } + + public static void disableLicensing() { + disableLicensing(License.OperationMode.BASIC); + } + + public static void disableLicensing(License.OperationMode operationMode) { + for (XPackLicenseState licenseState : internalCluster().getInstances(XPackLicenseState.class)) { + licenseState.update(operationMode, false); + } + } + + public static void enableLicensing() { + enableLicensing(License.OperationMode.BASIC); + } + + public static void enableLicensing(License.OperationMode operationMode) { + for (XPackLicenseState licenseState : internalCluster().getInstances(XPackLicenseState.class)) { + licenseState.update(operationMode, true); + } + } +} diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/plugin/core/XPackLicenseStateTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/plugin/core/XPackLicenseStateTests.java new file mode 100644 index 00000000000..15b922b86e4 --- /dev/null +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/license/plugin/core/XPackLicenseStateTests.java @@ -0,0 +1,255 @@ +/* + * 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.core; + +import java.util.Arrays; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import org.elasticsearch.license.core.License; +import org.elasticsearch.license.core.License.OperationMode; +import org.elasticsearch.license.plugin.core.XPackLicenseState.AllowedRealmType; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.monitoring.Monitoring; +import org.elasticsearch.xpack.security.Security; + +import static org.elasticsearch.license.core.License.OperationMode.MISSING; +import static org.elasticsearch.license.core.License.OperationMode.BASIC; +import static org.elasticsearch.license.core.License.OperationMode.GOLD; +import static org.elasticsearch.license.core.License.OperationMode.PLATINUM; +import static org.elasticsearch.license.core.License.OperationMode.STANDARD; +import static org.elasticsearch.license.core.License.OperationMode.TRIAL; +import static org.hamcrest.Matchers.is; + +/** + * Unit tests for the {@link XPackLicenseState} + */ +public class XPackLicenseStateTests extends ESTestCase { + + /** Creates a license state with the given license type and active state, and checks the given method returns expected. */ + void assertAllowed(OperationMode mode, boolean active, Predicate<XPackLicenseState> predicate, boolean expected) { + XPackLicenseState licenseState = new XPackLicenseState(); + licenseState.update(mode, active); + assertEquals(expected, predicate.test(licenseState)); + } + + /** + * Checks the ack message going from the {@code from} license type to {@code to} license type. + * TODO: check the actual messages, not just the number of them! This was copied from previous license tests... + */ + void assertAckMesssages(String feature, OperationMode from, OperationMode to, int expectedMessages) { + String[] gotMessages = XPackLicenseState.ACKNOWLEDGMENT_MESSAGES.get(feature).apply(from, to); + assertEquals(expectedMessages, gotMessages.length); + } + + static <T> T randomFrom(T[] values, Predicate<T> filter) { + return randomFrom(Arrays.stream(values).filter(filter).collect(Collectors.toList())); + } + + static OperationMode randomMode() { + return randomFrom(OperationMode.values()); + } + + static OperationMode randomTrialStandardGoldOrPlatinumMode() { + return randomFrom(TRIAL, STANDARD, GOLD, PLATINUM); + } + + static OperationMode randomTrialOrPlatinumMode() { + return randomFrom(TRIAL, PLATINUM); + } + + public void testSecurityDefaults() { + XPackLicenseState licenseState = new XPackLicenseState(); + assertThat(licenseState.isAuthAllowed(), is(true)); + assertThat(licenseState.isIpFilteringAllowed(), is(true)); + assertThat(licenseState.isAuditingAllowed(), is(true)); + assertThat(licenseState.isStatsAndHealthAllowed(), is(true)); + assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(true)); + assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.ALL)); + } + + public void testSecurityBasic() { + XPackLicenseState licenseState = new XPackLicenseState(); + licenseState.update(BASIC, true); + + assertThat(licenseState.isAuthAllowed(), is(false)); + assertThat(licenseState.isIpFilteringAllowed(), is(false)); + assertThat(licenseState.isAuditingAllowed(), is(false)); + assertThat(licenseState.isStatsAndHealthAllowed(), is(true)); + assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(false)); + assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.NONE)); + } + + public void testSecurityBasicExpired() { + XPackLicenseState licenseState = new XPackLicenseState(); + licenseState.update(BASIC, false); + + assertThat(licenseState.isAuthAllowed(), is(false)); + assertThat(licenseState.isIpFilteringAllowed(), is(false)); + assertThat(licenseState.isAuditingAllowed(), is(false)); + assertThat(licenseState.isStatsAndHealthAllowed(), is(false)); + assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(false)); + assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.NONE)); + } + + public void testSecurityStandard() { + XPackLicenseState licenseState = new XPackLicenseState(); + licenseState.update(STANDARD, true); + + assertThat(licenseState.isAuthAllowed(), is(true)); + assertThat(licenseState.isIpFilteringAllowed(), is(false)); + assertThat(licenseState.isAuditingAllowed(), is(false)); + assertThat(licenseState.isStatsAndHealthAllowed(), is(true)); + assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(false)); + assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.NATIVE)); + } + + public void testSecurityStandardExpired() { + XPackLicenseState licenseState = new XPackLicenseState(); + licenseState.update(STANDARD, false); + + assertThat(licenseState.isAuthAllowed(), is(true)); + assertThat(licenseState.isIpFilteringAllowed(), is(false)); + assertThat(licenseState.isAuditingAllowed(), is(false)); + assertThat(licenseState.isStatsAndHealthAllowed(), is(false)); + assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(false)); + assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.NATIVE)); + } + + public void testSecurityGold() { + XPackLicenseState licenseState = new XPackLicenseState(); + licenseState.update(GOLD, true); + + assertThat(licenseState.isAuthAllowed(), is(true)); + assertThat(licenseState.isIpFilteringAllowed(), is(true)); + assertThat(licenseState.isAuditingAllowed(), is(true)); + assertThat(licenseState.isStatsAndHealthAllowed(), is(true)); + assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(false)); + assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.DEFAULT)); + } + + public void testSecurityGoldExpired() { + XPackLicenseState licenseState = new XPackLicenseState(); + licenseState.update(GOLD, false); + + assertThat(licenseState.isAuthAllowed(), is(true)); + assertThat(licenseState.isIpFilteringAllowed(), is(true)); + assertThat(licenseState.isAuditingAllowed(), is(true)); + assertThat(licenseState.isStatsAndHealthAllowed(), is(false)); + assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(false)); + assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.DEFAULT)); + } + + public void testSecurityPlatinum() { + XPackLicenseState licenseState = new XPackLicenseState(); + licenseState.update(PLATINUM, true); + + assertThat(licenseState.isAuthAllowed(), is(true)); + assertThat(licenseState.isIpFilteringAllowed(), is(true)); + assertThat(licenseState.isAuditingAllowed(), is(true)); + assertThat(licenseState.isStatsAndHealthAllowed(), is(true)); + assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(true)); + assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.ALL)); + } + + public void testSecurityPlatinumExpired() { + XPackLicenseState licenseState = new XPackLicenseState(); + licenseState.update(PLATINUM, false); + + assertThat(licenseState.isAuthAllowed(), is(true)); + assertThat(licenseState.isIpFilteringAllowed(), is(true)); + assertThat(licenseState.isAuditingAllowed(), is(true)); + assertThat(licenseState.isStatsAndHealthAllowed(), is(false)); + assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(true)); + assertThat(licenseState.allowedRealmType(), is(AllowedRealmType.ALL)); + } + + public void testSecurityAckBasicToNotGoldOrStandard() { + OperationMode toMode = randomFrom(OperationMode.values(), mode -> mode != GOLD && mode != STANDARD); + assertAckMesssages(Security.NAME, BASIC, toMode, 0); + } + + public void testSecurityAckAnyToTrialOrPlatinum() { + assertAckMesssages(Security.NAME, randomMode(), randomTrialOrPlatinumMode(), 0); + } + + public void testSecurityAckTrialStandardGoldOrPlatinumToBasic() { + assertAckMesssages(Security.NAME, randomTrialStandardGoldOrPlatinumMode(), BASIC, 3); + } + + public void testSecurityAckAnyToStandard() { + OperationMode from = randomFrom(BASIC, GOLD, PLATINUM, TRIAL); + assertAckMesssages(Security.NAME, from, STANDARD, 4); + } + + public void testSecurityAckBasicStandardTrialOrPlatinumToGold() { + OperationMode from = randomFrom(BASIC, PLATINUM, TRIAL, STANDARD); + assertAckMesssages(Security.NAME, from, GOLD, 2); + } + + public void testMonitoringAckBasicToAny() { + assertAckMesssages(Monitoring.NAME, BASIC, randomMode(), 0); + } + + public void testMonitoringAckAnyToTrialGoldOrPlatinum() { + assertAckMesssages(Monitoring.NAME, randomMode(), randomTrialStandardGoldOrPlatinumMode(), 0); + } + + public void testMonitoringAckNotBasicToBasic() { + OperationMode from = randomFrom(STANDARD, GOLD, PLATINUM, TRIAL); + assertAckMesssages(Monitoring.NAME, from, BASIC, 2); + } + + public void testMonitoringAllowed() { + assertAllowed(randomMode(), true, XPackLicenseState::isMonitoringAllowed, true); + assertAllowed(randomMode(), false, XPackLicenseState::isMonitoringAllowed, false); + } + + public void testMonitoringUpdateRetention() { + OperationMode mode = randomFrom(STANDARD, GOLD, PLATINUM, TRIAL); + assertAllowed(mode, true, XPackLicenseState::isUpdateRetentionAllowed, true); + assertAllowed(BASIC, true, XPackLicenseState::isUpdateRetentionAllowed, false); + assertAllowed(MISSING, false, XPackLicenseState::isUpdateRetentionAllowed, false); + } + + public void testWatcherPlatinumGoldTrial() throws Exception { + assertAllowed(randomFrom(TRIAL, GOLD, PLATINUM), true, XPackLicenseState::isWatcherAllowed, true); + } + + public void testWatcherBasicStandardLicense() throws Exception { + assertAllowed(randomFrom(BASIC, STANDARD), true, XPackLicenseState::isWatcherAllowed, false); + } + + public void testWatcherInactive() { + assertAllowed(randomFrom(BASIC, STANDARD), false, XPackLicenseState::isWatcherAllowed, false); + } + + public void testWatcherInactivePlatinumGoldTrial() throws Exception { + assertAllowed(randomFrom(TRIAL, GOLD, PLATINUM), false, XPackLicenseState::isWatcherAllowed, false); + } + + public void testGraphPlatinumTrial() throws Exception { + assertAllowed(TRIAL, true, XPackLicenseState::isGraphAllowed, true); + assertAllowed(PLATINUM, true, XPackLicenseState::isGraphAllowed, true); + } + + public void testGraphBasic() throws Exception { + assertAllowed(BASIC, true, XPackLicenseState::isGraphAllowed, false); + } + + public void testGraphStandard() throws Exception { + assertAllowed(STANDARD, true, XPackLicenseState::isGraphAllowed, false); + } + + public void testGraphInactiveBasic() { + assertAllowed(BASIC, false, XPackLicenseState::isGraphAllowed, false); + } + + public void testGraphInactivePlatinumTrial() throws Exception { + assertAllowed(TRIAL, false, XPackLicenseState::isGraphAllowed, false); + assertAllowed(PLATINUM, false, XPackLicenseState::isGraphAllowed, false); + } +} diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityFeatureSetTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityFeatureSetTests.java index 7d12adae599..bd266827d73 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityFeatureSetTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityFeatureSetTests.java @@ -8,6 +8,7 @@ package org.elasticsearch.xpack.security; import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.XPackFeatureSet; import org.elasticsearch.xpack.security.audit.AuditTrailService; @@ -41,7 +42,7 @@ import static org.mockito.Mockito.when; public class SecurityFeatureSetTests extends ESTestCase { private Settings settings; - private SecurityLicenseState licenseState; + private XPackLicenseState licenseState; private Realms realms; private NamedWriteableRegistry namedWriteableRegistry; private IPFilter ipFilter; @@ -52,7 +53,7 @@ public class SecurityFeatureSetTests extends ESTestCase { @Before public void init() throws Exception { settings = Settings.builder().put("path.home", createTempDir()).build(); - licenseState = mock(SecurityLicenseState.class); + licenseState = mock(XPackLicenseState.class); realms = mock(Realms.class); namedWriteableRegistry = mock(NamedWriteableRegistry.class); ipFilter = mock(IPFilter.class); @@ -70,7 +71,7 @@ public class SecurityFeatureSetTests extends ESTestCase { SecurityFeatureSet featureSet = new SecurityFeatureSet(settings, licenseState, realms, namedWriteableRegistry, rolesStore, ipFilter, auditTrail, cryptoService); boolean available = randomBoolean(); - when(licenseState.authenticationAndAuthorizationEnabled()).thenReturn(available); + when(licenseState.isAuthAllowed()).thenReturn(available); assertThat(featureSet.available(), is(available)); } @@ -106,7 +107,7 @@ public class SecurityFeatureSetTests extends ESTestCase { public void testUsage() throws Exception { boolean authcAuthzAvailable = randomBoolean(); - when(licenseState.authenticationAndAuthorizationEnabled()).thenReturn(authcAuthzAvailable); + when(licenseState.isAuthAllowed()).thenReturn(authcAuthzAvailable); Settings.Builder settings = Settings.builder().put(this.settings); diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityLicenseStateTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityLicenseStateTests.java deleted file mode 100644 index 1c05c4155b1..00000000000 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityLicenseStateTests.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.security; - -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.core.License.OperationMode; -import org.elasticsearch.license.plugin.core.Licensee; -import org.elasticsearch.xpack.security.SecurityLicenseState.EnabledRealmType; -import org.elasticsearch.test.ESTestCase; - -import static org.hamcrest.Matchers.is; - -/** - * Unit tests for the {@link SecurityLicenseState} - */ -public class SecurityLicenseStateTests extends ESTestCase { - - public void testDefaults() { - SecurityLicenseState licenseState = new SecurityLicenseState(); - assertThat(licenseState.authenticationAndAuthorizationEnabled(), is(true)); - assertThat(licenseState.ipFilteringEnabled(), is(true)); - assertThat(licenseState.auditingEnabled(), is(true)); - assertThat(licenseState.statsAndHealthEnabled(), is(true)); - assertThat(licenseState.documentAndFieldLevelSecurityEnabled(), is(true)); - assertThat(licenseState.enabledRealmType(), is(EnabledRealmType.ALL)); - } - - public void testBasic() { - SecurityLicenseState licenseState = new SecurityLicenseState(); - licenseState.updateStatus(new Licensee.Status(License.OperationMode.BASIC, true)); - - assertThat(licenseState.authenticationAndAuthorizationEnabled(), is(false)); - assertThat(licenseState.ipFilteringEnabled(), is(false)); - assertThat(licenseState.auditingEnabled(), is(false)); - assertThat(licenseState.statsAndHealthEnabled(), is(true)); - assertThat(licenseState.documentAndFieldLevelSecurityEnabled(), is(false)); - assertThat(licenseState.enabledRealmType(), is(EnabledRealmType.NONE)); - } - - public void testBasicExpired() { - SecurityLicenseState licenseState = new SecurityLicenseState(); - licenseState.updateStatus(new Licensee.Status(License.OperationMode.BASIC, false)); - - assertThat(licenseState.authenticationAndAuthorizationEnabled(), is(false)); - assertThat(licenseState.ipFilteringEnabled(), is(false)); - assertThat(licenseState.auditingEnabled(), is(false)); - assertThat(licenseState.statsAndHealthEnabled(), is(false)); - assertThat(licenseState.documentAndFieldLevelSecurityEnabled(), is(false)); - assertThat(licenseState.enabledRealmType(), is(EnabledRealmType.NONE)); - } - - public void testStandard() { - SecurityLicenseState licenseState = new SecurityLicenseState(); - licenseState.updateStatus(new Licensee.Status(OperationMode.STANDARD, true)); - - assertThat(licenseState.authenticationAndAuthorizationEnabled(), is(true)); - assertThat(licenseState.ipFilteringEnabled(), is(false)); - assertThat(licenseState.auditingEnabled(), is(false)); - assertThat(licenseState.statsAndHealthEnabled(), is(true)); - assertThat(licenseState.documentAndFieldLevelSecurityEnabled(), is(false)); - assertThat(licenseState.enabledRealmType(), is(EnabledRealmType.NATIVE)); - } - - public void testStandardExpired() { - SecurityLicenseState licenseState = new SecurityLicenseState(); - licenseState.updateStatus(new Licensee.Status(OperationMode.STANDARD, false)); - - assertThat(licenseState.authenticationAndAuthorizationEnabled(), is(true)); - assertThat(licenseState.ipFilteringEnabled(), is(false)); - assertThat(licenseState.auditingEnabled(), is(false)); - assertThat(licenseState.statsAndHealthEnabled(), is(false)); - assertThat(licenseState.documentAndFieldLevelSecurityEnabled(), is(false)); - assertThat(licenseState.enabledRealmType(), is(EnabledRealmType.NATIVE)); - } - - public void testGold() { - SecurityLicenseState licenseState = new SecurityLicenseState(); - licenseState.updateStatus(new Licensee.Status(License.OperationMode.GOLD, true)); - - assertThat(licenseState.authenticationAndAuthorizationEnabled(), is(true)); - assertThat(licenseState.ipFilteringEnabled(), is(true)); - assertThat(licenseState.auditingEnabled(), is(true)); - assertThat(licenseState.statsAndHealthEnabled(), is(true)); - assertThat(licenseState.documentAndFieldLevelSecurityEnabled(), is(false)); - assertThat(licenseState.enabledRealmType(), is(EnabledRealmType.DEFAULT)); - } - - public void testGoldExpired() { - SecurityLicenseState licenseState = new SecurityLicenseState(); - licenseState.updateStatus(new Licensee.Status(License.OperationMode.GOLD, false)); - - assertThat(licenseState.authenticationAndAuthorizationEnabled(), is(true)); - assertThat(licenseState.ipFilteringEnabled(), is(true)); - assertThat(licenseState.auditingEnabled(), is(true)); - assertThat(licenseState.statsAndHealthEnabled(), is(false)); - assertThat(licenseState.documentAndFieldLevelSecurityEnabled(), is(false)); - assertThat(licenseState.enabledRealmType(), is(EnabledRealmType.DEFAULT)); - } - - public void testPlatinum() { - SecurityLicenseState licenseState = new SecurityLicenseState(); - licenseState.updateStatus(new Licensee.Status(License.OperationMode.PLATINUM, true)); - - assertThat(licenseState.authenticationAndAuthorizationEnabled(), is(true)); - assertThat(licenseState.ipFilteringEnabled(), is(true)); - assertThat(licenseState.auditingEnabled(), is(true)); - assertThat(licenseState.statsAndHealthEnabled(), is(true)); - assertThat(licenseState.documentAndFieldLevelSecurityEnabled(), is(true)); - assertThat(licenseState.enabledRealmType(), is(EnabledRealmType.ALL)); - } - - public void testPlatinumExpired() { - SecurityLicenseState licenseState = new SecurityLicenseState(); - licenseState.updateStatus(new Licensee.Status(License.OperationMode.PLATINUM, false)); - - assertThat(licenseState.authenticationAndAuthorizationEnabled(), is(true)); - assertThat(licenseState.ipFilteringEnabled(), is(true)); - assertThat(licenseState.auditingEnabled(), is(true)); - assertThat(licenseState.statsAndHealthEnabled(), is(false)); - assertThat(licenseState.documentAndFieldLevelSecurityEnabled(), is(true)); - assertThat(licenseState.enabledRealmType(), is(EnabledRealmType.ALL)); - } -} diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityLicenseeTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityLicenseeTests.java deleted file mode 100644 index 34b399548f3..00000000000 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityLicenseeTests.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.security; - -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.core.License.OperationMode; -import org.elasticsearch.license.plugin.core.AbstractLicenseeTestCase; -import org.elasticsearch.license.plugin.core.Licensee.Status; - -import static org.hamcrest.Matchers.equalTo; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -/** - * Tests {@link SecurityLicensee}. - * <p> - * If you change the behavior of these tests, then it means that licensing changes for Security! - */ -public class SecurityLicenseeTests extends AbstractLicenseeTestCase { - private final SecurityLicenseState securityLicenseState = mock(SecurityLicenseState.class); - - public void testOnChangeModifiesSecurityLicenseState() { - Status status = mock(Status.class); - - SecurityLicensee licensee = new SecurityLicensee(Settings.EMPTY, securityLicenseState); - - licensee.onChange(status); - - assertSame(status, licensee.getStatus()); - - verify(securityLicenseState).updateStatus(status); - verifyNoMoreInteractions(securityLicenseState); - } - - public void testAcknowledgementMessagesFromBasicToAnyNotGoldOrStandardIsNoOp() { - assertEmptyAck(OperationMode.BASIC, - randomFrom(OperationMode.values(), mode -> mode != OperationMode.GOLD && mode != OperationMode.STANDARD), - this::buildLicensee); - } - - public void testAcknowledgementMessagesFromAnyToTrialOrPlatinumIsNoOp() { - assertEmptyAck(randomMode(), randomTrialOrPlatinumMode(), this::buildLicensee); - } - - public void testAcknowledgementMessagesFromTrialStandardGoldOrPlatinumToBasicNotesLimits() { - OperationMode from = randomTrialStandardGoldOrPlatinumMode(); - OperationMode to = OperationMode.BASIC; - - String[] messages = ackLicenseChange(from, to, this::buildLicensee); - - // leaving messages up to inspection - assertThat(fromToMessage(from, to), messages.length, equalTo(3)); - } - - public void testAcknowlegmentMessagesFromAnyToStandardNotesLimits() { - OperationMode from = randomFrom(OperationMode.BASIC, OperationMode.GOLD, OperationMode.PLATINUM, OperationMode.TRIAL); - OperationMode to = OperationMode.STANDARD; - - String[] messages = ackLicenseChange(from, to, this::buildLicensee); - - // leaving messages up to inspection - assertThat(fromToMessage(from, to), messages.length, equalTo(4)); - } - - public void testAcknowledgementMessagesFromBasicStandardTrialOrPlatinumToGoldNotesLimits() { - OperationMode from = randomFrom(OperationMode.BASIC, OperationMode.PLATINUM, OperationMode.TRIAL, OperationMode.STANDARD); - String[] messages = ackLicenseChange(from, OperationMode.GOLD, this::buildLicensee); - - // leaving messages up to inspection - assertThat(messages.length, equalTo(2)); - } - - private SecurityLicensee buildLicensee() { - return new SecurityLicensee(Settings.EMPTY, securityLicenseState); - } -} diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityPluginEnabledDisabledTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityPluginEnabledDisabledTests.java deleted file mode 100644 index a38a93d98bd..00000000000 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityPluginEnabledDisabledTests.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.security; - -import org.elasticsearch.common.network.NetworkModule; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.integration.LicensingTests; -import org.elasticsearch.test.SecurityIntegTestCase; -import org.elasticsearch.transport.Transport; -import org.elasticsearch.transport.TransportService; -import org.elasticsearch.xpack.XPackPlugin; -import org.elasticsearch.xpack.security.transport.SecurityServerTransportService; -import org.elasticsearch.xpack.security.transport.netty3.SecurityNetty3Transport; -import org.hamcrest.Matcher; -import org.junit.After; -import org.junit.BeforeClass; - -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.not; - -public class SecurityPluginEnabledDisabledTests extends SecurityIntegTestCase { - private static boolean enabled; - - @BeforeClass - public static void init() { - enabled = randomBoolean(); - } - - @After - public void cleanup() throws Exception { - // now that on a disabled license we block cluster health/stats and indices stats, we need - // to make sure that after the tests (which disable the license for testing purposes) we - // reenabled the license, so the internal cluster will be cleaned appropriately. - logger.info("cleanup: enabling licensing..."); - LicensingTests.enableLicensing(); - } - @Override - protected Class<? extends XPackPlugin> xpackPluginClass() { - return LicensingTests.InternalXPackPlugin.class; - } - - @Override - protected Settings nodeSettings(int nodeOrdinal) { - logger.info("******* security is {}", enabled ? "enabled" : "disabled"); - return Settings.builder() - .put(super.nodeSettings(nodeOrdinal)) - .put(XPackPlugin.featureEnabledSetting(Security.NAME), enabled) - .put(NetworkModule.HTTP_ENABLED.getKey(), true) - .build(); - } - - @Override - protected Settings transportClientSettings() { - return Settings.builder() - .put(super.transportClientSettings()) - .put(XPackPlugin.featureEnabledSetting(Security.NAME), enabled) - .build(); - } - - public void testTransportEnabledDisabled() throws Exception { - for (TransportService service : internalCluster().getInstances(TransportService.class)) { - Matcher<TransportService> matcher = instanceOf(SecurityServerTransportService.class); - if (!enabled) { - matcher = not(matcher); - } - assertThat(service, matcher); - } - for (Transport transport : internalCluster().getInstances(Transport.class)) { - Matcher<Transport> matcher = instanceOf(SecurityNetty3Transport.class); - if (!enabled) { - matcher = not(matcher); - } - assertThat(transport, matcher); - } - } -} diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java index 5cfe68781ac..63e83c52713 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java @@ -14,6 +14,7 @@ import java.util.Map; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.xpack.extensions.XPackExtension; @@ -52,7 +53,7 @@ public class SecurityTests extends ESTestCase { Settings settings = Settings.builder().put(testSettings) .put("path.home", createTempDir()).build(); Environment env = new Environment(settings); - Security security = new Security(settings, env); + Security security = new Security(settings, env, new XPackLicenseState()); ThreadPool threadPool = mock(ThreadPool.class); ClusterService clusterService = mock(ClusterService.class); return security.createComponents(null, threadPool, clusterService, null, Arrays.asList(extensions)); diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/VersionCompatibilityTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/VersionCompatibilityTests.java index e262b646a98..89bbe0df04d 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/VersionCompatibilityTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/VersionCompatibilityTests.java @@ -27,7 +27,7 @@ import static org.hamcrest.CoreMatchers.is; public class VersionCompatibilityTests extends ESTestCase { public void testCompatibility() { /** - * see https://github.com/elasticsearch/elasticsearch/issues/9372 {@link SecurityLicensee} + * see https://github.com/elasticsearch/elasticsearch/issues/9372 {@link org.elasticsearch.license.plugin.core.XPackLicenseState} * Once es core supports merging cluster level custom metadata (licenses in our case), the tribe node will see some license * coming from the tribe and everything will be ok. * diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilterTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilterTests.java index cd5c71dad71..7ba58060678 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilterTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/action/filter/SecurityActionFilterTests.java @@ -18,7 +18,6 @@ import org.elasticsearch.tasks.Task; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.xpack.security.SecurityContext; -import org.elasticsearch.xpack.security.SecurityLicenseState; import org.elasticsearch.xpack.security.action.SecurityActionMapper; import org.elasticsearch.xpack.security.audit.AuditTrailService; import org.elasticsearch.xpack.security.authc.Authentication; @@ -28,6 +27,7 @@ import org.elasticsearch.xpack.security.authz.AuthorizationService; import org.elasticsearch.xpack.security.user.SystemUser; import org.elasticsearch.xpack.security.user.User; import org.elasticsearch.xpack.security.crypto.CryptoService; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.junit.Before; import static org.hamcrest.Matchers.equalTo; @@ -50,7 +50,7 @@ public class SecurityActionFilterTests extends ESTestCase { private AuthorizationService authzService; private CryptoService cryptoService; private AuditTrailService auditTrail; - private SecurityLicenseState securityLicenseState; + private XPackLicenseState licenseState; private SecurityActionFilter filter; @Before @@ -59,12 +59,12 @@ public class SecurityActionFilterTests extends ESTestCase { authzService = mock(AuthorizationService.class); cryptoService = mock(CryptoService.class); auditTrail = mock(AuditTrailService.class); - securityLicenseState = mock(SecurityLicenseState.class); - when(securityLicenseState.authenticationAndAuthorizationEnabled()).thenReturn(true); - when(securityLicenseState.statsAndHealthEnabled()).thenReturn(true); + licenseState = mock(XPackLicenseState.class); + when(licenseState.isAuthAllowed()).thenReturn(true); + when(licenseState.isStatsAndHealthAllowed()).thenReturn(true); ThreadPool threadPool = mock(ThreadPool.class); when(threadPool.getThreadContext()).thenReturn(new ThreadContext(Settings.EMPTY)); - filter = new SecurityActionFilter(Settings.EMPTY, authcService, authzService, cryptoService, auditTrail, securityLicenseState, + filter = new SecurityActionFilter(Settings.EMPTY, authcService, authzService, cryptoService, auditTrail, licenseState, new SecurityActionMapper(), new HashSet<>(), threadPool, mock(SecurityContext.class)); } @@ -135,7 +135,7 @@ public class SecurityActionFilterTests extends ESTestCase { ActionListener listener = mock(ActionListener.class); ActionFilterChain chain = mock(ActionFilterChain.class); Task task = mock(Task.class); - when(securityLicenseState.authenticationAndAuthorizationEnabled()).thenReturn(false); + when(licenseState.isAuthAllowed()).thenReturn(false); filter.apply(task, "_action", request, listener, chain); verifyZeroInteractions(authcService); verifyZeroInteractions(authzService); diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/audit/AuditTrailServiceTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/audit/AuditTrailServiceTests.java index 27b225d3c42..514c29e9aa3 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/audit/AuditTrailServiceTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/audit/AuditTrailServiceTests.java @@ -7,7 +7,7 @@ package org.elasticsearch.xpack.security.audit; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.xpack.security.SecurityLicenseState; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.security.user.User; import org.elasticsearch.xpack.security.authc.AuthenticationToken; import org.elasticsearch.xpack.security.transport.filter.IPFilter; @@ -38,8 +38,8 @@ public class AuditTrailServiceTests extends ESTestCase { private AuthenticationToken token; private TransportMessage message; private RestRequest restRequest; - private SecurityLicenseState securityLicenseState; - private boolean auditingEnabled; + private XPackLicenseState licenseState; + private boolean isAuditingAllowed; @Before public void init() throws Exception { @@ -48,10 +48,10 @@ public class AuditTrailServiceTests extends ESTestCase { auditTrailsBuilder.add(mock(AuditTrail.class)); } auditTrails = unmodifiableList(auditTrailsBuilder); - securityLicenseState = mock(SecurityLicenseState.class); - service = new AuditTrailService(Settings.EMPTY, auditTrails, securityLicenseState); - auditingEnabled = randomBoolean(); - when(securityLicenseState.auditingEnabled()).thenReturn(auditingEnabled); + licenseState = mock(XPackLicenseState.class); + service = new AuditTrailService(Settings.EMPTY, auditTrails, licenseState); + isAuditingAllowed = randomBoolean(); + when(licenseState.isAuditingAllowed()).thenReturn(isAuditingAllowed); token = mock(AuthenticationToken.class); message = mock(TransportMessage.class); restRequest = mock(RestRequest.class); @@ -59,8 +59,8 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAuthenticationFailed() throws Exception { service.authenticationFailed(token, "_action", message); - verify(securityLicenseState).auditingEnabled(); - if (auditingEnabled) { + verify(licenseState).isAuditingAllowed(); + if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { verify(auditTrail).authenticationFailed(token, "_action", message); } @@ -71,8 +71,8 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAuthenticationFailedNoToken() throws Exception { service.authenticationFailed("_action", message); - verify(securityLicenseState).auditingEnabled(); - if (auditingEnabled) { + verify(licenseState).isAuditingAllowed(); + if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { verify(auditTrail).authenticationFailed("_action", message); } @@ -83,8 +83,8 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAuthenticationFailedRestNoToken() throws Exception { service.authenticationFailed(restRequest); - verify(securityLicenseState).auditingEnabled(); - if (auditingEnabled) { + verify(licenseState).isAuditingAllowed(); + if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { verify(auditTrail).authenticationFailed(restRequest); } @@ -95,8 +95,8 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAuthenticationFailedRest() throws Exception { service.authenticationFailed(token, restRequest); - verify(securityLicenseState).auditingEnabled(); - if (auditingEnabled) { + verify(licenseState).isAuditingAllowed(); + if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { verify(auditTrail).authenticationFailed(token, restRequest); } @@ -107,8 +107,8 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAuthenticationFailedRealm() throws Exception { service.authenticationFailed("_realm", token, "_action", message); - verify(securityLicenseState).auditingEnabled(); - if (auditingEnabled) { + verify(licenseState).isAuditingAllowed(); + if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { verify(auditTrail).authenticationFailed("_realm", token, "_action", message); } @@ -119,8 +119,8 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAuthenticationFailedRestRealm() throws Exception { service.authenticationFailed("_realm", token, restRequest); - verify(securityLicenseState).auditingEnabled(); - if (auditingEnabled) { + verify(licenseState).isAuditingAllowed(); + if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { verify(auditTrail).authenticationFailed("_realm", token, restRequest); } @@ -131,8 +131,8 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAnonymousAccess() throws Exception { service.anonymousAccessDenied("_action", message); - verify(securityLicenseState).auditingEnabled(); - if (auditingEnabled) { + verify(licenseState).isAuditingAllowed(); + if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { verify(auditTrail).anonymousAccessDenied("_action", message); } @@ -144,8 +144,8 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAccessGranted() throws Exception { User user = new User("_username", "r1"); service.accessGranted(user, "_action", message); - verify(securityLicenseState).auditingEnabled(); - if (auditingEnabled) { + verify(licenseState).isAuditingAllowed(); + if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { verify(auditTrail).accessGranted(user, "_action", message); } @@ -157,8 +157,8 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAccessDenied() throws Exception { User user = new User("_username", "r1"); service.accessDenied(user, "_action", message); - verify(securityLicenseState).auditingEnabled(); - if (auditingEnabled) { + verify(licenseState).isAuditingAllowed(); + if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { verify(auditTrail).accessDenied(user, "_action", message); } @@ -171,8 +171,8 @@ public class AuditTrailServiceTests extends ESTestCase { InetAddress inetAddress = InetAddress.getLoopbackAddress(); SecurityIpFilterRule rule = randomBoolean() ? SecurityIpFilterRule.ACCEPT_ALL : IPFilter.DEFAULT_PROFILE_ACCEPT_ALL; service.connectionGranted(inetAddress, "client", rule); - verify(securityLicenseState).auditingEnabled(); - if (auditingEnabled) { + verify(licenseState).isAuditingAllowed(); + if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { verify(auditTrail).connectionGranted(inetAddress, "client", rule); } @@ -185,8 +185,8 @@ public class AuditTrailServiceTests extends ESTestCase { InetAddress inetAddress = InetAddress.getLoopbackAddress(); SecurityIpFilterRule rule = new SecurityIpFilterRule(false, "_all"); service.connectionDenied(inetAddress, "client", rule); - verify(securityLicenseState).auditingEnabled(); - if (auditingEnabled) { + verify(licenseState).isAuditingAllowed(); + if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { verify(auditTrail).connectionDenied(inetAddress, "client", rule); } diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java index b53277f96b3..1a73410842d 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java @@ -16,13 +16,12 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.env.Environment; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.rest.FakeRestRequest; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportMessage; -import org.elasticsearch.xpack.security.SecurityLicenseState; -import org.elasticsearch.xpack.security.SecurityLicenseState.EnabledRealmType; import org.elasticsearch.xpack.security.audit.AuditTrailService; import org.elasticsearch.xpack.security.authc.Authentication.RealmRef; import org.elasticsearch.xpack.security.authc.AuthenticationService.Authenticator; @@ -88,11 +87,11 @@ public class AuthenticationServiceTests extends ESTestCase { .put("path.home", createTempDir()) .put("node.name", "authc_test") .build(); - SecurityLicenseState securityLicenseState = mock(SecurityLicenseState.class); - when(securityLicenseState.enabledRealmType()).thenReturn(EnabledRealmType.ALL); - when(securityLicenseState.authenticationAndAuthorizationEnabled()).thenReturn(true); - realms = new Realms(Settings.EMPTY, new Environment(settings), Collections.<String, Realm.Factory>emptyMap(), securityLicenseState, - mock(ReservedRealm.class)) { + XPackLicenseState licenseState = mock(XPackLicenseState.class); + when(licenseState.allowedRealmType()).thenReturn(XPackLicenseState.AllowedRealmType.ALL); + when(licenseState.isAuthAllowed()).thenReturn(true); + realms = new Realms(Settings.EMPTY, new Environment(settings), Collections.<String, Realm.Factory>emptyMap(), + licenseState, mock(ReservedRealm.class)) { @Override protected void doStart() { diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java index 2102a461789..81faa8cc74b 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java @@ -8,13 +8,13 @@ package org.elasticsearch.xpack.security.authc; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.env.Environment; -import org.elasticsearch.xpack.security.SecurityLicenseState.EnabledRealmType; import org.elasticsearch.xpack.security.user.User; import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm; import org.elasticsearch.xpack.security.authc.esnative.NativeRealm; import org.elasticsearch.xpack.security.authc.file.FileRealm; import org.elasticsearch.xpack.security.authc.ldap.LdapRealm; -import org.elasticsearch.xpack.security.SecurityLicenseState; +import org.elasticsearch.license.plugin.core.XPackLicenseState; +import org.elasticsearch.license.plugin.core.XPackLicenseState.AllowedRealmType; import org.elasticsearch.test.ESTestCase; import org.junit.Before; @@ -35,7 +35,7 @@ import static org.mockito.Mockito.when; public class RealmsTests extends ESTestCase { private Map<String, Realm.Factory> factories; - private SecurityLicenseState securityLicenseState; + private XPackLicenseState licenseState; private ReservedRealm reservedRealm; @Before @@ -47,10 +47,10 @@ public class RealmsTests extends ESTestCase { String name = "type_" + i; factories.put(name, config -> new DummyRealm(name, config)); } - securityLicenseState = mock(SecurityLicenseState.class); + licenseState = mock(XPackLicenseState.class); reservedRealm = mock(ReservedRealm.class); - when(securityLicenseState.authenticationAndAuthorizationEnabled()).thenReturn(true); - when(securityLicenseState.enabledRealmType()).thenReturn(EnabledRealmType.ALL); + when(licenseState.isAuthAllowed()).thenReturn(true); + when(licenseState.allowedRealmType()).thenReturn(AllowedRealmType.ALL); } public void testWithSettings() throws Exception { @@ -69,7 +69,7 @@ public class RealmsTests extends ESTestCase { } Settings settings = builder.build(); Environment env = new Environment(settings); - Realms realms = new Realms(settings, env, factories, securityLicenseState, reservedRealm); + Realms realms = new Realms(settings, env, factories, licenseState, reservedRealm); realms.start(); Iterator<Realm> iterator = realms.iterator(); @@ -98,7 +98,7 @@ public class RealmsTests extends ESTestCase { .build(); Environment env = new Environment(settings); try { - new Realms(settings, env, factories, securityLicenseState, reservedRealm).start(); + new Realms(settings, env, factories, licenseState, reservedRealm).start(); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsString("multiple [file] realms are configured")); @@ -107,7 +107,7 @@ public class RealmsTests extends ESTestCase { public void testWithEmptySettings() throws Exception { Realms realms = new Realms(Settings.EMPTY, new Environment(Settings.builder().put("path.home", createTempDir()).build()), - factories, securityLicenseState, reservedRealm); + factories, licenseState, reservedRealm); realms.start(); Iterator<Realm> iter = realms.iterator(); assertThat(iter.hasNext(), is(true)); @@ -140,7 +140,7 @@ public class RealmsTests extends ESTestCase { } Settings settings = builder.build(); Environment env = new Environment(settings); - Realms realms = new Realms(settings, env, factories, securityLicenseState, reservedRealm); + Realms realms = new Realms(settings, env, factories, licenseState, reservedRealm); realms.start(); // this is the iterator when licensed @@ -158,7 +158,7 @@ public class RealmsTests extends ESTestCase { i++; } - when(securityLicenseState.enabledRealmType()).thenReturn(EnabledRealmType.DEFAULT); + when(licenseState.allowedRealmType()).thenReturn(AllowedRealmType.DEFAULT); iter = realms.iterator(); assertThat(iter.hasNext(), is(true)); @@ -174,7 +174,7 @@ public class RealmsTests extends ESTestCase { assertThat(realm.name(), equalTo("default_" + NativeRealm.TYPE)); assertThat(iter.hasNext(), is(false)); - when(securityLicenseState.enabledRealmType()).thenReturn(EnabledRealmType.NATIVE); + when(licenseState.allowedRealmType()).thenReturn(AllowedRealmType.NATIVE); iter = realms.iterator(); assertThat(iter.hasNext(), is(true)); @@ -202,7 +202,7 @@ public class RealmsTests extends ESTestCase { .put("xpack.security.authc.realms.custom.order", "1"); Settings settings = builder.build(); Environment env = new Environment(settings); - Realms realms = new Realms(settings, env, factories, securityLicenseState, reservedRealm); + Realms realms = new Realms(settings, env, factories, licenseState, reservedRealm); realms.start(); Iterator<Realm> iter = realms.iterator(); assertThat(iter.hasNext(), is(true)); @@ -219,7 +219,7 @@ public class RealmsTests extends ESTestCase { } assertThat(types, contains("ldap", "type_0")); - when(securityLicenseState.enabledRealmType()).thenReturn(EnabledRealmType.DEFAULT); + when(licenseState.allowedRealmType()).thenReturn(AllowedRealmType.DEFAULT); iter = realms.iterator(); assertThat(iter.hasNext(), is(true)); realm = iter.next(); @@ -232,7 +232,7 @@ public class RealmsTests extends ESTestCase { } assertThat(i, is(1)); - when(securityLicenseState.enabledRealmType()).thenReturn(EnabledRealmType.NATIVE); + when(licenseState.allowedRealmType()).thenReturn(AllowedRealmType.NATIVE); iter = realms.iterator(); assertThat(iter.hasNext(), is(true)); realm = iter.next(); @@ -259,7 +259,7 @@ public class RealmsTests extends ESTestCase { .put("xpack.security.authc.realms.native.order", "1"); Settings settings = builder.build(); Environment env = new Environment(settings); - Realms realms = new Realms(settings, env, factories, securityLicenseState, reservedRealm); + Realms realms = new Realms(settings, env, factories, licenseState, reservedRealm); realms.start(); Iterator<Realm> iter = realms.iterator(); assertThat(iter.hasNext(), is(true)); @@ -273,7 +273,7 @@ public class RealmsTests extends ESTestCase { assertThat(realm.type(), is(type)); assertThat(iter.hasNext(), is(false)); - when(securityLicenseState.enabledRealmType()).thenReturn(EnabledRealmType.NATIVE); + when(licenseState.allowedRealmType()).thenReturn(AllowedRealmType.NATIVE); iter = realms.iterator(); assertThat(iter.hasNext(), is(true)); realm = iter.next(); @@ -305,7 +305,7 @@ public class RealmsTests extends ESTestCase { } Settings settings = builder.build(); Environment env = new Environment(settings); - Realms realms = new Realms(settings, env, factories, securityLicenseState, reservedRealm); + Realms realms = new Realms(settings, env, factories, licenseState, reservedRealm); realms.start(); Iterator<Realm> iterator = realms.iterator(); Realm realm = iterator.next(); @@ -343,12 +343,12 @@ public class RealmsTests extends ESTestCase { .put("xpack.security.authc.realms.realm_1.order", 0) .build(); Environment env = new Environment(settings); - Realms realms = new Realms(settings, env, factories, securityLicenseState, reservedRealm); + Realms realms = new Realms(settings, env, factories, licenseState, reservedRealm); realms.start(); assertThat(realms.iterator().hasNext(), is(true)); - when(securityLicenseState.authenticationAndAuthorizationEnabled()).thenReturn(false); + when(licenseState.isAuthAllowed()).thenReturn(false); assertThat(realms.iterator().hasNext(), is(false)); } diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperIntegrationTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperIntegrationTests.java index b2ba7b49429..51a836dad05 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperIntegrationTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperIntegrationTests.java @@ -34,8 +34,8 @@ import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.index.query.TermQueryBuilder; import org.elasticsearch.index.shard.ShardId; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.script.ScriptService; -import org.elasticsearch.xpack.security.SecurityLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.IndexSettingsModule; @@ -78,8 +78,8 @@ public class SecurityIndexSearcherWrapperIntegrationTests extends ESTestCase { } }); - SecurityLicenseState licenseState = mock(SecurityLicenseState.class); - when(licenseState.documentAndFieldLevelSecurityEnabled()).thenReturn(true); + XPackLicenseState licenseState = mock(XPackLicenseState.class); + when(licenseState.isDocumentAndFieldLevelSecurityAllowed()).thenReturn(true); SecurityIndexSearcherWrapper wrapper = new SecurityIndexSearcherWrapper(indexSettings, queryShardContext, mapperService, bitsetFilterCache, threadContext, licenseState, scriptService) { diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperUnitTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperUnitTests.java index 928c3db2ce3..3e029b98141 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperUnitTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperUnitTests.java @@ -63,7 +63,7 @@ import org.elasticsearch.script.ScriptService; import org.elasticsearch.search.aggregations.LeafBucketCollector; import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.xpack.security.authz.accesscontrol.DocumentSubsetReader.DocumentSubsetDirectoryReader; -import org.elasticsearch.xpack.security.SecurityLicenseState; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.IndexSettingsModule; import org.elasticsearch.xpack.security.user.User; @@ -104,7 +104,7 @@ public class SecurityIndexSearcherWrapperUnitTests extends ESTestCase { private ScriptService scriptService; private SecurityIndexSearcherWrapper securityIndexSearcherWrapper; private ElasticsearchDirectoryReader esIn; - private SecurityLicenseState licenseState; + private XPackLicenseState licenseState; private IndexSettings indexSettings; @Before @@ -119,8 +119,8 @@ public class SecurityIndexSearcherWrapperUnitTests extends ESTestCase { new IndicesModule(new NamedWriteableRegistry(), emptyList()).getMapperRegistry(), () -> null); ShardId shardId = new ShardId(index, 0); - licenseState = mock(SecurityLicenseState.class); - when(licenseState.documentAndFieldLevelSecurityEnabled()).thenReturn(true); + licenseState = mock(XPackLicenseState.class); + when(licenseState.isDocumentAndFieldLevelSecurityAllowed()).thenReturn(true); threadContext = new ThreadContext(Settings.EMPTY); IndexShard indexShard = mock(IndexShard.class); when(indexShard.shardId()).thenReturn(shardId); @@ -175,7 +175,7 @@ public class SecurityIndexSearcherWrapperUnitTests extends ESTestCase { } public void testWrapReaderWhenFeatureDisabled() throws Exception { - when(licenseState.documentAndFieldLevelSecurityEnabled()).thenReturn(false); + when(licenseState.isDocumentAndFieldLevelSecurityAllowed()).thenReturn(false); securityIndexSearcherWrapper = new SecurityIndexSearcherWrapper(indexSettings, null, mapperService, null, threadContext, licenseState, scriptService); DirectoryReader reader = securityIndexSearcherWrapper.wrap(esIn); diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/rest/SecurityRestFilterTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/rest/SecurityRestFilterTests.java index badc05f9d2c..c9f8d291aa6 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/rest/SecurityRestFilterTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/rest/SecurityRestFilterTests.java @@ -13,10 +13,10 @@ import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestFilterChain; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.xpack.security.authc.Authentication; -import org.elasticsearch.xpack.security.SecurityLicenseState; +import org.elasticsearch.xpack.security.authc.AuthenticationService; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.xpack.security.authc.AuthenticationService; import org.junit.Before; import static org.elasticsearch.xpack.security.support.Exceptions.authenticationError; @@ -34,7 +34,7 @@ public class SecurityRestFilterTests extends ESTestCase { private RestChannel channel; private RestFilterChain chain; private SecurityRestFilter filter; - private SecurityLicenseState licenseState; + private XPackLicenseState licenseState; @Before public void init() throws Exception { @@ -42,8 +42,8 @@ public class SecurityRestFilterTests extends ESTestCase { RestController restController = mock(RestController.class); channel = mock(RestChannel.class); chain = mock(RestFilterChain.class); - licenseState = mock(SecurityLicenseState.class); - when(licenseState.authenticationAndAuthorizationEnabled()).thenReturn(true); + licenseState = mock(XPackLicenseState.class); + when(licenseState.isAuthAllowed()).thenReturn(true); ThreadPool threadPool = mock(ThreadPool.class); when(threadPool.getThreadContext()).thenReturn(new ThreadContext(Settings.EMPTY)); filter = new SecurityRestFilter(authcService, restController, Settings.EMPTY, threadPool, licenseState); @@ -61,7 +61,7 @@ public class SecurityRestFilterTests extends ESTestCase { public void testProcessBasicLicense() throws Exception { RestRequest request = mock(RestRequest.class); - when(licenseState.authenticationAndAuthorizationEnabled()).thenReturn(false); + when(licenseState.isAuthAllowed()).thenReturn(false); filter.process(request, channel, null, chain); verify(chain).continueProcessing(request, channel, null); verifyZeroInteractions(channel, authcService); diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/TransportFilterTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/TransportFilterTests.java index f6ad400e782..2e395d5f16f 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/TransportFilterTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/TransportFilterTests.java @@ -17,7 +17,9 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.transport.MockTcpTransportPlugin; import org.elasticsearch.xpack.security.action.SecurityActionMapper; -import org.elasticsearch.xpack.security.SecurityLicenseState; +import org.elasticsearch.xpack.security.authc.AuthenticationService; +import org.elasticsearch.xpack.security.authz.AuthorizationService; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.threadpool.ThreadPool; @@ -288,8 +290,8 @@ public class TransportFilterTests extends ESIntegTestCase { AuthenticationService authcService, AuthorizationService authzService, SecurityActionMapper actionMapper, ClientTransportFilter clientTransportFilter) { super(settings, transport, threadPool, authcService, authzService, actionMapper, clientTransportFilter, - mock(SecurityLicenseState.class)); - when(licenseState.authenticationAndAuthorizationEnabled()).thenReturn(true); + mock(XPackLicenseState.class)); + when(licenseState.isAuthAllowed()).thenReturn(true); } @Override diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/filter/IPFilterTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/filter/IPFilterTests.java index fadac74c3eb..17e8fdac070 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/filter/IPFilterTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/filter/IPFilterTests.java @@ -15,7 +15,7 @@ import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.http.HttpServerTransport; import org.elasticsearch.xpack.security.audit.AuditTrail; -import org.elasticsearch.xpack.security.SecurityLicenseState; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.junit.annotations.Network; import org.elasticsearch.transport.Transport; @@ -45,7 +45,7 @@ import static org.mockito.Mockito.when; */ public class IPFilterTests extends ESTestCase { private IPFilter ipFilter; - private SecurityLicenseState licenseState; + private XPackLicenseState licenseState; private AuditTrailService auditTrail; private Transport transport; private HttpServerTransport httpTransport; @@ -53,8 +53,8 @@ public class IPFilterTests extends ESTestCase { @Before public void init() { - licenseState = mock(SecurityLicenseState.class); - when(licenseState.ipFilteringEnabled()).thenReturn(true); + licenseState = mock(XPackLicenseState.class); + when(licenseState.isIpFilteringAllowed()).thenReturn(true); auditTrail = mock(AuditTrailService.class); clusterSettings = new ClusterSettings(Settings.EMPTY, new HashSet<>(Arrays.asList( IPFilter.HTTP_FILTER_ALLOW_SETTING, @@ -218,7 +218,7 @@ public class IPFilterTests extends ESTestCase { Settings settings = Settings.builder() .put("xpack.security.transport.filter.deny", "_all") .build(); - when(licenseState.ipFilteringEnabled()).thenReturn(false); + when(licenseState.isIpFilteringAllowed()).thenReturn(false); ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); @@ -229,7 +229,7 @@ public class IPFilterTests extends ESTestCase { verifyZeroInteractions(auditTrail); // for sanity enable license and check that it is denied - when(licenseState.ipFilteringEnabled()).thenReturn(true); + when(licenseState.isIpFilteringAllowed()).thenReturn(true); ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/IPFilterNetty3UpstreamHandlerTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/IPFilterNetty3UpstreamHandlerTests.java index db81a953475..2c696d1ba4b 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/IPFilterNetty3UpstreamHandlerTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/transport/netty3/IPFilterNetty3UpstreamHandlerTests.java @@ -13,8 +13,7 @@ import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.http.HttpServerTransport; -import org.elasticsearch.xpack.security.audit.AuditTrail; -import org.elasticsearch.xpack.security.SecurityLicenseState; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.security.audit.AuditTrailService; import org.elasticsearch.xpack.security.transport.filter.IPFilter; import org.elasticsearch.test.ESTestCase; @@ -67,8 +66,8 @@ public class IPFilterNetty3UpstreamHandlerTests extends ESTestCase { IPFilter.TRANSPORT_FILTER_ALLOW_SETTING, IPFilter.TRANSPORT_FILTER_DENY_SETTING, TransportSettings.TRANSPORT_PROFILES_SETTING))); - SecurityLicenseState licenseState = mock(SecurityLicenseState.class); - when(licenseState.ipFilteringEnabled()).thenReturn(true); + XPackLicenseState licenseState = mock(XPackLicenseState.class); + when(licenseState.isIpFilteringAllowed()).thenReturn(true); AuditTrailService auditTrailService = new AuditTrailService(settings, Collections.emptyList(), licenseState); IPFilter ipFilter = new IPFilter(settings, auditTrailService, clusterSettings, licenseState); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/license/plugin/core/XPackLicenseState.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/license/plugin/core/XPackLicenseState.java new file mode 100644 index 00000000000..7e4c7a77eca --- /dev/null +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/license/plugin/core/XPackLicenseState.java @@ -0,0 +1,349 @@ +/* + * 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.core; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.BiFunction; + +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.logging.LoggerMessageFormat; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.core.License.OperationMode; +import org.elasticsearch.xpack.graph.Graph; +import org.elasticsearch.xpack.monitoring.Monitoring; +import org.elasticsearch.xpack.monitoring.MonitoringSettings; +import org.elasticsearch.xpack.security.Security; +import org.elasticsearch.xpack.watcher.Watcher; + +/** + * A holder for the current state of the license for all xpack features. + */ +public class XPackLicenseState { + + /** Messages for each feature which are printed when the license expires. */ + static final Map<String, String[]> EXPIRATION_MESSAGES; + static { + Map<String, String[]> messages = new LinkedHashMap<>(); + messages.put(Security.NAME, new String[] { + "Cluster health, cluster stats and indices stats operations are blocked", + "All data operations (read and write) continue to work" + }); + messages.put(Watcher.NAME, new String[] { + "PUT / GET watch APIs are disabled, DELETE watch API continues to work", + "Watches execute and write to the history", + "The actions of the watches don't execute" + }); + messages.put(Monitoring.NAME, new String[] { + "The agent will stop collecting cluster and indices metrics", + "The agent will stop automatically cleaning indices older than [xpack.monitoring.history.duration]" + }); + messages.put(Graph.NAME, new String[] { + "Graph explore APIs are disabled" + }); + EXPIRATION_MESSAGES = Collections.unmodifiableMap(messages); + } + + /** + * Messages for each feature which are printed when the license type changes. + * The value is a function taking the old and new license type, and returns the messages for that feature. + */ + static final Map<String, BiFunction<OperationMode, OperationMode, String[]>> ACKNOWLEDGMENT_MESSAGES; + static { + Map<String, BiFunction<OperationMode, OperationMode, String[]>> messages = new LinkedHashMap<>(); + messages.put(Security.NAME, XPackLicenseState::securityAcknowledgementMessages); + messages.put(Watcher.NAME, XPackLicenseState::watcherAcknowledgementMessages); + messages.put(Monitoring.NAME, XPackLicenseState::monitoringAcknowledgementMessages); + messages.put(Graph.NAME, XPackLicenseState::graphAcknowledgementMessages); + ACKNOWLEDGMENT_MESSAGES = Collections.unmodifiableMap(messages); + } + + private static String[] securityAcknowledgementMessages(OperationMode currentMode, OperationMode newMode) { + switch (newMode) { + case BASIC: + switch (currentMode) { + case TRIAL: + case STANDARD: + case GOLD: + case PLATINUM: + return new String[] { + "The following X-Pack security functionality will be disabled: authentication, authorization, " + + "ip filtering, and auditing. Please restart your node after applying the license.", + "Field and document level access control will be disabled.", + "Custom realms will be ignored." + }; + } + break; + case GOLD: + switch (currentMode) { + case BASIC: + case STANDARD: + // ^^ though technically it was already disabled, it's not bad to remind them + case TRIAL: + case PLATINUM: + return new String[] { + "Field and document level access control will be disabled.", + "Custom realms will be ignored." + }; + } + break; + case STANDARD: + switch (currentMode) { + case BASIC: + // ^^ though technically it was already disabled, it's not bad to remind them + case GOLD: + case PLATINUM: + case TRIAL: + return new String[] { + "Authentication will be limited to the native realms.", + "IP filtering and auditing will be disabled.", + "Field and document level access control will be disabled.", + "Custom realms will be ignored." + }; + } + } + return Strings.EMPTY_ARRAY; + } + + private static String[] watcherAcknowledgementMessages(OperationMode currentMode, OperationMode newMode) { + switch (newMode) { + case BASIC: + switch (currentMode) { + case TRIAL: + case STANDARD: + case GOLD: + case PLATINUM: + return new String[] { "Watcher will be disabled" }; + } + break; + } + return Strings.EMPTY_ARRAY; + } + + private static String[] monitoringAcknowledgementMessages(OperationMode currentMode, OperationMode newMode) { + switch (newMode) { + case BASIC: + switch (currentMode) { + case TRIAL: + case STANDARD: + case GOLD: + case PLATINUM: + return new String[] { + LoggerMessageFormat.format( + "Multi-cluster support is disabled for clusters with [{}] license. If you are\n" + + "running multiple clusters, users won't be able to access the clusters with\n" + + "[{}] licenses from within a single X-Pack Kibana instance. You will have to deploy a\n" + + "separate and dedicated X-pack Kibana instance for each [{}] cluster you wish to monitor.", + newMode, newMode, newMode), + LoggerMessageFormat.format( + "Automatic index cleanup is locked to {} days for clusters with [{}] license.", + MonitoringSettings.HISTORY_DURATION.getDefault(Settings.EMPTY).days(), newMode) + }; + } + break; + } + return Strings.EMPTY_ARRAY; + } + + private static String[] graphAcknowledgementMessages(OperationMode currentMode, OperationMode newMode) { + switch (newMode) { + case BASIC: + case STANDARD: + case GOLD: + switch (currentMode) { + case TRIAL: + case PLATINUM: + return new String[] { "Graph will be disabled" }; + } + break; + } + return Strings.EMPTY_ARRAY; + } + + /** A wrapper for the license mode and state, to allow atomically swapping. */ + private static class Status { + + /** The current "mode" of the license (ie license type). */ + final OperationMode mode; + + /** True if the license is active, or false if it is expired. */ + final boolean active; + + Status(OperationMode mode, boolean active) { + this.mode = mode; + this.active = active; + } + } + private volatile Status status = new Status(OperationMode.TRIAL, true); + + /** Updates the current state of the license, which will change what features are available. */ + void update(OperationMode mode, boolean active) { + status = new Status(mode, active); + } + + /** Return the current license type. */ + public OperationMode getOperationMode() { + return status.mode; + } + + /** Return true if the license is currently within its time boundaries, false otherwise. */ + public boolean isActive() { + return status.active; + } + + /** + * @return true if authentication and authorization should be enabled. this does not indicate what realms are available + * @see #allowedRealmType() for the enabled realms + */ + public boolean isAuthAllowed() { + OperationMode mode = status.mode; + return mode == OperationMode.STANDARD || mode == OperationMode.GOLD || mode == OperationMode.PLATINUM + || mode == OperationMode.TRIAL; + } + + /** + * @return true if IP filtering should be enabled + */ + public boolean isIpFilteringAllowed() { + OperationMode mode = status.mode; + return mode == OperationMode.GOLD || mode == OperationMode.PLATINUM || mode == OperationMode.TRIAL; + } + + /** + * @return true if auditing should be enabled + */ + public boolean isAuditingAllowed() { + OperationMode mode = status.mode; + return mode == OperationMode.GOLD || mode == OperationMode.PLATINUM || mode == OperationMode.TRIAL; + } + + /** + * Indicates whether the stats and health API calls should be allowed. If a license is expired and past the grace + * period then we deny these calls. + * + * @return true if the license allows for the stats and health APIs to be used. + */ + public boolean isStatsAndHealthAllowed() { + return status.active; + } + + /** + * Determine if Document Level Security (DLS) and Field Level Security (FLS) should be enabled. + * <p> + * DLS and FLS are only disabled when the mode is not: + * <ul> + * <li>{@link OperationMode#PLATINUM}</li> + * <li>{@link OperationMode#TRIAL}</li> + * </ul> + * Note: This does not consider the <em>state</em> of the license so that Security does not suddenly leak information! + * + * @return {@code true} to enable DLS and FLS. Otherwise {@code false}. + */ + public boolean isDocumentAndFieldLevelSecurityAllowed() { + OperationMode mode = status.mode; + return mode == OperationMode.TRIAL || mode == OperationMode.PLATINUM; + } + + /** Classes of realms that may be available based on the license type. */ + public enum AllowedRealmType { + NONE, + NATIVE, + DEFAULT, + ALL + } + + /** + * @return the type of realms that are enabled based on the license {@link OperationMode} + */ + public AllowedRealmType allowedRealmType() { + switch (status.mode) { + case PLATINUM: + case TRIAL: + return AllowedRealmType.ALL; + case GOLD: + return AllowedRealmType.DEFAULT; + case STANDARD: + return AllowedRealmType.NATIVE; + default: + return AllowedRealmType.NONE; + } + } + + /** + * Determine if Watcher is available based on the current license. + * <p> + * Watcher is available if the license is active (hasn't expired) and of one of the following types: + * <ul> + * <li>{@link OperationMode#PLATINUM}</li> + * <li>{@link OperationMode#GOLD}</li> + * <li>{@link OperationMode#TRIAL}</li> + * </ul> + * + * @return {@code true} as long as the license is valid. Otherwise {@code false}. + */ + public boolean isWatcherAllowed() { + // status is volatile, so a local variable is used for a consistent view + Status localStatus = status; + + if (localStatus.active == false) { + return false; + } + + switch (localStatus.mode) { + case TRIAL: + case GOLD: + case PLATINUM: + return true; + default: + return false; + } + } + + /** + * Monitoring is always available as long as there is a valid license + * + * @return true + */ + public boolean isMonitoringAllowed() { + return status.active; + } + + /** + * Determine if the current license allows the retention of indices to be modified. + * <p> + * Only users with a non-{@link OperationMode#BASIC} license can update the retention period. + * <p> + * Note: This does not consider the <em>state</em> of the license so that any change is remembered for when they fix their license. + * + * @return {@code true} if the user is allowed to modify the retention. Otherwise {@code false}. + */ + public boolean isUpdateRetentionAllowed() { + final OperationMode mode = status.mode; + return mode != OperationMode.BASIC && mode != OperationMode.MISSING; + } + + /** + * Determine if Graph Exploration should be enabled. + * <p> + * Exploration is only disabled when the license has expired or if the mode is not: + * <ul> + * <li>{@link OperationMode#PLATINUM}</li> + * <li>{@link OperationMode#TRIAL}</li> + * </ul> + * + * @return {@code true} as long as the license is valid. Otherwise {@code false}. + */ + public boolean isGraphAllowed() { + // status is volatile + Status localStatus = status; + OperationMode operationMode = localStatus.mode; + + boolean licensed = operationMode == OperationMode.TRIAL || operationMode == OperationMode.PLATINUM; + + return licensed && localStatus.active; + } +} diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java index 6543a8332bb..1208b6e20f4 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java @@ -30,6 +30,7 @@ import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.inject.Binder; import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.inject.multibindings.Multibinder; +import org.elasticsearch.common.inject.util.Providers; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; @@ -37,6 +38,7 @@ import org.elasticsearch.env.Environment; import org.elasticsearch.index.IndexModule; import org.elasticsearch.ingest.Processor; import org.elasticsearch.license.plugin.Licensing; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.plugins.ActionPlugin; import org.elasticsearch.plugins.IngestPlugin; import org.elasticsearch.plugins.Plugin; @@ -121,6 +123,7 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I protected boolean transportClientMode; protected final XPackExtensionsService extensionsService; + protected XPackLicenseState licenseState; protected Licensing licensing; protected Security security; protected Monitoring monitoring; @@ -132,9 +135,10 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I this.settings = settings; this.transportClientMode = transportClientMode(settings); this.env = transportClientMode ? null : new Environment(settings); + this.licenseState = new XPackLicenseState(); this.licensing = new Licensing(settings); - this.security = new Security(settings, env); + this.security = new Security(settings, env, licenseState); this.monitoring = new Monitoring(settings); this.watcher = new Watcher(settings); this.graph = new Graph(settings); @@ -171,6 +175,8 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I modules.add(new TextTemplateModule()); // Note: this only exists so LicenseService subclasses can be bound in mock tests modules.addAll(licensing.nodeModules()); + } else { + modules.add(b -> b.bind(XPackLicenseState.class).toProvider(Providers.of(null))); } return modules; } @@ -190,8 +196,7 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I final InternalClient internalClient = new InternalClient(settings, threadPool, client, security.getCryptoService()); components.add(internalClient); - components.addAll(licensing.createComponents(clusterService, getClock(), env, resourceWatcherService, - security.getSecurityLicenseState())); + components.addAll(licensing.createComponents(clusterService, getClock(), env, resourceWatcherService, licenseState)); components.addAll(security.createComponents(internalClient, threadPool, clusterService, resourceWatcherService, extensionsService.getExtensions())); diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherFeatureSet.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherFeatureSet.java index daa629cfae7..ad5aa66073b 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherFeatureSet.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherFeatureSet.java @@ -12,6 +12,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.XPackFeatureSet; import java.io.IOException; @@ -24,15 +25,15 @@ import java.util.Map; public class WatcherFeatureSet implements XPackFeatureSet { private final boolean enabled; - private final WatcherLicensee licensee; + private final XPackLicenseState licenseState; private final WatcherService watcherService; @Inject - public WatcherFeatureSet(Settings settings, @Nullable WatcherLicensee licensee, NamedWriteableRegistry namedWriteableRegistry, + public WatcherFeatureSet(Settings settings, @Nullable XPackLicenseState licenseState, NamedWriteableRegistry namedWriteableRegistry, @Nullable WatcherService watcherService) { this.watcherService = watcherService; this.enabled = Watcher.enabled(settings); - this.licensee = licensee; + this.licenseState = licenseState; namedWriteableRegistry.register(Usage.class, Usage.writeableName(Watcher.NAME), Usage::new); } @@ -48,7 +49,7 @@ public class WatcherFeatureSet implements XPackFeatureSet { @Override public boolean available() { - return licensee != null && licensee.isAvailable(); + return licenseState != null && licenseState.isWatcherAllowed(); } @Override diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherLicensee.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherLicensee.java deleted file mode 100644 index a9264f27f4e..00000000000 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherLicensee.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.watcher; - -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.core.License.OperationMode; -import org.elasticsearch.license.plugin.core.AbstractLicenseeComponent; - -public class WatcherLicensee extends AbstractLicenseeComponent { - - public static final String ID = Watcher.NAME; - - public WatcherLicensee(Settings settings) { - super(settings, ID); - } - - @Override - public String[] expirationMessages() { - return new String[] { - "PUT / GET watch APIs are disabled, DELETE watch API continues to work", - "Watches execute and write to the history", - "The actions of the watches don't execute" - }; - } - - @Override - public String[] acknowledgmentMessages(OperationMode currentMode, OperationMode newMode) { - switch (newMode) { - case BASIC: - switch (currentMode) { - case TRIAL: - case STANDARD: - case GOLD: - case PLATINUM: - return new String[] { "Watcher will be disabled" }; - } - break; - } - return Strings.EMPTY_ARRAY; - } - - /** - * Determine if Watcher is available based on the current license. - * <p> - * Watcher is available if the license is active (hasn't expired) and of one of the following types: - * <ul> - * <li>{@link OperationMode#PLATINUM}</li> - * <li>{@link OperationMode#GOLD}</li> - * <li>{@link OperationMode#TRIAL}</li> - * </ul> - * - * @return {@code true} as long as the license is valid. Otherwise {@code false}. - */ - public boolean isAvailable() { - // status is volatile, so a local variable is used for a consistent view - Status localStatus = status; - - if (localStatus.isActive() == false) { - return false; - } - - switch (localStatus.getMode()) { - case TRIAL: - case GOLD: - case PLATINUM: - return true; - default: - return false; - } - } - - public boolean isExecutingActionsAllowed() { - return isWatcherTransportActionAllowed(); - } - - public boolean isGetWatchAllowed() { - return isWatcherTransportActionAllowed(); - } - - public boolean isPutWatchAllowed() { - return isWatcherTransportActionAllowed(); - } - - - public boolean isWatcherTransportActionAllowed() { - return isAvailable(); - } - - -} diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionRegistry.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionRegistry.java index 4ef05636691..af126a8fbbb 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionRegistry.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionRegistry.java @@ -8,7 +8,7 @@ package org.elasticsearch.xpack.watcher.actions; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.xpack.watcher.WatcherLicensee; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.support.clock.Clock; import org.elasticsearch.xpack.watcher.support.validation.Validation; import org.elasticsearch.xpack.watcher.transform.TransformRegistry; @@ -25,15 +25,15 @@ public class ActionRegistry { private final Map<String, ActionFactory> parsers; private final TransformRegistry transformRegistry; private final Clock clock; - private final WatcherLicensee watcherLicensee; + private final XPackLicenseState licenseState; @Inject public ActionRegistry(Map<String, ActionFactory> parsers, TransformRegistry transformRegistry, Clock clock, - WatcherLicensee watcherLicensee) { + XPackLicenseState licenseState) { this.parsers = parsers; this.transformRegistry = transformRegistry; this.clock = clock; - this.watcherLicensee = watcherLicensee; + this.licenseState = licenseState; } ActionFactory factory(String type) { @@ -57,7 +57,7 @@ public class ActionRegistry { throw new ElasticsearchParseException("could not parse action [{}] for watch [{}]. {}", id, watchId, error); } } else if (token == XContentParser.Token.START_OBJECT && id != null) { - ActionWrapper action = ActionWrapper.parse(watchId, id, parser, this, transformRegistry, clock, watcherLicensee); + ActionWrapper action = ActionWrapper.parse(watchId, id, parser, this, transformRegistry, clock, licenseState); actions.add(action); } } diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionWrapper.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionWrapper.java index 8e71fab6e60..056ae4779fb 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionWrapper.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/ActionWrapper.java @@ -14,10 +14,10 @@ import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.watcher.actions.throttler.ActionThrottler; import org.elasticsearch.xpack.watcher.actions.throttler.Throttler; import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext; -import org.elasticsearch.xpack.watcher.WatcherLicensee; import org.elasticsearch.xpack.watcher.support.WatcherDateTimeUtils; import org.elasticsearch.xpack.support.clock.Clock; import org.elasticsearch.xpack.watcher.transform.ExecutableTransform; @@ -140,7 +140,7 @@ public class ActionWrapper implements ToXContent { static ActionWrapper parse(String watchId, String actionId, XContentParser parser, ActionRegistry actionRegistry, TransformRegistry transformRegistry, - Clock clock, WatcherLicensee watcherLicensee) throws IOException { + Clock clock, XPackLicenseState licenseState) throws IOException { assert parser.currentToken() == XContentParser.Token.START_OBJECT; @@ -178,7 +178,7 @@ public class ActionWrapper implements ToXContent { throw new ElasticsearchParseException("could not parse watch action [{}/{}]. missing action type", watchId, actionId); } - ActionThrottler throttler = new ActionThrottler(clock, throttlePeriod, watcherLicensee); + ActionThrottler throttler = new ActionThrottler(clock, throttlePeriod, licenseState); return new ActionWrapper(actionId, throttler, transform, action); } diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/throttler/ActionThrottler.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/throttler/ActionThrottler.java index 25eb9b00010..d5fb240a574 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/throttler/ActionThrottler.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/throttler/ActionThrottler.java @@ -7,8 +7,8 @@ package org.elasticsearch.xpack.watcher.actions.throttler; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext; -import org.elasticsearch.xpack.watcher.WatcherLicensee; import org.elasticsearch.xpack.support.clock.Clock; /** @@ -18,18 +18,18 @@ public class ActionThrottler implements Throttler { private static final AckThrottler ACK_THROTTLER = new AckThrottler(); - private final WatcherLicensee watcherLicensee; + private final XPackLicenseState licenseState; private final PeriodThrottler periodThrottler; private final AckThrottler ackThrottler; - public ActionThrottler(Clock clock, @Nullable TimeValue throttlePeriod, WatcherLicensee watcherLicensee) { - this(new PeriodThrottler(clock, throttlePeriod), ACK_THROTTLER, watcherLicensee); + public ActionThrottler(Clock clock, @Nullable TimeValue throttlePeriod, XPackLicenseState licenseState) { + this(new PeriodThrottler(clock, throttlePeriod), ACK_THROTTLER, licenseState); } - ActionThrottler(PeriodThrottler periodThrottler, AckThrottler ackThrottler, WatcherLicensee watcherLicensee) { + ActionThrottler(PeriodThrottler periodThrottler, AckThrottler ackThrottler, XPackLicenseState licenseState) { this.periodThrottler = periodThrottler; this.ackThrottler = ackThrottler; - this.watcherLicensee = watcherLicensee; + this.licenseState = licenseState; } public TimeValue throttlePeriod() { @@ -38,7 +38,7 @@ public class ActionThrottler implements Throttler { @Override public Result throttle(String actionId, WatchExecutionContext ctx) { - if (!watcherLicensee.isExecutingActionsAllowed()) { + if (licenseState.isWatcherAllowed() == false) { return Result.throttle("watcher license does not allow action execution"); } if (periodThrottler != null) { diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/WatcherTransportAction.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/WatcherTransportAction.java index 74dcd226922..a884e2f1068 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/WatcherTransportAction.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/WatcherTransportAction.java @@ -14,10 +14,11 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.license.plugin.core.LicenseUtils; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; -import org.elasticsearch.xpack.watcher.WatcherLicensee; +import org.elasticsearch.xpack.watcher.Watcher; import java.util.function.Supplier; @@ -27,22 +28,22 @@ import java.util.function.Supplier; public abstract class WatcherTransportAction<Request extends MasterNodeRequest<Request>, Response extends ActionResponse> extends TransportMasterNodeAction<Request, Response> { - protected final WatcherLicensee watcherLicensee; + protected final XPackLicenseState licenseState; public WatcherTransportAction(Settings settings, String actionName, TransportService transportService, ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters, - IndexNameExpressionResolver indexNameExpressionResolver, WatcherLicensee watcherLicensee, + IndexNameExpressionResolver indexNameExpressionResolver, XPackLicenseState licenseState, Supplier<Request> request) { super(settings, actionName, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver, request); - this.watcherLicensee = watcherLicensee; + this.licenseState = licenseState; } @Override protected void doExecute(Task task, Request request, ActionListener<Response> listener) { - if (watcherLicensee.isWatcherTransportActionAllowed()) { + if (licenseState.isWatcherAllowed()) { super.doExecute(task, request, listener); } else { - listener.onFailure(LicenseUtils.newComplianceException(WatcherLicensee.ID)); + listener.onFailure(LicenseUtils.newComplianceException(Watcher.NAME)); } } } diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/ack/TransportAckWatchAction.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/ack/TransportAckWatchAction.java index 5706d95c759..0ccf499a414 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/ack/TransportAckWatchAction.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/ack/TransportAckWatchAction.java @@ -15,10 +15,10 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import org.elasticsearch.xpack.watcher.WatcherService; -import org.elasticsearch.xpack.watcher.WatcherLicensee; import org.elasticsearch.xpack.watcher.transport.actions.WatcherTransportAction; import org.elasticsearch.xpack.watcher.watch.WatchStatus; import org.elasticsearch.xpack.watcher.watch.WatchStore; @@ -34,9 +34,9 @@ public class TransportAckWatchAction extends WatcherTransportAction<AckWatchRequ public TransportAckWatchAction(Settings settings, TransportService transportService, ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver, WatcherService watcherService, - WatcherLicensee watcherLicensee) { + XPackLicenseState licenseState) { super(settings, AckWatchAction.NAME, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver, - watcherLicensee, AckWatchRequest::new); + licenseState, AckWatchRequest::new); this.watcherService = watcherService; } diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/activate/TransportActivateWatchAction.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/activate/TransportActivateWatchAction.java index 930451d32da..307c2122108 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/activate/TransportActivateWatchAction.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/activate/TransportActivateWatchAction.java @@ -15,10 +15,10 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import org.elasticsearch.xpack.watcher.WatcherService; -import org.elasticsearch.xpack.watcher.WatcherLicensee; import org.elasticsearch.xpack.watcher.transport.actions.WatcherTransportAction; import org.elasticsearch.xpack.watcher.watch.WatchStatus; import org.elasticsearch.xpack.watcher.watch.WatchStore; @@ -34,9 +34,9 @@ public class TransportActivateWatchAction extends WatcherTransportAction<Activat public TransportActivateWatchAction(Settings settings, TransportService transportService, ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver, WatcherService watcherService, - WatcherLicensee watcherLicensee) { + XPackLicenseState licenseState) { super(settings, ActivateWatchAction.NAME, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver, - watcherLicensee, ActivateWatchRequest::new); + licenseState, ActivateWatchRequest::new); this.watcherService = watcherService; } diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/delete/TransportDeleteWatchAction.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/delete/TransportDeleteWatchAction.java index 74178752ec4..f90c20b9aca 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/delete/TransportDeleteWatchAction.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/delete/TransportDeleteWatchAction.java @@ -16,10 +16,10 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import org.elasticsearch.xpack.watcher.WatcherService; -import org.elasticsearch.xpack.watcher.WatcherLicensee; import org.elasticsearch.xpack.watcher.transport.actions.WatcherTransportAction; import org.elasticsearch.xpack.watcher.watch.WatchStore; @@ -34,9 +34,9 @@ public class TransportDeleteWatchAction extends WatcherTransportAction<DeleteWat public TransportDeleteWatchAction(Settings settings, TransportService transportService, ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver, WatcherService watcherService, - WatcherLicensee watcherLicensee) { + XPackLicenseState licenseState) { super(settings, DeleteWatchAction.NAME, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver, - watcherLicensee, DeleteWatchRequest::new); + licenseState, DeleteWatchRequest::new); this.watcherService = watcherService; } diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/execute/TransportExecuteWatchAction.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/execute/TransportExecuteWatchAction.java index 705f07b885c..70d4364aa50 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/execute/TransportExecuteWatchAction.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/execute/TransportExecuteWatchAction.java @@ -18,6 +18,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import org.elasticsearch.xpack.watcher.condition.always.AlwaysCondition; @@ -26,7 +27,6 @@ import org.elasticsearch.xpack.watcher.execution.ExecutionService; import org.elasticsearch.xpack.watcher.execution.ManualExecutionContext; import org.elasticsearch.xpack.watcher.history.WatchRecord; import org.elasticsearch.xpack.watcher.input.simple.SimpleInput; -import org.elasticsearch.xpack.watcher.WatcherLicensee; import org.elasticsearch.xpack.support.clock.Clock; import org.elasticsearch.xpack.watcher.support.xcontent.WatcherParams; import org.elasticsearch.xpack.watcher.transport.actions.WatcherTransportAction; @@ -58,10 +58,10 @@ public class TransportExecuteWatchAction extends WatcherTransportAction<ExecuteW public TransportExecuteWatchAction(Settings settings, TransportService transportService, ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver, ExecutionService executionService, - Clock clock, WatcherLicensee watcherLicensee, WatchStore watchStore, TriggerService triggerService, + Clock clock, XPackLicenseState licenseState, WatchStore watchStore, TriggerService triggerService, Watch.Parser watchParser) { super(settings, ExecuteWatchAction.NAME, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver, - watcherLicensee, ExecuteWatchRequest::new); + licenseState, ExecuteWatchRequest::new); this.executionService = executionService; this.watchStore = watchStore; this.clock = clock; diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/get/TransportGetWatchAction.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/get/TransportGetWatchAction.java index 224f56052f3..28c821f3484 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/get/TransportGetWatchAction.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/get/TransportGetWatchAction.java @@ -19,10 +19,11 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.license.plugin.core.LicenseUtils; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xpack.watcher.Watcher; import org.elasticsearch.xpack.watcher.WatcherService; -import org.elasticsearch.xpack.watcher.WatcherLicensee; import org.elasticsearch.xpack.watcher.support.xcontent.WatcherParams; import org.elasticsearch.xpack.watcher.transport.actions.WatcherTransportAction; import org.elasticsearch.xpack.watcher.watch.Watch; @@ -43,9 +44,9 @@ public class TransportGetWatchAction extends WatcherTransportAction<GetWatchRequ public TransportGetWatchAction(Settings settings, TransportService transportService, ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver, WatcherService watcherService, - WatcherLicensee watcherLicensee) { - super(settings, GetWatchAction.NAME, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver, - watcherLicensee, GetWatchRequest::new); + XPackLicenseState licenseState) { + super(settings, GetWatchAction.NAME, transportService, clusterService, threadPool, actionFilters, + indexNameExpressionResolver, licenseState, GetWatchRequest::new); this.watcherService = watcherService; } @@ -62,8 +63,8 @@ public class TransportGetWatchAction extends WatcherTransportAction<GetWatchRequ @Override protected void masterOperation(GetWatchRequest request, ClusterState state, ActionListener<GetWatchResponse> listener) throws ElasticsearchException { - if (!watcherLicensee.isGetWatchAllowed()) { - listener.onFailure(LicenseUtils.newComplianceException(WatcherLicensee.ID)); + if (licenseState.isWatcherAllowed() == false) { + listener.onFailure(LicenseUtils.newComplianceException(Watcher.NAME)); return; } diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/put/TransportPutWatchAction.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/put/TransportPutWatchAction.java index f7636f2cb37..0854a19c127 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/put/TransportPutWatchAction.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/put/TransportPutWatchAction.java @@ -17,10 +17,11 @@ import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.license.plugin.core.LicenseUtils; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xpack.watcher.Watcher; import org.elasticsearch.xpack.watcher.WatcherService; -import org.elasticsearch.xpack.watcher.WatcherLicensee; import org.elasticsearch.xpack.watcher.transport.actions.WatcherTransportAction; import org.elasticsearch.xpack.watcher.watch.WatchStore; @@ -34,9 +35,9 @@ public class TransportPutWatchAction extends WatcherTransportAction<PutWatchRequ public TransportPutWatchAction(Settings settings, TransportService transportService, ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver, WatcherService watcherService, - WatcherLicensee watcherLicensee) { - super(settings, PutWatchAction.NAME, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver, - watcherLicensee, PutWatchRequest::new); + XPackLicenseState licenseState) { + super(settings, PutWatchAction.NAME, transportService, clusterService, threadPool, actionFilters, + indexNameExpressionResolver, licenseState, PutWatchRequest::new); this.watcherService = watcherService; } @@ -53,8 +54,8 @@ public class TransportPutWatchAction extends WatcherTransportAction<PutWatchRequ @Override protected void masterOperation(PutWatchRequest request, ClusterState state, ActionListener<PutWatchResponse> listener) throws ElasticsearchException { - if (!watcherLicensee.isPutWatchAllowed()) { - listener.onFailure(LicenseUtils.newComplianceException(WatcherLicensee.ID)); + if (licenseState.isWatcherAllowed() == false) { + listener.onFailure(LicenseUtils.newComplianceException(Watcher.NAME)); return; } diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/service/TransportWatcherServiceAction.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/service/TransportWatcherServiceAction.java index b82e76e318a..0ef66da86ea 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/service/TransportWatcherServiceAction.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/service/TransportWatcherServiceAction.java @@ -15,10 +15,10 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import org.elasticsearch.xpack.watcher.WatcherLifeCycleService; -import org.elasticsearch.xpack.watcher.WatcherLicensee; import org.elasticsearch.xpack.watcher.transport.actions.WatcherTransportAction; /** @@ -31,9 +31,9 @@ public class TransportWatcherServiceAction extends WatcherTransportAction<Watche public TransportWatcherServiceAction(Settings settings, TransportService transportService, ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver, - WatcherLifeCycleService lifeCycleService, WatcherLicensee watcherLicensee) { + WatcherLifeCycleService lifeCycleService, XPackLicenseState licenseState) { super(settings, WatcherServiceAction.NAME, transportService, clusterService, threadPool, actionFilters, - indexNameExpressionResolver, watcherLicensee, WatcherServiceRequest::new); + indexNameExpressionResolver, licenseState, WatcherServiceRequest::new); this.lifeCycleService = lifeCycleService; } diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/stats/TransportWatcherStatsAction.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/stats/TransportWatcherStatsAction.java index a3943413afd..c606855b164 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/stats/TransportWatcherStatsAction.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/stats/TransportWatcherStatsAction.java @@ -15,13 +15,13 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import org.elasticsearch.xpack.watcher.WatcherBuild; import org.elasticsearch.xpack.watcher.WatcherLifeCycleService; import org.elasticsearch.xpack.watcher.WatcherService; import org.elasticsearch.xpack.watcher.execution.ExecutionService; -import org.elasticsearch.xpack.watcher.WatcherLicensee; import org.elasticsearch.xpack.watcher.transport.actions.WatcherTransportAction; /** @@ -37,10 +37,10 @@ public class TransportWatcherStatsAction extends WatcherTransportAction<WatcherS public TransportWatcherStatsAction(Settings settings, TransportService transportService, ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver, WatcherService watcherService, - ExecutionService executionService, WatcherLicensee watcherLicensee, + ExecutionService executionService, XPackLicenseState licenseState, WatcherLifeCycleService lifeCycleService) { super(settings, WatcherStatsAction.NAME, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver, - watcherLicensee, WatcherStatsRequest::new); + licenseState, WatcherStatsRequest::new); this.watcherService = watcherService; this.executionService = executionService; this.lifeCycleService = lifeCycleService; diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherFeatureSetTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherFeatureSetTests.java index 1736ee5997d..f12743353cb 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherFeatureSetTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherFeatureSetTests.java @@ -9,6 +9,7 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource; import org.junit.Before; @@ -31,26 +32,26 @@ import static org.mockito.Mockito.when; */ public class WatcherFeatureSetTests extends ESTestCase { - private WatcherLicensee licensee; + private XPackLicenseState licenseState; private NamedWriteableRegistry namedWriteableRegistry; private WatcherService watcherService; @Before public void init() throws Exception { - licensee = mock(WatcherLicensee.class); + licenseState = mock(XPackLicenseState.class); namedWriteableRegistry = mock(NamedWriteableRegistry.class); watcherService = mock(WatcherService.class); } public void testWritableRegistration() throws Exception { - new WatcherFeatureSet(Settings.EMPTY, licensee, namedWriteableRegistry, watcherService); + new WatcherFeatureSet(Settings.EMPTY, licenseState, namedWriteableRegistry, watcherService); verify(namedWriteableRegistry).register(eq(WatcherFeatureSet.Usage.class), eq("xpack.usage.watcher"), anyObject()); } public void testAvailable() throws Exception { - WatcherFeatureSet featureSet = new WatcherFeatureSet(Settings.EMPTY, licensee, namedWriteableRegistry, watcherService); + WatcherFeatureSet featureSet = new WatcherFeatureSet(Settings.EMPTY, licenseState, namedWriteableRegistry, watcherService); boolean available = randomBoolean(); - when(licensee.isAvailable()).thenReturn(available); + when(licenseState.isWatcherAllowed()).thenReturn(available); assertThat(featureSet.available(), is(available)); } @@ -64,7 +65,7 @@ public class WatcherFeatureSetTests extends ESTestCase { } else { settings.put("xpack.watcher.enabled", enabled); } - WatcherFeatureSet featureSet = new WatcherFeatureSet(settings.build(), licensee, namedWriteableRegistry, watcherService); + WatcherFeatureSet featureSet = new WatcherFeatureSet(settings.build(), licenseState, namedWriteableRegistry, watcherService); assertThat(featureSet.enabled(), is(enabled)); } @@ -73,7 +74,7 @@ public class WatcherFeatureSetTests extends ESTestCase { statsMap.put("foo", "bar"); when(watcherService.usageStats()).thenReturn(statsMap); - WatcherFeatureSet featureSet = new WatcherFeatureSet(Settings.EMPTY, licensee, namedWriteableRegistry, watcherService); + WatcherFeatureSet featureSet = new WatcherFeatureSet(Settings.EMPTY, licenseState, namedWriteableRegistry, watcherService); XContentBuilder builder = jsonBuilder(); featureSet.usage().toXContent(builder, ToXContent.EMPTY_PARAMS); diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/actions/throttler/WatchThrottlerTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/actions/throttler/WatchThrottlerTests.java index ca4a94a79cb..a63e9cc217b 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/actions/throttler/WatchThrottlerTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/actions/throttler/WatchThrottlerTests.java @@ -5,9 +5,9 @@ */ package org.elasticsearch.xpack.watcher.actions.throttler; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext; -import org.elasticsearch.xpack.watcher.WatcherLicensee; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; @@ -26,9 +26,9 @@ public class WatchThrottlerTests extends ESTestCase { when(periodThrottler.throttle("_action", ctx)).thenReturn(Throttler.Result.NO); Throttler.Result expectedResult = Throttler.Result.throttle("_reason"); when(ackThrottler.throttle("_action", ctx)).thenReturn(expectedResult); - WatcherLicensee watcherLicensee = mock(WatcherLicensee.class); - when(watcherLicensee.isExecutingActionsAllowed()).thenReturn(true); - ActionThrottler throttler = new ActionThrottler(periodThrottler, ackThrottler, watcherLicensee); + XPackLicenseState licenseState = mock(XPackLicenseState.class); + when(licenseState.isWatcherAllowed()).thenReturn(true); + ActionThrottler throttler = new ActionThrottler(periodThrottler, ackThrottler, licenseState); Throttler.Result result = throttler.throttle("_action", ctx); assertThat(result, notNullValue()); assertThat(result, is(expectedResult)); @@ -41,9 +41,9 @@ public class WatchThrottlerTests extends ESTestCase { Throttler.Result expectedResult = Throttler.Result.throttle("_reason"); when(periodThrottler.throttle("_action", ctx)).thenReturn(expectedResult); when(ackThrottler.throttle("_action", ctx)).thenReturn(Throttler.Result.NO); - WatcherLicensee watcherLicensee = mock(WatcherLicensee.class); - when(watcherLicensee.isExecutingActionsAllowed()).thenReturn(true); - ActionThrottler throttler = new ActionThrottler(periodThrottler, ackThrottler, watcherLicensee); + XPackLicenseState licenseState = mock(XPackLicenseState.class); + when(licenseState.isWatcherAllowed()).thenReturn(true); + ActionThrottler throttler = new ActionThrottler(periodThrottler, ackThrottler, licenseState); Throttler.Result result = throttler.throttle("_action", ctx); assertThat(result, notNullValue()); assertThat(result, is(expectedResult)); @@ -57,9 +57,9 @@ public class WatchThrottlerTests extends ESTestCase { when(periodThrottler.throttle("_action", ctx)).thenReturn(periodResult); Throttler.Result ackResult = Throttler.Result.throttle("_reason_ack"); when(ackThrottler.throttle("_action", ctx)).thenReturn(ackResult); - WatcherLicensee watcherLicensee = mock(WatcherLicensee.class); - when(watcherLicensee.isExecutingActionsAllowed()).thenReturn(true); - ActionThrottler throttler = new ActionThrottler(periodThrottler, ackThrottler, watcherLicensee); + XPackLicenseState licenseState = mock(XPackLicenseState.class); + when(licenseState.isWatcherAllowed()).thenReturn(true); + ActionThrottler throttler = new ActionThrottler(periodThrottler, ackThrottler, licenseState); Throttler.Result result = throttler.throttle("_action", ctx); assertThat(result, notNullValue()); // we always check the period first... so the result will come for the period throttler @@ -72,9 +72,9 @@ public class WatchThrottlerTests extends ESTestCase { WatchExecutionContext ctx = mock(WatchExecutionContext.class); when(periodThrottler.throttle("_action", ctx)).thenReturn(Throttler.Result.NO); when(ackThrottler.throttle("_action", ctx)).thenReturn(Throttler.Result.NO); - WatcherLicensee watcherLicensee = mock(WatcherLicensee.class); - when(watcherLicensee.isExecutingActionsAllowed()).thenReturn(true); - ActionThrottler throttler = new ActionThrottler(periodThrottler, ackThrottler, watcherLicensee); + XPackLicenseState licenseState = mock(XPackLicenseState.class); + when(licenseState.isWatcherAllowed()).thenReturn(true); + ActionThrottler throttler = new ActionThrottler(periodThrottler, ackThrottler, licenseState); Throttler.Result result = throttler.throttle("_action", ctx); assertThat(result, notNullValue()); assertThat(result, is(Throttler.Result.NO)); @@ -85,9 +85,9 @@ public class WatchThrottlerTests extends ESTestCase { WatchExecutionContext ctx = mock(WatchExecutionContext.class); Throttler.Result ackResult = mock(Throttler.Result.class); when(ackThrottler.throttle("_action", ctx)).thenReturn(ackResult); - WatcherLicensee watcherLicensee = mock(WatcherLicensee.class); - when(watcherLicensee.isExecutingActionsAllowed()).thenReturn(true); - ActionThrottler throttler = new ActionThrottler(null, ackThrottler, watcherLicensee); + XPackLicenseState licenseState = mock(XPackLicenseState.class); + when(licenseState.isWatcherAllowed()).thenReturn(true); + ActionThrottler throttler = new ActionThrottler(null, ackThrottler, licenseState); Throttler.Result result = throttler.throttle("_action", ctx); assertThat(result, notNullValue()); assertThat(result, sameInstance(ackResult)); @@ -98,9 +98,9 @@ public class WatchThrottlerTests extends ESTestCase { WatchExecutionContext ctx = mock(WatchExecutionContext.class); Throttler.Result ackResult = mock(Throttler.Result.class); when(ackThrottler.throttle("_action", ctx)).thenReturn(ackResult); - WatcherLicensee watcherLicensee = mock(WatcherLicensee.class); - when(watcherLicensee.isExecutingActionsAllowed()).thenReturn(false); - ActionThrottler throttler = new ActionThrottler(null, ackThrottler, watcherLicensee); + XPackLicenseState licenseState = mock(XPackLicenseState.class); + when(licenseState.isWatcherAllowed()).thenReturn(false); + ActionThrottler throttler = new ActionThrottler(null, ackThrottler, licenseState); Throttler.Result result = throttler.throttle("_action", ctx); assertThat(result, notNullValue()); assertThat(result.reason(), is("watcher license does not allow action execution")); diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/license/LicenseTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/license/LicenseTests.java deleted file mode 100644 index b994e6c2860..00000000000 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/license/LicenseTests.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.watcher.license; - -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.license.core.License; -import org.elasticsearch.license.plugin.core.AbstractLicenseeTestCase; -import org.elasticsearch.xpack.watcher.WatcherLicensee; - -import static org.elasticsearch.license.core.License.OperationMode.BASIC; -import static org.elasticsearch.license.core.License.OperationMode.GOLD; -import static org.elasticsearch.license.core.License.OperationMode.PLATINUM; -import static org.elasticsearch.license.core.License.OperationMode.STANDARD; -import static org.elasticsearch.license.core.License.OperationMode.TRIAL; -import static org.hamcrest.Matchers.is; - -public class LicenseTests extends AbstractLicenseeTestCase { - - private WatcherLicensee watcherLicensee; - - public void testPlatinumGoldTrialLicenseCanDoEverything() throws Exception { - initLicense(TRIAL, GOLD, PLATINUM); - assertWatcherActionsAllowed(watcherLicensee); - } - - public void testBasicStandardLicenseDisablesWatcher() throws Exception { - initLicense(BASIC, STANDARD); - assertWatcherActionsNotAllowed(watcherLicensee); - } - - public void testNoLicenseDisablesWatcher() { - initLicense(BASIC, STANDARD); - disable(watcherLicensee); - - assertWatcherActionsNotAllowed(watcherLicensee); - } - - public void testExpiredPlatinumGoldTrialLicenseDisablesWatcher() throws Exception { - initLicense(TRIAL, GOLD, PLATINUM); - disable(watcherLicensee); - - assertWatcherActionsNotAllowed(watcherLicensee); - } - - public void testUpgradingFromBasicOrStandardLicenseWorks() { - initLicense(BASIC, STANDARD); - assertWatcherActionsNotAllowed(watcherLicensee); - - setOperationMode(watcherLicensee, randomFrom(TRIAL, GOLD, PLATINUM)); - assertWatcherActionsAllowed(watcherLicensee); - } - - public void testDowngradingToBasicOrStandardLicenseWorks() { - initLicense(TRIAL, GOLD, PLATINUM); - assertWatcherActionsAllowed(watcherLicensee); - - setOperationMode(watcherLicensee, randomFrom(BASIC, STANDARD)); - assertWatcherActionsNotAllowed(watcherLicensee); - } - - public void testUpgradingExpiredLicenseWorks() { - initLicense(TRIAL, GOLD, PLATINUM); - disable(watcherLicensee); - - assertWatcherActionsNotAllowed(watcherLicensee); - - setOperationMode(watcherLicensee, randomFrom(TRIAL, GOLD, PLATINUM)); - assertWatcherActionsAllowed(watcherLicensee); - } - - private void assertWatcherActionsAllowed(WatcherLicensee watcherLicensee) { - assertThat("Expected putting a watch to be allowed", watcherLicensee.isPutWatchAllowed(), is(true)); - assertThat("Expected getting a watch to be allowed", watcherLicensee.isGetWatchAllowed(), is(true)); - assertThat("Expected watcher transport actions to be allowed", watcherLicensee.isWatcherTransportActionAllowed(), is(true)); - assertThat("Expected actions of a watch to be executed", watcherLicensee.isExecutingActionsAllowed(), is(true)); - } - - private void assertWatcherActionsNotAllowed(WatcherLicensee watcherLicensee) { - assertThat("Expected putting a watch not to be allowed", watcherLicensee.isPutWatchAllowed(), is(false)); - assertThat("Expected getting a watch not to be allowed", watcherLicensee.isGetWatchAllowed(), is(false)); - assertThat("Expected watcher transport actions not to be allowed", watcherLicensee.isWatcherTransportActionAllowed(), is(false)); - assertThat("Expected actions of a watch not to be executed", watcherLicensee.isExecutingActionsAllowed(), is(false)); - } - - private void initLicense(License.OperationMode ... allowedLicenses) { - watcherLicensee = new WatcherLicensee(Settings.EMPTY); - setOperationMode(watcherLicensee, randomFrom(allowedLicenses)); - } -} diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/AbstractWatcherIntegrationTestCase.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/AbstractWatcherIntegrationTestCase.java index d79bccbb720..fb9dc6d1b00 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/AbstractWatcherIntegrationTestCase.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/AbstractWatcherIntegrationTestCase.java @@ -22,7 +22,7 @@ import org.elasticsearch.common.util.Callback; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.index.query.QueryBuilder; -import org.elasticsearch.script.ScriptService; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.xpack.monitoring.Monitoring; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.script.MockMustacheScriptEngine; @@ -48,7 +48,6 @@ import org.elasticsearch.xpack.watcher.client.WatcherClient; import org.elasticsearch.xpack.watcher.execution.ExecutionService; import org.elasticsearch.xpack.watcher.execution.ExecutionState; import org.elasticsearch.xpack.watcher.history.HistoryStore; -import org.elasticsearch.xpack.watcher.WatcherLicensee; import org.elasticsearch.xpack.watcher.support.WatcherIndexTemplateRegistry; import org.elasticsearch.xpack.support.clock.ClockMock; import org.elasticsearch.xpack.common.http.HttpClient; @@ -357,10 +356,6 @@ public abstract class AbstractWatcherIntegrationTestCase extends ESIntegTestCase return randomBoolean() ? new XPackClient(client).watcher() : new WatcherClient(client); } - protected ScriptService scriptService() { - return internalCluster().getInstance(ScriptService.class); - } - protected HttpClient watcherHttpClient() { return internalCluster().getInstance(HttpClient.class); } @@ -369,10 +364,6 @@ public abstract class AbstractWatcherIntegrationTestCase extends ESIntegTestCase return new NoopEmailService(); } - protected WatcherLicensee licenseService() { - return getInstanceFromMaster(WatcherLicensee.class); - } - protected IndexNameExpressionResolver indexNameExpressionResolver() { return internalCluster().getInstance(IndexNameExpressionResolver.class); } @@ -541,8 +532,8 @@ public abstract class AbstractWatcherIntegrationTestCase extends ESIntegTestCase protected void ensureLicenseEnabled() throws Exception { assertBusy(() -> { - for (WatcherLicensee service : internalCluster().getInstances(WatcherLicensee.class)) { - assertThat(service.isWatcherTransportActionAllowed(), is(true)); + for (XPackLicenseState licenseState : internalCluster().getInstances(XPackLicenseState.class)) { + assertThat(licenseState.isWatcherAllowed(), is(true)); } }); } diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/watch/WatchTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/watch/WatchTests.java index e3bea2db3b3..121bcf639a7 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/watch/WatchTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/watch/WatchTests.java @@ -5,6 +5,14 @@ */ package org.elasticsearch.xpack.watcher.watch; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.logging.ESLogger; @@ -16,6 +24,7 @@ import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.index.query.MatchAllQueryBuilder; import org.elasticsearch.index.query.QueryParser; import org.elasticsearch.indices.query.IndicesQueriesRegistry; +import org.elasticsearch.license.plugin.core.XPackLicenseState; import org.elasticsearch.script.ScriptService; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.common.http.HttpClient; @@ -35,7 +44,6 @@ import org.elasticsearch.xpack.notification.email.attachment.EmailAttachmentsPar import org.elasticsearch.xpack.support.clock.Clock; import org.elasticsearch.xpack.support.clock.ClockMock; import org.elasticsearch.xpack.support.clock.SystemClock; -import org.elasticsearch.xpack.watcher.WatcherLicensee; import org.elasticsearch.xpack.watcher.actions.ActionFactory; import org.elasticsearch.xpack.watcher.actions.ActionRegistry; import org.elasticsearch.xpack.watcher.actions.ActionStatus; @@ -117,14 +125,6 @@ import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.junit.Before; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import static java.util.Collections.singleton; import static java.util.Collections.singletonMap; import static java.util.Collections.unmodifiableMap; @@ -148,7 +148,7 @@ public class WatchTests extends ESTestCase { private TextTemplateEngine templateEngine; private HtmlSanitizer htmlSanitizer; private HttpAuthRegistry authRegistry; - private WatcherLicensee watcherLicensee; + private XPackLicenseState licenseState; private ESLogger logger; private Settings settings = Settings.EMPTY; private WatcherSearchTemplateService searchTemplateService; @@ -161,7 +161,7 @@ public class WatchTests extends ESTestCase { emailService = mock(EmailService.class); templateEngine = mock(TextTemplateEngine.class); htmlSanitizer = mock(HtmlSanitizer.class); - watcherLicensee = mock(WatcherLicensee.class); + licenseState = mock(XPackLicenseState.class); authRegistry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(null))); logger = Loggers.getLogger(WatchTests.class); searchTemplateService = mock(WatcherSearchTemplateService.class); @@ -476,12 +476,12 @@ public class WatchTests extends ESTestCase { break; } } - return new ActionRegistry(unmodifiableMap(parsers), transformRegistry, SystemClock.INSTANCE, watcherLicensee); + return new ActionRegistry(unmodifiableMap(parsers), transformRegistry, SystemClock.INSTANCE, licenseState); } private ActionThrottler randomThrottler() { return new ActionThrottler(SystemClock.INSTANCE, randomBoolean() ? null : TimeValue.timeValueMinutes(randomIntBetween(3, 5)), - watcherLicensee); + licenseState); } static class ParseOnlyScheduleTriggerEngine extends ScheduleTriggerEngine {