Marvel: Rename cluster_licenses to cluster_info and add additional stats
Closes elastic/elasticsearch#490 Original commit: elastic/x-pack-elasticsearch@6dceb5b20c
This commit is contained in:
parent
47ba724498
commit
8c6b0d03d4
|
@ -13,7 +13,7 @@ import org.elasticsearch.common.unit.TimeValue;
|
|||
import org.elasticsearch.common.util.CollectionUtils;
|
||||
import org.elasticsearch.common.util.concurrent.EsExecutors;
|
||||
import org.elasticsearch.marvel.agent.collector.Collector;
|
||||
import org.elasticsearch.marvel.agent.collector.licenses.LicensesCollector;
|
||||
import org.elasticsearch.marvel.agent.collector.cluster.ClusterInfoCollector;
|
||||
import org.elasticsearch.marvel.agent.exporter.Exporter;
|
||||
import org.elasticsearch.marvel.agent.exporter.MarvelDoc;
|
||||
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
|
||||
|
@ -58,7 +58,7 @@ public class AgentService extends AbstractLifecycleComponent<AgentService> imple
|
|||
for (Collector collector : collectors) {
|
||||
if (Regex.simpleMatch(filters, collector.name().toLowerCase(Locale.ROOT))) {
|
||||
list.add(collector);
|
||||
} else if (collector instanceof LicensesCollector) {
|
||||
} else if (collector instanceof ClusterInfoCollector) {
|
||||
list.add(collector);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,12 +7,12 @@ package org.elasticsearch.marvel.agent.collector;
|
|||
|
||||
import org.elasticsearch.common.inject.AbstractModule;
|
||||
import org.elasticsearch.common.inject.multibindings.Multibinder;
|
||||
import org.elasticsearch.marvel.agent.collector.cluster.ClusterInfoCollector;
|
||||
import org.elasticsearch.marvel.agent.collector.cluster.ClusterStateCollector;
|
||||
import org.elasticsearch.marvel.agent.collector.cluster.ClusterStatsCollector;
|
||||
import org.elasticsearch.marvel.agent.collector.indices.IndexRecoveryCollector;
|
||||
import org.elasticsearch.marvel.agent.collector.indices.IndexStatsCollector;
|
||||
import org.elasticsearch.marvel.agent.collector.indices.IndicesStatsCollector;
|
||||
import org.elasticsearch.marvel.agent.collector.licenses.LicensesCollector;
|
||||
import org.elasticsearch.marvel.agent.collector.node.NodeStatsCollector;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
@ -24,7 +24,7 @@ public class CollectorModule extends AbstractModule {
|
|||
|
||||
public CollectorModule() {
|
||||
// Registers default collectors
|
||||
registerCollector(LicensesCollector.class);
|
||||
registerCollector(ClusterInfoCollector.class);
|
||||
registerCollector(IndicesStatsCollector.class);
|
||||
registerCollector(IndexStatsCollector.class);
|
||||
registerCollector(ClusterStatsCollector.class);
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
* 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.marvel.agent.collector.licenses;
|
||||
package org.elasticsearch.marvel.agent.collector.cluster;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.cluster.ClusterService;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
|
@ -22,26 +24,28 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Collector for registered licenses.
|
||||
* Collector for registered licenses and additional cluster information.
|
||||
* <p/>
|
||||
* This collector runs on the master node and collect data about all
|
||||
* known licenses that are currently registered. Each license is
|
||||
* collected as a {@link LicensesMarvelDoc} document.
|
||||
* known licenses that are currently registered. It also ships some stats
|
||||
* about the cluster (to be used in Phone Home feature).
|
||||
*/
|
||||
public class LicensesCollector extends AbstractCollector<LicensesMarvelDoc> {
|
||||
public class ClusterInfoCollector extends AbstractCollector<ClusterInfoMarvelDoc> {
|
||||
|
||||
public static final String NAME = "licenses-collector";
|
||||
public static final String TYPE = "cluster_licenses";
|
||||
public static final String NAME = "cluster-info-collector";
|
||||
public static final String TYPE = "cluster_info";
|
||||
|
||||
private final ClusterName clusterName;
|
||||
private final LicenseService licenseService;
|
||||
private final Client client;
|
||||
|
||||
@Inject
|
||||
public LicensesCollector(Settings settings, ClusterService clusterService, MarvelSettings marvelSettings, LicenseService licenseService,
|
||||
ClusterName clusterName) {
|
||||
public ClusterInfoCollector(Settings settings, ClusterService clusterService, MarvelSettings marvelSettings, LicenseService licenseService,
|
||||
ClusterName clusterName, Client client) {
|
||||
super(settings, NAME, clusterService, marvelSettings, licenseService);
|
||||
this.clusterName = clusterName;
|
||||
this.licenseService = licenseService;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -54,12 +58,15 @@ public class LicensesCollector extends AbstractCollector<LicensesMarvelDoc> {
|
|||
protected Collection<MarvelDoc> doCollect() throws Exception {
|
||||
List<MarvelDoc> results = new ArrayList<>(1);
|
||||
|
||||
// Retrieves all licenses
|
||||
List<License> licenses = licenseService.licenses();
|
||||
if (licenses != null) {
|
||||
String clusterUUID = clusterUUID();
|
||||
results.add(new LicensesMarvelDoc(MarvelSettings.MARVEL_DATA_INDEX_NAME, TYPE, clusterUUID, clusterUUID, System.currentTimeMillis(),
|
||||
clusterName.value(), Version.CURRENT.toString(), licenses));
|
||||
}
|
||||
|
||||
// Retrieves additional cluster stats
|
||||
ClusterStatsResponse clusterStats = client.admin().cluster().prepareClusterStats().get(marvelSettings.clusterStatsTimeout());
|
||||
|
||||
String clusterUUID = clusterUUID();
|
||||
results.add(new ClusterInfoMarvelDoc(MarvelSettings.MARVEL_DATA_INDEX_NAME, TYPE, clusterUUID, clusterUUID, System.currentTimeMillis(),
|
||||
clusterName.value(), Version.CURRENT.toString(), licenses, clusterStats));
|
||||
return Collections.unmodifiableCollection(results);
|
||||
}
|
||||
}
|
|
@ -3,25 +3,28 @@
|
|||
* 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.marvel.agent.collector.licenses;
|
||||
package org.elasticsearch.marvel.agent.collector.cluster;
|
||||
|
||||
import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse;
|
||||
import org.elasticsearch.license.core.License;
|
||||
import org.elasticsearch.marvel.agent.exporter.MarvelDoc;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LicensesMarvelDoc extends MarvelDoc {
|
||||
public class ClusterInfoMarvelDoc extends MarvelDoc {
|
||||
|
||||
private final String clusterName;
|
||||
private final String version;
|
||||
private final List<License> licenses;
|
||||
private final ClusterStatsResponse clusterStats;
|
||||
|
||||
LicensesMarvelDoc(String index, String type, String id, String clusterUUID, long timestamp,
|
||||
String clusterName, String version, List<License> licenses) {
|
||||
ClusterInfoMarvelDoc(String index, String type, String id, String clusterUUID, long timestamp,
|
||||
String clusterName, String version, List<License> licenses, ClusterStatsResponse clusterStats) {
|
||||
super(index, type, id, clusterUUID, timestamp);
|
||||
this.clusterName = clusterName;
|
||||
this.version = version;
|
||||
this.licenses = licenses;
|
||||
this.clusterStats = clusterStats;
|
||||
}
|
||||
|
||||
public String getClusterName() {
|
||||
|
@ -36,4 +39,7 @@ public class LicensesMarvelDoc extends MarvelDoc {
|
|||
return licenses;
|
||||
}
|
||||
|
||||
public ClusterStatsResponse getClusterStats() {
|
||||
return clusterStats;
|
||||
}
|
||||
}
|
|
@ -7,19 +7,19 @@ package org.elasticsearch.marvel.agent.renderer;
|
|||
|
||||
import org.elasticsearch.common.inject.AbstractModule;
|
||||
import org.elasticsearch.common.inject.multibindings.MapBinder;
|
||||
import org.elasticsearch.marvel.agent.collector.cluster.ClusterInfoCollector;
|
||||
import org.elasticsearch.marvel.agent.collector.cluster.ClusterStateCollector;
|
||||
import org.elasticsearch.marvel.agent.collector.cluster.ClusterStatsCollector;
|
||||
import org.elasticsearch.marvel.agent.collector.indices.IndexRecoveryCollector;
|
||||
import org.elasticsearch.marvel.agent.collector.indices.IndexStatsCollector;
|
||||
import org.elasticsearch.marvel.agent.collector.indices.IndicesStatsCollector;
|
||||
import org.elasticsearch.marvel.agent.collector.licenses.LicensesCollector;
|
||||
import org.elasticsearch.marvel.agent.collector.node.NodeStatsCollector;
|
||||
import org.elasticsearch.marvel.agent.renderer.cluster.ClusterInfoRenderer;
|
||||
import org.elasticsearch.marvel.agent.renderer.cluster.ClusterStateRenderer;
|
||||
import org.elasticsearch.marvel.agent.renderer.cluster.ClusterStatsRenderer;
|
||||
import org.elasticsearch.marvel.agent.renderer.indices.IndexRecoveryRenderer;
|
||||
import org.elasticsearch.marvel.agent.renderer.indices.IndexStatsRenderer;
|
||||
import org.elasticsearch.marvel.agent.renderer.indices.IndicesStatsRenderer;
|
||||
import org.elasticsearch.marvel.agent.renderer.licenses.LicensesRenderer;
|
||||
import org.elasticsearch.marvel.agent.renderer.node.NodeStatsRenderer;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -38,8 +38,8 @@ public class RendererModule extends AbstractModule {
|
|||
MapBinder<String, Renderer> mbinder = MapBinder.newMapBinder(binder(), String.class, Renderer.class);
|
||||
|
||||
// Bind default renderers
|
||||
bind(LicensesRenderer.class).asEagerSingleton();
|
||||
mbinder.addBinding(LicensesCollector.TYPE).to(LicensesRenderer.class);
|
||||
bind(ClusterInfoRenderer.class).asEagerSingleton();
|
||||
mbinder.addBinding(ClusterInfoCollector.TYPE).to(ClusterInfoRenderer.class);
|
||||
|
||||
bind(IndicesStatsRenderer.class).asEagerSingleton();
|
||||
mbinder.addBinding(IndicesStatsCollector.TYPE).to(IndicesStatsRenderer.class);
|
||||
|
|
|
@ -3,34 +3,33 @@
|
|||
* 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.marvel.agent.renderer.licenses;
|
||||
package org.elasticsearch.marvel.agent.renderer.cluster;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.hash.Hashing;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilderString;
|
||||
import org.elasticsearch.license.core.License;
|
||||
import org.elasticsearch.marvel.agent.collector.licenses.LicensesMarvelDoc;
|
||||
import org.elasticsearch.marvel.agent.collector.cluster.ClusterInfoMarvelDoc;
|
||||
import org.elasticsearch.marvel.agent.renderer.AbstractRenderer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class LicensesRenderer extends AbstractRenderer<LicensesMarvelDoc> {
|
||||
public class ClusterInfoRenderer extends AbstractRenderer<ClusterInfoMarvelDoc> {
|
||||
|
||||
public LicensesRenderer() {
|
||||
super(Strings.EMPTY_ARRAY, false);
|
||||
public ClusterInfoRenderer() {
|
||||
super(null, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doRender(LicensesMarvelDoc marvelDoc, XContentBuilder builder, ToXContent.Params params) throws IOException {
|
||||
|
||||
protected void doRender(ClusterInfoMarvelDoc marvelDoc, XContentBuilder builder, ToXContent.Params params) throws IOException {
|
||||
builder.field(Fields.CLUSTER_NAME, marvelDoc.getClusterName());
|
||||
builder.field(Fields.VERSION, marvelDoc.getVersion());
|
||||
builder.startArray(Fields.LICENSES);
|
||||
|
||||
builder.startArray(Fields.LICENSES);
|
||||
List<License> licenses = marvelDoc.getLicenses();
|
||||
if (licenses != null) {
|
||||
for (License license : licenses) {
|
||||
|
@ -50,6 +49,13 @@ public class LicensesRenderer extends AbstractRenderer<LicensesMarvelDoc> {
|
|||
}
|
||||
}
|
||||
builder.endArray();
|
||||
|
||||
builder.startObject(Fields.CLUSTER_STATS);
|
||||
ClusterStatsResponse clusterStats = marvelDoc.getClusterStats();
|
||||
if (clusterStats != null) {
|
||||
clusterStats.toXContent(builder, params);
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
public static String hash(License license, String clusterName) {
|
||||
|
@ -65,6 +71,7 @@ public class LicensesRenderer extends AbstractRenderer<LicensesMarvelDoc> {
|
|||
static final XContentBuilderString CLUSTER_NAME = new XContentBuilderString("cluster_name");
|
||||
static final XContentBuilderString LICENSES = new XContentBuilderString("licenses");
|
||||
static final XContentBuilderString VERSION = new XContentBuilderString("version");
|
||||
static final XContentBuilderString CLUSTER_STATS = new XContentBuilderString("cluster_stats");
|
||||
|
||||
static final XContentBuilderString HKEY = new XContentBuilderString("hkey");
|
||||
|
|
@ -186,7 +186,7 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"cluster_licenses": {
|
||||
"cluster_info": {
|
||||
"enabled": false
|
||||
},
|
||||
"marvel_node_stats": {
|
||||
|
|
|
@ -7,6 +7,8 @@ package org.elasticsearch.marvel.agent.collector;
|
|||
|
||||
import com.carrotsearch.randomizedtesting.RandomizedTest;
|
||||
import com.carrotsearch.randomizedtesting.SysGlobals;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.cluster.ack.ClusterStateUpdateResponse;
|
||||
import org.elasticsearch.cluster.block.ClusterBlocks;
|
||||
import org.elasticsearch.common.component.AbstractComponent;
|
||||
import org.elasticsearch.common.inject.AbstractModule;
|
||||
|
@ -16,9 +18,10 @@ import org.elasticsearch.common.settings.Settings;
|
|||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.license.core.License;
|
||||
import org.elasticsearch.license.plugin.core.LicensesClientService;
|
||||
import org.elasticsearch.license.plugin.core.LicensesManagerService;
|
||||
import org.elasticsearch.license.plugin.core.LicensesService;
|
||||
import org.elasticsearch.marvel.MarvelPlugin;
|
||||
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
|
||||
import org.elasticsearch.marvel.license.LicenseIntegrationTests;
|
||||
import org.elasticsearch.marvel.license.LicenseService;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
|
@ -72,7 +75,7 @@ public class AbstractCollectorTestCase extends ESIntegTestCase {
|
|||
.signature("_signature")
|
||||
.type("standard")
|
||||
.subscriptionType("all_is_good")
|
||||
.uid(String.valueOf(RandomizedTest.systemPropertyAsInt(SysGlobals.CHILDVM_SYSPROP_JVM_ID, 0)) + System.identityHashCode(LicenseIntegrationTests.class))
|
||||
.uid(String.valueOf(RandomizedTest.systemPropertyAsInt(SysGlobals.CHILDVM_SYSPROP_JVM_ID, 0)) + System.identityHashCode(AbstractCollectorTestCase.class))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -84,6 +87,9 @@ public class AbstractCollectorTestCase extends ESIntegTestCase {
|
|||
for (LicenseServiceForCollectors service : internalCluster().getInstances(LicenseServiceForCollectors.class)) {
|
||||
service.enable(license);
|
||||
}
|
||||
for (LicensesManagerServiceForCollectors service : internalCluster().getInstances(LicensesManagerServiceForCollectors.class)) {
|
||||
service.update(license);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void beginGracefulPeriod() {
|
||||
|
@ -94,6 +100,9 @@ public class AbstractCollectorTestCase extends ESIntegTestCase {
|
|||
for (LicenseServiceForCollectors service : internalCluster().getInstances(LicenseServiceForCollectors.class)) {
|
||||
service.disable(license);
|
||||
}
|
||||
for (LicensesManagerServiceForCollectors service : internalCluster().getInstances(LicensesManagerServiceForCollectors.class)) {
|
||||
service.update(license);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void endGracefulPeriod() {
|
||||
|
@ -104,6 +113,9 @@ public class AbstractCollectorTestCase extends ESIntegTestCase {
|
|||
for (LicenseServiceForCollectors service : internalCluster().getInstances(LicenseServiceForCollectors.class)) {
|
||||
service.disable(license);
|
||||
}
|
||||
for (LicensesManagerServiceForCollectors service : internalCluster().getInstances(LicensesManagerServiceForCollectors.class)) {
|
||||
service.update(license);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void disableLicense() {
|
||||
|
@ -114,6 +126,9 @@ public class AbstractCollectorTestCase extends ESIntegTestCase {
|
|||
for (LicenseServiceForCollectors service : internalCluster().getInstances(LicenseServiceForCollectors.class)) {
|
||||
service.disable(license);
|
||||
}
|
||||
for (LicensesManagerServiceForCollectors service : internalCluster().getInstances(LicensesManagerServiceForCollectors.class)) {
|
||||
service.update(license);
|
||||
}
|
||||
}
|
||||
|
||||
private static long randomDaysInMillis() {
|
||||
|
@ -163,12 +178,14 @@ public class AbstractCollectorTestCase extends ESIntegTestCase {
|
|||
|
||||
@Override
|
||||
public Collection<Module> nodeModules() {
|
||||
return Collections.<Module>singletonList(new AbstractModule(){
|
||||
return Collections.<Module>singletonList(new AbstractModule() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(LicenseServiceForCollectors.class).asEagerSingleton();
|
||||
bind(LicensesClientService.class).to(LicenseServiceForCollectors.class);
|
||||
bind(LicensesManagerServiceForCollectors.class).asEagerSingleton();
|
||||
bind(LicensesManagerService.class).to(LicensesManagerServiceForCollectors.class);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -200,4 +217,31 @@ public class AbstractCollectorTestCase extends ESIntegTestCase {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class LicensesManagerServiceForCollectors implements LicensesManagerService {
|
||||
|
||||
private final Map<String, License> licenses = Collections.synchronizedMap(new HashMap<String, License>());
|
||||
|
||||
@Override
|
||||
public void registerLicenses(LicensesService.PutLicenseRequestHolder requestHolder, ActionListener<LicensesService.LicensesUpdateResponse> listener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLicenses(LicensesService.DeleteLicenseRequestHolder requestHolder, ActionListener<ClusterStateUpdateResponse> listener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> enabledFeatures() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<License> getLicenses() {
|
||||
return new ArrayList<>(licenses.values());
|
||||
}
|
||||
|
||||
public void update(License license) {
|
||||
licenses.put(license.uid(), license);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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.marvel.agent.collector.cluster;
|
||||
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.cluster.ClusterService;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.marvel.agent.collector.AbstractCollectorTestCase;
|
||||
import org.elasticsearch.marvel.agent.exporter.MarvelDoc;
|
||||
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
|
||||
import org.elasticsearch.marvel.license.LicenseService;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
@LuceneTestCase.AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/13017")
|
||||
public class ClusterInfoCollectorTests extends AbstractCollectorTestCase {
|
||||
|
||||
@Test
|
||||
public void testClusterInfoCollector() throws Exception {
|
||||
Collection<MarvelDoc> results = newClusterInfoCollector().doCollect();
|
||||
assertThat(results, hasSize(1));
|
||||
|
||||
MarvelDoc marvelDoc = results.iterator().next();
|
||||
assertNotNull(marvelDoc);
|
||||
assertThat(marvelDoc, instanceOf(ClusterInfoMarvelDoc.class));
|
||||
|
||||
ClusterInfoMarvelDoc clusterInfoMarvelDoc = (ClusterInfoMarvelDoc) marvelDoc;
|
||||
assertThat(clusterInfoMarvelDoc.clusterUUID(), equalTo(client().admin().cluster().prepareState().setMetaData(true).get().getState().metaData().clusterUUID()));
|
||||
assertThat(clusterInfoMarvelDoc.timestamp(), greaterThan(0L));
|
||||
assertThat(clusterInfoMarvelDoc.type(), equalTo(ClusterInfoCollector.TYPE));
|
||||
|
||||
assertThat(clusterInfoMarvelDoc.getClusterName(), equalTo(client().admin().cluster().prepareState().setMetaData(true).get().getClusterName().value()));
|
||||
assertThat(clusterInfoMarvelDoc.getVersion(), equalTo(client().admin().cluster().prepareNodesInfo().get().getNodes()[0].getVersion().toString()));
|
||||
|
||||
assertNotNull(clusterInfoMarvelDoc.getLicenses());
|
||||
assertThat(clusterInfoMarvelDoc.getLicenses(), hasSize(1));
|
||||
|
||||
assertNotNull(clusterInfoMarvelDoc.getClusterStats());
|
||||
assertThat(clusterInfoMarvelDoc.getClusterStats().getNodesStats().getCounts().getTotal(), equalTo(internalCluster().getNodeNames().length));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tesClusterInfoCollectorWithLicensing() {
|
||||
String[] nodes = internalCluster().getNodeNames();
|
||||
for (String node : nodes) {
|
||||
logger.debug("--> creating a new instance of the collector");
|
||||
ClusterInfoCollector collector = newClusterInfoCollector(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 can still collect data (if node is master)");
|
||||
endGracefulPeriod();
|
||||
if (node.equals(internalCluster().getMasterName())) {
|
||||
assertCanCollect(collector);
|
||||
} 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);
|
||||
} else {
|
||||
assertCannotCollect(collector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ClusterInfoCollector newClusterInfoCollector() {
|
||||
return newClusterInfoCollector(null);
|
||||
}
|
||||
|
||||
private ClusterInfoCollector newClusterInfoCollector(String nodeId) {
|
||||
if (!Strings.hasText(nodeId)) {
|
||||
nodeId = randomFrom(internalCluster().getNodeNames());
|
||||
}
|
||||
return new ClusterInfoCollector(internalCluster().getInstance(Settings.class, nodeId),
|
||||
internalCluster().getInstance(ClusterService.class, nodeId),
|
||||
internalCluster().getInstance(MarvelSettings.class, nodeId),
|
||||
internalCluster().getInstance(LicenseService.class, nodeId),
|
||||
internalCluster().getInstance(ClusterName.class, nodeId),
|
||||
client(nodeId));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* 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.marvel.agent.renderer.cluster;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.get.GetResponse;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.license.core.License;
|
||||
import org.elasticsearch.license.plugin.LicensePlugin;
|
||||
import org.elasticsearch.marvel.MarvelPlugin;
|
||||
import org.elasticsearch.marvel.agent.collector.cluster.ClusterInfoCollector;
|
||||
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
|
||||
import org.elasticsearch.node.Node;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
@ClusterScope(scope = ESIntegTestCase.Scope.SUITE, transportClientRatio = 0.0)
|
||||
public class ClusterInfoIT extends ESIntegTestCase {
|
||||
|
||||
@Override
|
||||
protected Settings nodeSettings(int nodeOrdinal) {
|
||||
return Settings.builder()
|
||||
.put(super.nodeSettings(nodeOrdinal))
|
||||
.put(Node.HTTP_ENABLED, true)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)
|
||||
.put(MarvelSettings.STARTUP_DELAY, "1s")
|
||||
.put(MarvelSettings.COLLECTORS, ClusterInfoCollector.NAME)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> nodePlugins() {
|
||||
return Arrays.asList(LicensePlugin.class, MarvelPlugin.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> transportClientPlugins() {
|
||||
return nodePlugins();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLicenses() throws Exception {
|
||||
final String clusterUUID = client().admin().cluster().prepareState().setMetaData(true).get().getState().metaData().clusterUUID();
|
||||
assertTrue(Strings.hasText(clusterUUID));
|
||||
|
||||
logger.debug("--> waiting for licenses collector to collect data (ie, the trial marvel license)");
|
||||
GetResponse response = assertBusy(new Callable<GetResponse>() {
|
||||
@Override
|
||||
public GetResponse call() throws Exception {
|
||||
// Checks if the marvel data index exists (it should have been created by the LicenseCollector)
|
||||
assertTrue(MarvelSettings.MARVEL_DATA_INDEX_NAME + " index does not exist", client().admin().indices().prepareExists(MarvelSettings.MARVEL_DATA_INDEX_NAME).get().isExists());
|
||||
ensureYellow(MarvelSettings.MARVEL_DATA_INDEX_NAME);
|
||||
|
||||
GetResponse response = client().prepareGet(MarvelSettings.MARVEL_DATA_INDEX_NAME, ClusterInfoCollector.TYPE, clusterUUID).get();
|
||||
assertTrue(MarvelSettings.MARVEL_DATA_INDEX_NAME + " document does not exist", response.isExists());
|
||||
return response;
|
||||
}
|
||||
});
|
||||
|
||||
logger.debug("--> checking that the document contains license information");
|
||||
assertThat(response.getIndex(), equalTo(MarvelSettings.MARVEL_DATA_INDEX_NAME));
|
||||
assertThat(response.getType(), equalTo(ClusterInfoCollector.TYPE));
|
||||
assertThat(response.getId(), equalTo(clusterUUID));
|
||||
|
||||
Map<String, Object> source = response.getSource();
|
||||
assertThat((String) source.get(ClusterInfoRenderer.Fields.CLUSTER_NAME.underscore().toString()), equalTo(cluster().getClusterName()));
|
||||
assertThat((String) source.get(ClusterInfoRenderer.Fields.VERSION.underscore().toString()), equalTo(Version.CURRENT.toString()));
|
||||
|
||||
Object licensesList = source.get(ClusterInfoRenderer.Fields.LICENSES.underscore().toString());
|
||||
assertThat(licensesList, instanceOf(List.class));
|
||||
|
||||
List licenses = (List) licensesList;
|
||||
assertThat(licenses.size(), equalTo(1));
|
||||
|
||||
Map license = (Map) licenses.iterator().next();
|
||||
assertThat(license, instanceOf(Map.class));
|
||||
|
||||
String uid = (String) ((Map) license).get(ClusterInfoRenderer.Fields.UID.underscore().toString());
|
||||
assertThat(uid, not(isEmptyOrNullString()));
|
||||
|
||||
String type = (String) ((Map) license).get(ClusterInfoRenderer.Fields.TYPE.underscore().toString());
|
||||
assertThat(type, not(isEmptyOrNullString()));
|
||||
|
||||
String status = (String) ((Map) license).get(ClusterInfoRenderer.Fields.STATUS.underscore().toString());
|
||||
assertThat(status, not(isEmptyOrNullString()));
|
||||
|
||||
Long expiryDate = (Long) ((Map) license).get(ClusterInfoRenderer.Fields.EXPIRY_DATE_IN_MILLIS.underscore().toString());
|
||||
assertThat(expiryDate, greaterThan(0L));
|
||||
|
||||
// We basically recompute the hash here
|
||||
String hkey = (String) ((Map) license).get(ClusterInfoRenderer.Fields.HKEY.underscore().toString());
|
||||
String recalculated = ClusterInfoRenderer.hash(status, uid, type, String.valueOf(expiryDate), clusterUUID);
|
||||
assertThat(hkey, equalTo(recalculated));
|
||||
|
||||
assertThat((String) ((Map) license).get(ClusterInfoRenderer.Fields.FEATURE.underscore().toString()), not(isEmptyOrNullString()));
|
||||
assertThat((String) ((Map) license).get(ClusterInfoRenderer.Fields.ISSUER.underscore().toString()), not(isEmptyOrNullString()));
|
||||
assertThat((String) ((Map) license).get(ClusterInfoRenderer.Fields.ISSUED_TO.underscore().toString()), not(isEmptyOrNullString()));
|
||||
assertThat((Long) ((Map) license).get(ClusterInfoRenderer.Fields.ISSUE_DATE_IN_MILLIS.underscore().toString()), greaterThan(0L));
|
||||
assertThat((Integer) ((Map) license).get(ClusterInfoRenderer.Fields.MAX_NODES.underscore().toString()), greaterThan(0));
|
||||
|
||||
Object clusterStats = source.get(ClusterStatsRenderer.Fields.CLUSTER_STATS.underscore().toString());
|
||||
assertNotNull(clusterStats);
|
||||
assertThat(clusterStats, instanceOf(Map.class));
|
||||
assertThat(((Map) clusterStats).size(), greaterThan(0));
|
||||
|
||||
logger.debug("--> check that the cluster_info is not indexed");
|
||||
refresh();
|
||||
assertHitCount(client().prepareCount()
|
||||
.setIndices(MarvelSettings.MARVEL_DATA_INDEX_NAME)
|
||||
.setTypes(ClusterInfoCollector.TYPE)
|
||||
.setQuery(QueryBuilders.boolQuery()
|
||||
.should(QueryBuilders.matchQuery(ClusterInfoRenderer.Fields.STATUS.underscore().toString(), License.Status.ACTIVE.label()))
|
||||
.should(QueryBuilders.matchQuery(ClusterInfoRenderer.Fields.STATUS.underscore().toString(), License.Status.INVALID.label()))
|
||||
.should(QueryBuilders.matchQuery(ClusterInfoRenderer.Fields.STATUS.underscore().toString(), License.Status.EXPIRED.label()))
|
||||
.minimumNumberShouldMatch(1)
|
||||
).get(), 0L);
|
||||
|
||||
}
|
||||
}
|
|
@ -1,118 +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.marvel.agent.renderer.licenses;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.get.GetResponse;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.license.core.License;
|
||||
import org.elasticsearch.license.plugin.LicensePlugin;
|
||||
import org.elasticsearch.marvel.MarvelPlugin;
|
||||
import org.elasticsearch.marvel.agent.collector.licenses.LicensesCollector;
|
||||
import org.elasticsearch.marvel.agent.renderer.AbstractRendererTestCase;
|
||||
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
public class LicensesIT extends AbstractRendererTestCase {
|
||||
|
||||
@Override
|
||||
protected Collection<String> collectors() {
|
||||
return Collections.singleton(LicensesCollector.NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> nodePlugins() {
|
||||
return Arrays.asList(LicensePlugin.class, MarvelPlugin.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> transportClientPlugins() {
|
||||
return nodePlugins();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLicenses() throws Exception {
|
||||
final String clusterUUID = client().admin().cluster().prepareState().setMetaData(true).get().getState().metaData().clusterUUID();
|
||||
assertTrue(Strings.hasText(clusterUUID));
|
||||
|
||||
logger.debug("--> waiting for licenses collector to collect data (ie, the trial marvel license)");
|
||||
GetResponse response = assertBusy(new Callable<GetResponse>() {
|
||||
@Override
|
||||
public GetResponse call() throws Exception {
|
||||
// Checks if the marvel data index exists (it should have been created by the LicenseCollector)
|
||||
assertTrue(MarvelSettings.MARVEL_DATA_INDEX_NAME + " index does not exist", client().admin().indices().prepareExists(MarvelSettings.MARVEL_DATA_INDEX_NAME).get().isExists());
|
||||
ensureYellow(MarvelSettings.MARVEL_DATA_INDEX_NAME);
|
||||
|
||||
GetResponse response = client().prepareGet(MarvelSettings.MARVEL_DATA_INDEX_NAME, LicensesCollector.TYPE, clusterUUID).get();
|
||||
assertTrue(MarvelSettings.MARVEL_DATA_INDEX_NAME + " document does not exist", response.isExists());
|
||||
return response;
|
||||
}
|
||||
});
|
||||
|
||||
logger.debug("--> checking that the document contains license information");
|
||||
assertThat(response.getIndex(), equalTo(MarvelSettings.MARVEL_DATA_INDEX_NAME));
|
||||
assertThat(response.getType(), equalTo(LicensesCollector.TYPE));
|
||||
assertThat(response.getId(), equalTo(clusterUUID));
|
||||
|
||||
Map<String, Object> source = response.getSource();
|
||||
assertThat((String) source.get(LicensesRenderer.Fields.CLUSTER_NAME.underscore().toString()), equalTo(cluster().getClusterName()));
|
||||
assertThat((String) source.get(LicensesRenderer.Fields.VERSION.underscore().toString()), equalTo(Version.CURRENT.toString()));
|
||||
|
||||
Object licensesList = source.get(LicensesRenderer.Fields.LICENSES.underscore().toString());
|
||||
assertThat(licensesList, instanceOf(List.class));
|
||||
|
||||
List licenses = (List) licensesList;
|
||||
assertThat(licenses.size(), equalTo(1));
|
||||
|
||||
Map license = (Map) licenses.iterator().next();
|
||||
assertThat(license, instanceOf(Map.class));
|
||||
|
||||
String uid = (String) ((Map) license).get(LicensesRenderer.Fields.UID.underscore().toString());
|
||||
assertThat(uid, not(isEmptyOrNullString()));
|
||||
|
||||
String type = (String) ((Map) license).get(LicensesRenderer.Fields.TYPE.underscore().toString());
|
||||
assertThat(type, not(isEmptyOrNullString()));
|
||||
|
||||
String status = (String) ((Map) license).get(LicensesRenderer.Fields.STATUS.underscore().toString());
|
||||
assertThat(status, not(isEmptyOrNullString()));
|
||||
|
||||
Long expiryDate = (Long) ((Map) license).get(LicensesRenderer.Fields.EXPIRY_DATE_IN_MILLIS.underscore().toString());
|
||||
assertThat(expiryDate, greaterThan(0L));
|
||||
|
||||
// We basically recompute the hash here
|
||||
String hkey = (String) ((Map) license).get(LicensesRenderer.Fields.HKEY.underscore().toString());
|
||||
String recalculated = LicensesRenderer.hash(status, uid, type, String.valueOf(expiryDate), clusterUUID);
|
||||
assertThat(hkey, equalTo(recalculated));
|
||||
|
||||
assertThat((String) ((Map) license).get(LicensesRenderer.Fields.FEATURE.underscore().toString()), not(isEmptyOrNullString()));
|
||||
assertThat((String) ((Map) license).get(LicensesRenderer.Fields.ISSUER.underscore().toString()), not(isEmptyOrNullString()));
|
||||
assertThat((String) ((Map) license).get(LicensesRenderer.Fields.ISSUED_TO.underscore().toString()), not(isEmptyOrNullString()));
|
||||
assertThat((Long) ((Map) license).get(LicensesRenderer.Fields.ISSUE_DATE_IN_MILLIS.underscore().toString()), greaterThan(0L));
|
||||
assertThat((Integer) ((Map) license).get(LicensesRenderer.Fields.MAX_NODES.underscore().toString()), greaterThan(0));
|
||||
|
||||
|
||||
logger.debug("--> check that the cluster_licenses is not indexed");
|
||||
refresh();
|
||||
assertHitCount(client().prepareCount()
|
||||
.setIndices(MarvelSettings.MARVEL_DATA_INDEX_NAME)
|
||||
.setTypes(LicensesCollector.TYPE)
|
||||
.setQuery(QueryBuilders.boolQuery()
|
||||
.should(QueryBuilders.matchQuery(LicensesRenderer.Fields.STATUS.underscore().toString(), License.Status.ACTIVE.label()))
|
||||
.should(QueryBuilders.matchQuery(LicensesRenderer.Fields.STATUS.underscore().toString(), License.Status.INVALID.label()))
|
||||
.should(QueryBuilders.matchQuery(LicensesRenderer.Fields.STATUS.underscore().toString(), License.Status.EXPIRED.label()))
|
||||
.minimumNumberShouldMatch(1)
|
||||
).get(), 0L);
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue