Fix license metadata serialization

Original commit: elastic/x-pack-elasticsearch@4c838f18d4
This commit is contained in:
Igor Motov 2014-10-28 16:45:27 -04:00
parent 8d6e0fc164
commit 783970f0e7
7 changed files with 97 additions and 106 deletions

View File

@ -147,17 +147,24 @@ public class LicensesMetaData implements MetaData.Custom {
} }
if (fieldName != null) { if (fieldName != null) {
if (fieldName.equals(Fields.LICENSES)) { if (fieldName.equals(Fields.LICENSES)) {
if (parser.nextToken() == XContentParser.Token.START_ARRAY) {
while (parser.nextToken() != XContentParser.Token.END_ARRAY) { while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
if (parser.currentToken().isValue()) {
signatures.add(parser.text()); signatures.add(parser.text());
} }
} }
if (fieldName.equals(Fields.TRIAL_LICENSES)) { }
} else if (fieldName.equals(Fields.TRIAL_LICENSES)) {
if (parser.nextToken() == XContentParser.Token.START_ARRAY) {
while (parser.nextToken() != XContentParser.Token.END_ARRAY) { while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
if (parser.currentToken().isValue()) {
encodedTrialLicenses.add(parser.text()); encodedTrialLicenses.add(parser.text());
} }
} }
} }
} }
}
}
return new LicensesMetaData(signatures, encodedTrialLicenses); return new LicensesMetaData(signatures, encodedTrialLicenses);
} }
@ -167,10 +174,8 @@ public class LicensesMetaData implements MetaData.Custom {
*/ */
@Override @Override
public void toXContent(LicensesMetaData licensesMetaData, XContentBuilder builder, ToXContent.Params params) throws IOException { public void toXContent(LicensesMetaData licensesMetaData, XContentBuilder builder, ToXContent.Params params) throws IOException {
builder.startObject();
builder.array(Fields.LICENSES, licensesMetaData.signatures.toArray(new String[licensesMetaData.signatures.size()])); builder.array(Fields.LICENSES, licensesMetaData.signatures.toArray(new String[licensesMetaData.signatures.size()]));
builder.array(Fields.TRIAL_LICENSES, licensesMetaData.encodedTrialLicenses.toArray(new String [licensesMetaData.encodedTrialLicenses.size()])); builder.array(Fields.TRIAL_LICENSES, licensesMetaData.encodedTrialLicenses.toArray(new String [licensesMetaData.encodedTrialLicenses.size()]));
builder.endObject();
} }
@Override @Override

View File

@ -0,0 +1,62 @@
/*
* 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.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.ProcessedClusterStateUpdateTask;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.plugin.core.LicensesMetaData;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import java.util.concurrent.CountDownLatch;
/**
*/
public abstract class AbstractLicensesIntegrationTests extends ElasticsearchIntegrationTest {
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return ImmutableSettings.settingsBuilder()
.put("plugins.load_classpath_plugins", false)
.put("plugin.types", LicensePlugin.class.getName())
.build();
}
@Override
protected Settings transportClientSettings() {
// Plugin should be loaded on the transport client as well
return nodeSettings(0);
}
protected void wipeAllLicenses() throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
ClusterService clusterService = internalCluster().getInstance(ClusterService.class, internalCluster().getMasterName());
clusterService.submitStateUpdateTask("delete licensing metadata", new ProcessedClusterStateUpdateTask() {
@Override
public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
latch.countDown();
}
@Override
public ClusterState execute(ClusterState currentState) throws Exception {
MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData());
mdBuilder.putCustom(LicensesMetaData.TYPE, null);
return ClusterState.builder(currentState).metaData(mdBuilder).build();
}
@Override
public void onFailure(String source, @Nullable Throwable t) {
logger.error("error on metaData cleanup after test", t);
}
});
latch.await();
}
}

View File

