Introducing infrastructure for feature usage API
- Each `XPackFeatureSet` can now return a `Usage` object that encapsulates the feature usage stats of the set - A new `/_xpack/usage` REST API is introduced to access the usage stats of all features - Intentionally not explicitly exposing the API in the `XPackClient` as this API is primarily meant for use by Kibana X-Pack (that said, it is still possible to call this API from the transport client using the `XPathUsageRequestBuilder`) - For now the usage stats that are returned are minimal, once this infrastructure is in, we'll start adding more stats Relates to elastic/elasticsearch#2210 Original commit: elastic/x-pack-elasticsearch@d651fe4b01
This commit is contained in:
parent
d552574016
commit
9dbbfd09f8
|
@ -7,9 +7,14 @@ package org.elasticsearch.graph;
|
|||
|
||||
import org.elasticsearch.common.Nullable;
|
||||
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.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.xpack.XPackFeatureSet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -19,9 +24,10 @@ public class GraphFeatureSet implements XPackFeatureSet {
|
|||
private final GraphLicensee licensee;
|
||||
|
||||
@Inject
|
||||
public GraphFeatureSet(Settings settings, @Nullable GraphLicensee licensee) {
|
||||
public GraphFeatureSet(Settings settings, @Nullable GraphLicensee licensee, NamedWriteableRegistry namedWriteableRegistry) {
|
||||
this.enabled = Graph.enabled(settings);
|
||||
this.licensee = licensee;
|
||||
namedWriteableRegistry.register(Usage.class, Usage.WRITEABLE_NAME, Usage::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,4 +49,36 @@ public class GraphFeatureSet implements XPackFeatureSet {
|
|||
public boolean enabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Usage usage() {
|
||||
return new Usage(available(), enabled());
|
||||
}
|
||||
|
||||
static class Usage extends XPackFeatureSet.Usage {
|
||||
|
||||
static final String WRITEABLE_NAME = writeableName(Graph.NAME);
|
||||
|
||||
public Usage(StreamInput input) throws IOException {
|
||||
super(input);
|
||||
}
|
||||
|
||||
public Usage(boolean available, boolean enabled) {
|
||||
super(Graph.NAME, available, enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWriteableName() {
|
||||
return WRITEABLE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
return builder.startObject()
|
||||
.field(Field.AVAILABLE, available)
|
||||
.field(Field.ENABLED, enabled)
|
||||
.endObject();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,19 @@ package org.elasticsearch.marvel;
|
|||
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
||||
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.marvel.agent.exporter.Exporter;
|
||||
import org.elasticsearch.marvel.agent.exporter.Exporters;
|
||||
import org.elasticsearch.marvel.agent.exporter.http.HttpExporter;
|
||||
import org.elasticsearch.marvel.agent.exporter.local.LocalExporter;
|
||||
import org.elasticsearch.xpack.XPackFeatureSet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -17,11 +27,15 @@ public class MonitoringFeatureSet implements XPackFeatureSet {
|
|||
|
||||
private final boolean enabled;
|
||||
private final MonitoringLicensee licensee;
|
||||
private final Exporters exporters;
|
||||
|
||||
@Inject
|
||||
public MonitoringFeatureSet(Settings settings, @Nullable MonitoringLicensee licensee) {
|
||||
public MonitoringFeatureSet(Settings settings, @Nullable MonitoringLicensee licensee, Exporters exporters,
|
||||
NamedWriteableRegistry namedWriteableRegistry) {
|
||||
this.enabled = MonitoringSettings.ENABLED.get(settings);
|
||||
this.licensee = licensee;
|
||||
this.exporters = exporters;
|
||||
namedWriteableRegistry.register(Usage.class, Usage.WRITEABLE_NAME, Usage::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,4 +57,98 @@ public class MonitoringFeatureSet implements XPackFeatureSet {
|
|||
public boolean enabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Usage usage() {
|
||||
|
||||
int enabledLocalExporters = 0;
|
||||
int enabledHttpExporters = 0;
|
||||
int enabledUnknownExporters = 0;
|
||||
for (Exporter exporter : exporters) {
|
||||
if (exporter.config().enabled()) {
|
||||
switch (exporter.type()) {
|
||||
case LocalExporter.TYPE:
|
||||
enabledLocalExporters++;
|
||||
break;
|
||||
case HttpExporter.TYPE:
|
||||
enabledHttpExporters++;
|
||||
break;
|
||||
default:
|
||||
enabledUnknownExporters++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Usage(available(), enabled(), enabledLocalExporters, enabledHttpExporters, enabledUnknownExporters);
|
||||
}
|
||||
|
||||
static class Usage extends XPackFeatureSet.Usage {
|
||||
|
||||
private static String WRITEABLE_NAME = writeableName(Monitoring.NAME);
|
||||
|
||||
private final int enabledLocalExporters;
|
||||
private final int enabledHttpExporters;
|
||||
private final int enabledUnknownExporters;
|
||||
|
||||
public Usage(StreamInput in) throws IOException {
|
||||
super(in);
|
||||
this.enabledLocalExporters = in.readVInt();
|
||||
this.enabledHttpExporters = in.readVInt();
|
||||
this.enabledUnknownExporters = in.readVInt();
|
||||
}
|
||||
|
||||
public Usage(boolean available, boolean enabled, int enabledLocalExporters, int enabledHttpExporters, int enabledUnknownExporters) {
|
||||
super(Monitoring.NAME, available, enabled);
|
||||
this.enabledLocalExporters = enabledLocalExporters;
|
||||
this.enabledHttpExporters = enabledHttpExporters;
|
||||
this.enabledUnknownExporters = enabledUnknownExporters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean available() {
|
||||
return available;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWriteableName() {
|
||||
return WRITEABLE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
super.writeTo(out);
|
||||
out.writeVInt(enabledLocalExporters);
|
||||
out.writeVInt(enabledHttpExporters);
|
||||
out.writeVInt(enabledUnknownExporters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.field(Field.AVAILABLE, available);
|
||||
builder.field(Field.ENABLED, enabled);
|
||||
|
||||
builder.startObject(Field.ENABLED_EXPORTERS);
|
||||
builder.field(Field.LOCAL, enabledLocalExporters);
|
||||
builder.field(Field.HTTP, enabledHttpExporters);
|
||||
if (enabledUnknownExporters > 0) {
|
||||
builder.field(Field.UNKNOWN, enabledUnknownExporters);
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
return builder.endObject();
|
||||
}
|
||||
|
||||
interface Field extends XPackFeatureSet.Usage.Field {
|
||||
String ENABLED_EXPORTERS = "enabled_exporters";
|
||||
String LOCAL = "_local";
|
||||
String HTTP = "http";
|
||||
String UNKNOWN = "_unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,10 @@ public abstract class Exporter implements AutoCloseable {
|
|||
return config.name;
|
||||
}
|
||||
|
||||
public Config config() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public boolean masterOnly() {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -7,9 +7,15 @@ package org.elasticsearch.shield;
|
|||
|
||||
import org.elasticsearch.common.Nullable;
|
||||
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.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.marvel.Monitoring;
|
||||
import org.elasticsearch.xpack.XPackFeatureSet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -19,9 +25,11 @@ public class SecurityFeatureSet implements XPackFeatureSet {
|
|||
private final SecurityLicenseState licenseState;
|
||||
|
||||
@Inject
|
||||
public SecurityFeatureSet(Settings settings, @Nullable SecurityLicenseState licenseState) {
|
||||
public SecurityFeatureSet(Settings settings, @Nullable SecurityLicenseState licenseState,
|
||||
NamedWriteableRegistry namedWriteableRegistry) {
|
||||
this.enabled = Security.enabled(settings);
|
||||
this.licenseState = licenseState;
|
||||
namedWriteableRegistry.register(Usage.class, Usage.WRITEABLE_NAME, Usage::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,4 +51,36 @@ public class SecurityFeatureSet implements XPackFeatureSet {
|
|||
public boolean enabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XPackFeatureSet.Usage usage() {
|
||||
return new Usage(available(), enabled());
|
||||
}
|
||||
|
||||
static class Usage extends XPackFeatureSet.Usage {
|
||||
|
||||
private static final String WRITEABLE_NAME = writeableName(Security.NAME);
|
||||
|
||||
public Usage(StreamInput input) throws IOException {
|
||||
super(input);
|
||||
}
|
||||
|
||||
public Usage(boolean available, boolean enabled) {
|
||||
super(Security.NAME, available, enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWriteableName() {
|
||||
return WRITEABLE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
return builder.startObject()
|
||||
.field(Field.AVAILABLE, available)
|
||||
.field(Field.ENABLED, enabled)
|
||||
.endObject();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,13 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack;
|
||||
|
||||
import org.elasticsearch.common.io.stream.NamedWriteable;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -18,4 +25,50 @@ public interface XPackFeatureSet {
|
|||
|
||||
boolean enabled();
|
||||
|
||||
Usage usage();
|
||||
|
||||
abstract class Usage implements ToXContent, NamedWriteable {
|
||||
|
||||
protected final String name;
|
||||
protected final boolean available;
|
||||
protected final boolean enabled;
|
||||
|
||||
public Usage(StreamInput input) throws IOException {
|
||||
this(input.readString(), input.readBoolean(), input.readBoolean());
|
||||
}
|
||||
|
||||
public Usage(String name, boolean available, boolean enabled) {
|
||||
this.name = name;
|
||||
this.available = available;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean available() {
|
||||
return available;
|
||||
}
|
||||
|
||||
public boolean enabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeBoolean(available);
|
||||
out.writeBoolean(enabled);
|
||||
}
|
||||
|
||||
protected interface Field {
|
||||
String AVAILABLE = "available";
|
||||
String ENABLED = "enabled";
|
||||
}
|
||||
|
||||
protected static String writeableName(String featureName) {
|
||||
return "xpack.usage." + featureName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,7 +27,9 @@ import org.elasticsearch.script.ScriptModule;
|
|||
import org.elasticsearch.shield.Security;
|
||||
import org.elasticsearch.shield.authc.AuthenticationModule;
|
||||
import org.elasticsearch.xpack.action.TransportXPackInfoAction;
|
||||
import org.elasticsearch.xpack.action.TransportXPackUsageAction;
|
||||
import org.elasticsearch.xpack.action.XPackInfoAction;
|
||||
import org.elasticsearch.xpack.action.XPackUsageAction;
|
||||
import org.elasticsearch.xpack.common.http.HttpClientModule;
|
||||
import org.elasticsearch.xpack.common.init.LazyInitializationModule;
|
||||
import org.elasticsearch.xpack.common.init.LazyInitializationService;
|
||||
|
@ -37,6 +39,7 @@ import org.elasticsearch.xpack.extensions.XPackExtensionsService;
|
|||
import org.elasticsearch.xpack.notification.Notification;
|
||||
import org.elasticsearch.xpack.rest.action.RestXPackInfoAction;
|
||||
import org.elasticsearch.xpack.common.text.TextTemplateModule;
|
||||
import org.elasticsearch.xpack.rest.action.RestXPackUsageAction;
|
||||
import org.elasticsearch.xpack.watcher.Watcher;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
@ -194,6 +197,7 @@ public class XPackPlugin extends Plugin {
|
|||
public void onModule(NetworkModule module) {
|
||||
if (!transportClientMode) {
|
||||
module.registerRestHandler(RestXPackInfoAction.class);
|
||||
module.registerRestHandler(RestXPackUsageAction.class);
|
||||
}
|
||||
licensing.onModule(module);
|
||||
monitoring.onModule(module);
|
||||
|
@ -205,6 +209,7 @@ public class XPackPlugin extends Plugin {
|
|||
public void onModule(ActionModule module) {
|
||||
if (!transportClientMode) {
|
||||
module.registerAction(XPackInfoAction.INSTANCE, TransportXPackInfoAction.class);
|
||||
module.registerAction(XPackUsageAction.INSTANCE, TransportXPackUsageAction.class);
|
||||
}
|
||||
licensing.onModule(module);
|
||||
monitoring.onModule(module);
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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.action;
|
||||
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.support.ActionFilters;
|
||||
import org.elasticsearch.action.support.HandledTransportAction;
|
||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
import org.elasticsearch.xpack.XPackFeatureSet;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class TransportXPackUsageAction extends HandledTransportAction<XPackUsageRequest, XPackUsageResponse> {
|
||||
|
||||
private final Set<XPackFeatureSet> featureSets;
|
||||
|
||||
@Inject
|
||||
public TransportXPackUsageAction(Settings settings, ThreadPool threadPool, TransportService transportService,
|
||||
ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver,
|
||||
Set<XPackFeatureSet> featureSets) {
|
||||
super(settings, XPackInfoAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver,
|
||||
XPackUsageRequest::new);
|
||||
this.featureSets = featureSets;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doExecute(XPackUsageRequest request, ActionListener<XPackUsageResponse> listener) {
|
||||
List<XPackFeatureSet.Usage> usages = featureSets.stream().map(XPackFeatureSet::usage).collect(Collectors.toList());
|
||||
listener.onResponse(new XPackUsageResponse(usages));
|
||||
}
|
||||
}
|
|
@ -14,7 +14,6 @@ import org.elasticsearch.common.xcontent.ToXContent;
|
|||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.license.core.License;
|
||||
import org.elasticsearch.xpack.XPackBuild;
|
||||
import org.elasticsearch.xpack.XPackFeatureSet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -219,7 +218,7 @@ public class XPackInfoResponse extends ActionResponse {
|
|||
}
|
||||
}
|
||||
|
||||
public static class FeatureSet implements XPackFeatureSet, ToXContent, Writeable {
|
||||
public static class FeatureSet implements ToXContent, Writeable {
|
||||
|
||||
private final String name;
|
||||
private final @Nullable String description;
|
||||
|
@ -237,23 +236,19 @@ public class XPackInfoResponse extends ActionResponse {
|
|||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String description() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean available() {
|
||||
return available;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.action;
|
||||
|
||||
import org.elasticsearch.action.Action;
|
||||
import org.elasticsearch.client.ElasticsearchClient;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class XPackUsageAction extends Action<XPackUsageRequest, XPackUsageResponse, XPackUsageRequestBuilder> {
|
||||
|
||||
public static final String NAME = "cluster:monitor/xpack/usage";
|
||||
public static final XPackUsageAction INSTANCE = new XPackUsageAction();
|
||||
|
||||
public XPackUsageAction() {
|
||||
super(NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XPackUsageRequestBuilder newRequestBuilder(ElasticsearchClient client) {
|
||||
return new XPackUsageRequestBuilder(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XPackUsageResponse newResponse() {
|
||||
return new XPackUsageResponse();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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.action;
|
||||
|
||||
import org.elasticsearch.action.ActionRequest;
|
||||
import org.elasticsearch.action.ActionRequestValidationException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class XPackUsageRequest extends ActionRequest<XPackUsageRequest> {
|
||||
|
||||
@Override
|
||||
public ActionRequestValidationException validate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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.action;
|
||||
|
||||
import org.elasticsearch.action.ActionRequestBuilder;
|
||||
import org.elasticsearch.client.ElasticsearchClient;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class XPackUsageRequestBuilder extends ActionRequestBuilder<XPackUsageRequest, XPackUsageResponse, XPackUsageRequestBuilder> {
|
||||
|
||||
public XPackUsageRequestBuilder(ElasticsearchClient client) {
|
||||
this(client, XPackUsageAction.INSTANCE);
|
||||
}
|
||||
|
||||
public XPackUsageRequestBuilder(ElasticsearchClient client, XPackUsageAction action) {
|
||||
super(client, action, new XPackUsageRequest());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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.action;
|
||||
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.license.core.License;
|
||||
import org.elasticsearch.xpack.XPackBuild;
|
||||
import org.elasticsearch.xpack.XPackFeatureSet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class XPackUsageResponse extends ActionResponse {
|
||||
|
||||
private List<XPackFeatureSet.Usage> usages;
|
||||
|
||||
public XPackUsageResponse() {}
|
||||
|
||||
public XPackUsageResponse(List<XPackFeatureSet.Usage> usages) {
|
||||
this.usages = usages;
|
||||
}
|
||||
|
||||
public List<XPackFeatureSet.Usage> getUsages() {
|
||||
return usages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
super.writeTo(out);
|
||||
out.writeVInt(usages.size());
|
||||
for (XPackFeatureSet.Usage usage : usages) {
|
||||
out.writeNamedWriteable(usage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFrom(StreamInput in) throws IOException {
|
||||
super.readFrom(in);
|
||||
int size = in.readVInt();
|
||||
usages = new ArrayList<>(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
usages.add(in.readNamedWriteable(XPackFeatureSet.Usage.class));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.rest.action;
|
||||
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.rest.BytesRestResponse;
|
||||
import org.elasticsearch.rest.RestChannel;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
import org.elasticsearch.rest.RestResponse;
|
||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
||||
import org.elasticsearch.xpack.XPackClient;
|
||||
import org.elasticsearch.xpack.XPackFeatureSet;
|
||||
import org.elasticsearch.xpack.action.XPackUsageRequestBuilder;
|
||||
import org.elasticsearch.xpack.action.XPackUsageResponse;
|
||||
import org.elasticsearch.xpack.rest.XPackRestHandler;
|
||||
|
||||
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
||||
import static org.elasticsearch.rest.RestStatus.OK;
|
||||
|
||||
public class RestXPackUsageAction extends XPackRestHandler {
|
||||
|
||||
@Inject
|
||||
public RestXPackUsageAction(Settings settings, RestController controller, Client client) {
|
||||
super(settings, client);
|
||||
controller.registerHandler(GET, URI_BASE + "/usage", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleRequest(RestRequest request, RestChannel restChannel, XPackClient client) throws Exception {
|
||||
new XPackUsageRequestBuilder(client.es()).execute(new RestBuilderListener<XPackUsageResponse>(restChannel) {
|
||||
@Override
|
||||
public RestResponse buildResponse(XPackUsageResponse response, XContentBuilder builder) throws Exception {
|
||||
builder.startObject();
|
||||
for (XPackFeatureSet.Usage usage : response.getUsages()) {
|
||||
builder.field(usage.name(), usage);
|
||||
}
|
||||
builder.endObject();
|
||||
return new BytesRestResponse(OK, builder);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -7,9 +7,14 @@ package org.elasticsearch.xpack.watcher;
|
|||
|
||||
import org.elasticsearch.common.Nullable;
|
||||
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.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.xpack.XPackFeatureSet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -19,9 +24,10 @@ public class WatcherFeatureSet implements XPackFeatureSet {
|
|||
private final WatcherLicensee licensee;
|
||||
|
||||
@Inject
|
||||
public WatcherFeatureSet(Settings settings, @Nullable WatcherLicensee licensee) {
|
||||
public WatcherFeatureSet(Settings settings, @Nullable WatcherLicensee licensee, NamedWriteableRegistry namedWriteableRegistry) {
|
||||
this.enabled = Watcher.enabled(settings);
|
||||
this.licensee = licensee;
|
||||
namedWriteableRegistry.register(Usage.class, Usage.WRITEABLE_NAME, Usage::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,4 +49,36 @@ public class WatcherFeatureSet implements XPackFeatureSet {
|
|||
public boolean enabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Usage usage() {
|
||||
return new Usage(available(), enabled());
|
||||
}
|
||||
|
||||
static class Usage extends XPackFeatureSet.Usage {
|
||||
|
||||
private static final String WRITEABLE_NAME = writeableName(Watcher.NAME);
|
||||
|
||||
public Usage(StreamInput input) throws IOException {
|
||||
super(input);
|
||||
}
|
||||
|
||||
public Usage(boolean available, boolean enabled) {
|
||||
super(Watcher.NAME, available, enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWriteableName() {
|
||||
return WRITEABLE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
return builder.startObject()
|
||||
.field(Field.AVAILABLE, available)
|
||||
.field(Field.ENABLED, enabled)
|
||||
.endObject();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue