Initial node level tests; minor cleanup

Original commit: elastic/x-pack-elasticsearch@a917460b3c
This commit is contained in:
Areek Zillur 2014-10-23 21:37:30 -04:00
parent 941a440046
commit ceaefcb2c8
4 changed files with 142 additions and 13 deletions

View File

@ -172,7 +172,7 @@ public class LicensesMetaData implements MetaData.Custom {
@Override @Override
public EnumSet<MetaData.XContentContext> context() { public EnumSet<MetaData.XContentContext> context() {
return MetaData.API_ONLY; return EnumSet.of(MetaData.XContentContext.GATEWAY);
} }

View File

@ -247,7 +247,7 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
LicensesMetaData currentLicensesMetaData = metaData.custom(LicensesMetaData.TYPE); LicensesMetaData currentLicensesMetaData = metaData.custom(LicensesMetaData.TYPE);
final LicensesWrapper licensesWrapper = LicensesWrapper.wrap(currentLicensesMetaData); final LicensesWrapper licensesWrapper = LicensesWrapper.wrap(currentLicensesMetaData);
// do not generate a trial license for a feature that already has a signed license // do not generate a trial license for a feature that already has a signed license
if (!esLicenseManager.hasLicenseForFeature(request.feature, getEffectiveLicenses())) { if (!hasLicenseForFeature(request.feature, currentLicensesMetaData)) {
licensesWrapper.addTrialLicense(generateTrialLicense(request.feature, request.duration, request.maxNodes)); licensesWrapper.addTrialLicense(generateTrialLicense(request.feature, request.duration, request.maxNodes));
} }
mdBuilder.putCustom(LicensesMetaData.TYPE, licensesWrapper.createLicensesMetaData()); mdBuilder.putCustom(LicensesMetaData.TYPE, licensesWrapper.createLicensesMetaData());
@ -275,6 +275,8 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
@Override @Override
protected void doStart() throws ElasticsearchException { protected void doStart() throws ElasticsearchException {
//Change to debug
logger.info("Started LicensesService");
if (DiscoveryNode.dataNode(settings) || DiscoveryNode.masterNode(settings)) { if (DiscoveryNode.dataNode(settings) || DiscoveryNode.masterNode(settings)) {
clusterService.add(this); clusterService.add(this);
} }
@ -287,6 +289,7 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
@Override @Override
protected void doClose() throws ElasticsearchException { protected void doClose() throws ElasticsearchException {
logger.info("Closing LicensesService");
if (notificationScheduler != null) { if (notificationScheduler != null) {
notificationScheduler.cancel(true); notificationScheduler.cancel(true);
notificationScheduler = null; notificationScheduler = null;
@ -310,6 +313,7 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
if (!pendingRegistrations.isEmpty()) { if (!pendingRegistrations.isEmpty()) {
ListenerHolder pendingRegistrationLister; ListenerHolder pendingRegistrationLister;
while ((pendingRegistrationLister = pendingRegistrations.poll()) != null) { while ((pendingRegistrationLister = pendingRegistrations.poll()) != null) {
logger.info("trying to register pending listener for " + pendingRegistrationLister.feature);
registerListener(pendingRegistrationLister); registerListener(pendingRegistrationLister);
} }
} }
@ -346,15 +350,20 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
public void register(String feature, TrialLicenseOptions trialLicenseOptions, Listener listener) { public void register(String feature, TrialLicenseOptions trialLicenseOptions, Listener listener) {
final ListenerHolder listenerHolder = new ListenerHolder(feature, trialLicenseOptions, listener); final ListenerHolder listenerHolder = new ListenerHolder(feature, trialLicenseOptions, listener);
registeredListeners.add(listenerHolder); registeredListeners.add(listenerHolder);
//if (!clusterService.state().blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK)) {
registerListener(listenerHolder); registerListener(listenerHolder);
//}
} }
/**
* Notifies new feature listener if it already has a signed license
* if new feature has a non-null trial license option, a master node request is made to generate the trial license
* if no trial license option is specified for the feature and no signed license is found,
* then notifies features to be disabled
*
* @param listenerHolder of the feature to register
*/
private void registerListener(final ListenerHolder listenerHolder) { private void registerListener(final ListenerHolder listenerHolder) {
LicensesMetaData currentMetaData = clusterService.state().metaData().custom(LicensesMetaData.TYPE); LicensesMetaData currentMetaData = clusterService.state().metaData().custom(LicensesMetaData.TYPE);
if (!esLicenseManager.hasLicenseForFeature(listenerHolder.feature, getEffectiveLicenses())) { if (!hasLicenseForFeature(listenerHolder.feature, currentMetaData)) {
// does not have actual license so generate a trial license // does not have actual license so generate a trial license
TrialLicenseOptions options = listenerHolder.trialLicenseOptions; TrialLicenseOptions options = listenerHolder.trialLicenseOptions;
if (options != null) { if (options != null) {
@ -373,7 +382,6 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
} else { } else {
// could not sent register trial license request to master // could not sent register trial license request to master
pendingRegistrations.add(listenerHolder); pendingRegistrations.add(listenerHolder);
} }
} }
} else { } else {
@ -390,15 +398,17 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
} }
} }
private boolean hasLicenseForFeature(String feature, LicensesMetaData currentLicensesMetaData) {
return esLicenseManager.hasLicenseForFeature(feature, getEffectiveLicenses(currentLicensesMetaData));
}
private String executorName() { private String executorName() {
return ThreadPool.Names.GENERIC; return ThreadPool.Names.GENERIC;
} }
public Map<String, ESLicense> getEffectiveLicenses() { public Map<String, ESLicense> getEffectiveLicenses(LicensesMetaData metaData) {
final ClusterState state = clusterService.state();
LicensesMetaData metaData = state.metaData().custom(LicensesMetaData.TYPE);
Map<String, ESLicense> map = new HashMap<>(); Map<String, ESLicense> map = new HashMap<>();
if (metaData != null) { if (metaData != null) {
Set<ESLicense> esLicenses = new HashSet<>(); Set<ESLicense> esLicenses = new HashSet<>();
for (String signature : metaData.getSignatures()) { for (String signature : metaData.getSignatures()) {
@ -473,8 +483,8 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
long offset = TimeValue.timeValueMinutes(1).getMillis(); long offset = TimeValue.timeValueMinutes(1).getMillis();
for (ListenerHolder listenerHolder : registeredListeners) { for (ListenerHolder listenerHolder : registeredListeners) {
long expiryDate = -1l; long expiryDate = -1l;
final Map<String, ESLicense> effectiveLicenses = getEffectiveLicenses(); if (hasLicenseForFeature(listenerHolder.feature, currentLicensesMetaData)) {
if (esLicenseManager.hasLicenseForFeature(listenerHolder.feature, effectiveLicenses)) { final Map<String, ESLicense> effectiveLicenses = getEffectiveLicenses(currentLicensesMetaData);
expiryDate = effectiveLicenses.get(listenerHolder.feature).expiryDate(); expiryDate = effectiveLicenses.get(listenerHolder.feature).expiryDate();
} else { } else {
final TrialLicense trialLicense = licensesWrapper.trialLicenses().getTrialLicense(listenerHolder.feature); final TrialLicense trialLicense = licensesWrapper.trialLicenses().getTrialLicense(listenerHolder.feature);

View File

@ -15,6 +15,8 @@ import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException; import java.text.ParseException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -98,6 +100,10 @@ public class TestUtils {
} }
} }
public static void isSame(Collection<ESLicense> firstLicenses, Collection<ESLicense> secondLicenses) {
isSame(new HashSet<>(firstLicenses), new HashSet<>(secondLicenses));
}
public static void isSame(Set<ESLicense> firstLicenses, Set<ESLicense> secondLicenses) { public static void isSame(Set<ESLicense> firstLicenses, Set<ESLicense> secondLicenses) {
// we do the build to make sure we weed out any expired licenses // we do the build to make sure we weed out any expired licenses

View File

@ -0,0 +1,113 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.license.plugin;
import org.elasticsearch.action.ActionFuture;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.ClusterAdminClient;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.TestUtils;
import org.elasticsearch.license.core.ESLicense;
import org.elasticsearch.license.core.ESLicenses;
import org.elasticsearch.license.plugin.action.get.GetLicenseRequestBuilder;
import org.elasticsearch.license.plugin.action.get.GetLicenseResponse;
import org.elasticsearch.license.plugin.action.put.PutLicenseRequestBuilder;
import org.elasticsearch.license.plugin.action.put.PutLicenseResponse;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Ignore;
import org.junit.Test;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope.SUITE;
import static org.hamcrest.CoreMatchers.equalTo;
@ClusterScope(scope = SUITE, numDataNodes = 0)
public class LicensesServiceClusterRestartTest extends ElasticsearchIntegrationTest {
static String priKeyPath;
static String pubKeyPath;
@Override
protected Settings transportClientSettings() {
// Plugin should be loaded on the transport client as well
return settingsBuilder().build();
}
@Test @Ignore
public void test() throws Exception {
priKeyPath = Paths.get(LicensesServiceClusterRestartTest.class.getResource("/private.key").toURI()).toAbsolutePath().toString();
pubKeyPath = Paths.get(LicensesServiceClusterRestartTest.class.getResource("/public.key").toURI()).toAbsolutePath().toString();
logger.info("--> starting 1 nodes");
String node1 = internalCluster().startNode(settingsBuilder());
ensureGreen();
final List<ESLicense> esLicenses = putLicense(node1);
final Client startNodeClient = internalCluster().startNodeClient(settingsBuilder().build());
//TODO: just pass node name instead
getAndCheckLicense(startNodeClient, esLicenses);
logger.info("--> cluster state before full cluster restart");
ClusterState clusterState = client().admin().cluster().prepareState().get().getState();
logger.info("Cluster state: {}", clusterState);
logger.info("--> restart all nodes");
internalCluster().fullRestart();
ensureYellow();
logger.info("--> cluster state after full cluster restart");
clusterState = client().admin().cluster().prepareState().get().getState();
logger.info("Cluster state: {}", clusterState);
getAndCheckLicense(internalCluster().startNodeClient(settingsBuilder().build()), esLicenses);
}
private List<ESLicense> putLicense(String node) throws Exception {
final ClusterAdminClient cluster = internalCluster().client(node).admin().cluster();
Map<String, TestUtils.FeatureAttributes> map = new HashMap<>();
TestUtils.FeatureAttributes featureAttributes =
new TestUtils.FeatureAttributes("shield", "subscription", "platinum", "foo bar Inc.", "elasticsearch", 2, "2014-12-13", "2015-12-13");
map.put(TestUtils.SHIELD, featureAttributes);
String licenseString = TestUtils.generateESLicenses(map);
String licenseOutput = TestUtils.runLicenseGenerationTool(licenseString, pubKeyPath, priKeyPath);
PutLicenseRequestBuilder putLicenseRequestBuilder = new PutLicenseRequestBuilder(cluster);
final List<ESLicense> putLicenses = ESLicenses.fromSource(licenseOutput);
assertThat(putLicenses.size(), equalTo(1));
putLicenseRequestBuilder.setLicense(putLicenses);
ensureGreen();
final ActionFuture<PutLicenseResponse> putLicenseFuture = putLicenseRequestBuilder.execute();
final PutLicenseResponse putLicenseResponse = putLicenseFuture.get();
assertTrue(putLicenseResponse.isAcknowledged());
return putLicenses;
}
private void getAndCheckLicense(Client client, List<ESLicense> license) {
final ClusterAdminClient cluster = client.admin().cluster();
final GetLicenseResponse response = new GetLicenseRequestBuilder(cluster).get();
assertThat(response.licenses().size(), equalTo(1));
TestUtils.isSame(license, response.licenses());
}
private ImmutableSettings.Builder settingsBuilder() {
return ImmutableSettings.settingsBuilder()
.put("gateway.type", "local")
.put("plugin.types", LicensePlugin.class.getName());
}
}