@ -36,25 +36,11 @@ import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.notNullValue;
@ClusterScope(scope = SUITE, numDataNodes = 10) @ClusterScope(scope = SUITE, numDataNodes = 10)
public class LicenseTransportTests extends ElasticsearchIntegrationTest { public class LicenseTransportTests extends AbstractLicensesIntegrationTests {
private static String pubKeyPath = null; private static String pubKeyPath = null;
private static String priKeyPath = null; private static String priKeyPath = null;
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return ImmutableSettings.settingsBuilder()
.put("plugins.load_classpath_plugins", false)
.put("plugin.types", LicensePlugin.class.getName())
.build();
}
@Override
protected Settings transportClientSettings() {
// Plugin should be loaded on the transport client as well
return nodeSettings(0);
}
@BeforeClass @BeforeClass
public static void setup() throws IOException, URISyntaxException { public static void setup() throws IOException, URISyntaxException {
priKeyPath = Paths.get(LicenseTransportTests.class.getResource("/private.key").toURI()).toAbsolutePath().toString(); priKeyPath = Paths.get(LicenseTransportTests.class.getResource("/private.key").toURI()).toAbsolutePath().toString();

View File

@ -5,61 +5,39 @@
*/ */
package org.elasticsearch.license.plugin; package org.elasticsearch.license.plugin;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.cluster.ack.ClusterStateUpdateResponse;
import org.elasticsearch.common.base.Predicate; import org.elasticsearch.common.base.Predicate;
import org.elasticsearch.common.collect.Lists;
import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.license.AbstractLicensingTestBase;
import org.elasticsearch.license.core.ESLicense; import org.elasticsearch.license.core.ESLicense;
import org.elasticsearch.license.licensor.ESLicenseSigner; import org.elasticsearch.license.licensor.ESLicenseSigner;
import org.elasticsearch.license.plugin.action.put.PutLicenseRequest;
import org.elasticsearch.license.plugin.action.put.PutLicenseRequestBuilder;
import org.elasticsearch.license.plugin.action.put.PutLicenseResponse;
import org.elasticsearch.license.plugin.core.LicensesManagerService; import org.elasticsearch.license.plugin.core.LicensesManagerService;
import org.elasticsearch.license.plugin.core.LicensesService;
import org.elasticsearch.license.plugin.core.LicensesStatus;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.InternalTestCluster; import org.elasticsearch.test.InternalTestCluster;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static org.elasticsearch.license.AbstractLicensingTestBase.getTestPriKeyPath; import static org.elasticsearch.license.AbstractLicensingTestBase.getTestPriKeyPath;
import static org.elasticsearch.license.AbstractLicensingTestBase.getTestPubKeyPath; import static org.elasticsearch.license.AbstractLicensingTestBase.getTestPubKeyPath;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope; import static org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope.SUITE;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope.TEST; import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope.TEST;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
@ClusterScope(scope = TEST, numDataNodes = 3, numClientNodes = 0) @ClusterScope(scope = TEST, numDataNodes = 3, numClientNodes = 0)
public class LicensesPluginIntegrationTests extends ElasticsearchIntegrationTest { public class LicensesPluginIntegrationTests extends AbstractLicensesIntegrationTests {
private final int trialLicenseDurationInSeconds = 5; private final int trialLicenseDurationInSeconds = 5;
@Override @Override
protected Settings nodeSettings(int nodeOrdinal) { protected Settings nodeSettings(int nodeOrdinal) {
return ImmutableSettings.settingsBuilder() return ImmutableSettings.settingsBuilder()
.put("plugins.load_classpath_plugins", false) .put(super.nodeSettings(nodeOrdinal))
.put("test_consumer_plugin.trial_license_duration_in_seconds", trialLicenseDurationInSeconds) .put("test_consumer_plugin.trial_license_duration_in_seconds", trialLicenseDurationInSeconds)
.put("plugin.types", LicensePlugin.class.getName() + "," + TestConsumerPlugin.class.getName()) .put("plugin.types", LicensePlugin.class.getName() + "," + TestConsumerPlugin.class.getName())
.build(); .build();
} }
@Override
protected Settings transportClientSettings() {
// Plugin should be loaded on the transport client as well
return nodeSettings(0);
}
@Test @Test
public void test() throws Exception { public void test() throws Exception {
// managerService should report feature to be enabled on all data nodes // managerService should report feature to be enabled on all data nodes

View File

@ -18,8 +18,6 @@ import org.elasticsearch.license.plugin.action.get.GetLicenseRequestBuilder;
import org.elasticsearch.license.plugin.action.get.GetLicenseResponse; import org.elasticsearch.license.plugin.action.get.GetLicenseResponse;
import org.elasticsearch.license.plugin.action.put.PutLicenseRequestBuilder; import org.elasticsearch.license.plugin.action.put.PutLicenseRequestBuilder;
import org.elasticsearch.license.plugin.action.put.PutLicenseResponse; import org.elasticsearch.license.plugin.action.put.PutLicenseResponse;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -32,34 +30,42 @@ import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope.SUITE;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
@ClusterScope(scope = SUITE, numDataNodes = 0) @ClusterScope(scope = SUITE, numDataNodes = 0)
public class LicensesServiceClusterRestartTest extends ElasticsearchIntegrationTest { public class LicensesServiceClusterRestartTest extends AbstractLicensesIntegrationTests {
static String priKeyPath; static String priKeyPath;
static String pubKeyPath; static String pubKeyPath;
@Override @Override
protected Settings transportClientSettings() { protected Settings transportClientSettings() {
// Plugin should be loaded on the transport client as well return super.transportClientSettings();
return settingsBuilder().build();
} }
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return ImmutableSettings.settingsBuilder()
.put(super.nodeSettings(nodeOrdinal))
.put("gateway.type", "local")
.put("format", "json")
.build();
}
@Test @Ignore @Test
public void test() throws Exception { public void test() throws Exception {
priKeyPath = Paths.get(LicensesServiceClusterRestartTest.class.getResource("/private.key").toURI()).toAbsolutePath().toString(); priKeyPath = Paths.get(LicensesServiceClusterRestartTest.class.getResource("/private.key").toURI()).toAbsolutePath().toString();
pubKeyPath = Paths.get(LicensesServiceClusterRestartTest.class.getResource("/public.key").toURI()).toAbsolutePath().toString(); pubKeyPath = Paths.get(LicensesServiceClusterRestartTest.class.getResource("/public.key").toURI()).toAbsolutePath().toString();
logger.info("--> starting 1 nodes"); logger.info("--> starting 1 nodes");
String node1 = internalCluster().startNode(settingsBuilder()); String node1 = internalCluster().startNode();
ensureGreen(); ensureGreen();
wipeAllLicenses();
final List<ESLicense> esLicenses = putLicense(node1); final List<ESLicense> esLicenses = putLicense(node1);
final Client startNodeClient = internalCluster().startNodeClient(settingsBuilder().build()); final Client startNodeClient = internalCluster().startNodeClient(settingsBuilder().build());
//TODO: just pass node name instead //TODO: just pass node name instead
getAndCheckLicense(startNodeClient, esLicenses); getAndCheckLicense(startNodeClient, esLicenses);
logger.info("--> cluster state before full cluster restart"); logger.info("--> cluster state before full cluster restart");
ClusterState clusterState = client().admin().cluster().prepareState().get().getState(); ClusterState clusterState = clusterService().state();
logger.info("Cluster state: {}", clusterState); logger.info("Cluster state: {}", clusterState);
logger.info("--> restart all nodes"); logger.info("--> restart all nodes");

View File

@ -21,29 +21,18 @@ import static org.hamcrest.Matchers.equalTo;
/** /**
*/ */
@ElasticsearchIntegrationTest.ClusterScope(scope = TEST, numDataNodes = 10, numClientNodes = 0) @ElasticsearchIntegrationTest.ClusterScope(scope = TEST, numDataNodes = 10, numClientNodes = 0)
public class LicensesServiceNodeTests extends ElasticsearchIntegrationTest { public class LicensesServiceNodeTests extends AbstractLicensesIntegrationTests {
@Override @Override
protected Settings nodeSettings(int nodeOrdinal) { protected Settings nodeSettings(int nodeOrdinal) {
return nodeSettings();
}
private Settings nodeSettings() {
return ImmutableSettings.settingsBuilder() return ImmutableSettings.settingsBuilder()
.put("plugins.load_classpath_plugins", false) .put(super.nodeSettings(nodeOrdinal))
.put("test_consumer_plugin.trial_license_duration_in_seconds", 10) .put("test_consumer_plugin.trial_license_duration_in_seconds", 10)
.putArray("plugin.types", LicensePlugin.class.getName(), TestConsumerPlugin.class.getName()) .putArray("plugin.types", LicensePlugin.class.getName(), TestConsumerPlugin.class.getName())
.put(InternalNode.HTTP_ENABLED, true) .put(InternalNode.HTTP_ENABLED, true)
.build(); .build();
} }
@Override
protected Settings transportClientSettings() {
// Plugin should be loaded on the transport client as well
return nodeSettings();
}
@Test @Test
@TestLogging("_root:DEBUG") @TestLogging("_root:DEBUG")
public void testPluginStatus() throws Exception { public void testPluginStatus() throws Exception {

View File

@ -42,57 +42,22 @@ import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope.TEST;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
@ClusterScope(scope = TEST, numDataNodes = 10) @ClusterScope(scope = TEST, numDataNodes = 10)
public class LicensesServiceTests extends ElasticsearchIntegrationTest { public class LicensesServiceTests extends AbstractLicensesIntegrationTests {
private static String pubKeyPath = null; private static String pubKeyPath = null;
private static String priKeyPath = null; private static String priKeyPath = null;
private static String node = null; private static String node = null;
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return ImmutableSettings.settingsBuilder()
.put("plugins.load_classpath_plugins", false)
.put("plugin.types", LicensePlugin.class.getName())
.build();
}
@Override
protected Settings transportClientSettings() {
// Plugin should be loaded on the transport client as well
return nodeSettings(0);
}
@BeforeClass @BeforeClass
public static void setup() throws IOException, URISyntaxException { public static void setup() throws IOException, URISyntaxException {
priKeyPath = Paths.get(LicenseTransportTests.class.getResource("/private.key").toURI()).toAbsolutePath().toString(); priKeyPath = Paths.get(LicenseTransportTests.class.getResource("/private.key").toURI()).toAbsolutePath().toString();
pubKeyPath = Paths.get(LicenseTransportTests.class.getResource("/public.key").toURI()).toAbsolutePath().toString(); pubKeyPath = Paths.get(LicenseTransportTests.class.getResource("/public.key").toURI()).toAbsolutePath().toString();
} }
@Before @Before
public void beforeTest() throws Exception { public void beforeTest() throws Exception {
final CountDownLatch latch = new CountDownLatch(1); wipeAllLicenses();
// todo: fix with awaitBusy
masterClusterService().submitStateUpdateTask("delete licensing metadata", new ProcessedClusterStateUpdateTask() {
@Override
public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
latch.countDown();
}
@Override
public ClusterState execute(ClusterState currentState) throws Exception {
MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData());
mdBuilder.putCustom(LicensesMetaData.TYPE, null);
return ClusterState.builder(currentState).metaData(mdBuilder).build();
}
@Override
public void onFailure(String source, @Nullable Throwable t) {
logger.error("error on metaData cleanup after test", t);
}
});
latch.await();
clear(); clear();
DiscoveryNodes discoveryNodes = LicensesServiceTests.masterClusterService().state().getNodes(); DiscoveryNodes discoveryNodes = LicensesServiceTests.masterClusterService().state().getNodes();