Skip to content

Commit

Permalink
Serialize NodesInfoRequest as a set of strings (#53140)
Browse files Browse the repository at this point in the history
For Node Info to be pluggable, NodesInfoRequest must be able to carry
arbitrary strings. This commit reworks the internals of that class to
use a set rather than hard-coded boolean fields.

NodesInfoRequest defaults to specifying all values. We test for
this behavior as we refactor and use random testing for the
various combinations of metrics.

Add backwards compatibility for transport requests.
  • Loading branch information
williamrandolph committed Mar 6, 2020
1 parent bc978e4 commit 4bd55ce
Show file tree
Hide file tree
Showing 3 changed files with 262 additions and 72 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ task verifyVersions {
* after the backport of the backcompat code is complete.
*/

boolean bwc_tests_enabled = true
final String bwc_tests_disabled_issue = "" /* place a PR link here when committing bwc changes */
boolean bwc_tests_enabled = false
final String bwc_tests_disabled_issue = "https://github.com/elastic/elasticsearch/pull/53140" /* place a PR link here when committing bwc changes */
if (bwc_tests_enabled == false) {
if (bwc_tests_disabled_issue.isEmpty()) {
throw new GradleException("bwc_tests_disabled_issue must be set when bwc_tests_enabled == false")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,40 +19,48 @@

package org.elasticsearch.action.admin.cluster.node.info;

import org.elasticsearch.Version;
import org.elasticsearch.action.support.nodes.BaseNodesRequest;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;

import java.io.IOException;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;

/**
* A request to get node (cluster) level information.
*/
public class NodesInfoRequest extends BaseNodesRequest<NodesInfoRequest> {

private boolean settings = true;
private boolean os = true;
private boolean process = true;
private boolean jvm = true;
private boolean threadPool = true;
private boolean transport = true;
private boolean http = true;
private boolean plugins = true;
private boolean ingest = true;
private boolean indices = true;
private Set<String> requestedMetrics = Metrics.allMetrics();

/**
* Create a new NodeInfoRequest from a {@link StreamInput} object.
*
* @param in A stream input object.
* @throws IOException if the stream cannot be deserialized.
*/
public NodesInfoRequest(StreamInput in) throws IOException {
super(in);
settings = in.readBoolean();
os = in.readBoolean();
process = in.readBoolean();
jvm = in.readBoolean();
threadPool = in.readBoolean();
transport = in.readBoolean();
http = in.readBoolean();
plugins = in.readBoolean();
ingest = in.readBoolean();
indices = in.readBoolean();
requestedMetrics.clear();
if (in.getVersion().before(Version.V_7_7_0)){
// prior to version 8.x, a NodesInfoRequest was serialized as a list
// of booleans in a fixed order
addOrRemoveMetric(in.readBoolean(), Metrics.SETTINGS.metricName());
addOrRemoveMetric(in.readBoolean(), Metrics.OS.metricName());
addOrRemoveMetric(in.readBoolean(), Metrics.PROCESS.metricName());
addOrRemoveMetric(in.readBoolean(), Metrics.JVM.metricName());
addOrRemoveMetric(in.readBoolean(), Metrics.THREAD_POOL.metricName());
addOrRemoveMetric(in.readBoolean(), Metrics.TRANSPORT.metricName());
addOrRemoveMetric(in.readBoolean(), Metrics.HTTP.metricName());
addOrRemoveMetric(in.readBoolean(), Metrics.PLUGINS.metricName());
addOrRemoveMetric(in.readBoolean(), Metrics.INGEST.metricName());
addOrRemoveMetric(in.readBoolean(), Metrics.INDICES.metricName());
} else {
requestedMetrics.addAll(Arrays.asList(in.readStringArray()));
}
}

/**
Expand All @@ -61,144 +69,127 @@ public NodesInfoRequest(StreamInput in) throws IOException {
*/
public NodesInfoRequest(String... nodesIds) {
super(nodesIds);
all();
}

/**
* Clears all info flags.
*/
public NodesInfoRequest clear() {
settings = false;
os = false;
process = false;
jvm = false;
threadPool = false;
transport = false;
http = false;
plugins = false;
ingest = false;
indices = false;
requestedMetrics.clear();
return this;
}

/**
* Sets to return all the data.
*/
public NodesInfoRequest all() {
settings = true;
os = true;
process = true;
jvm = true;
threadPool = true;
transport = true;
http = true;
plugins = true;
ingest = true;
indices = true;
requestedMetrics.addAll(Metrics.allMetrics());
return this;
}

/**
* Should the node settings be returned.
*/
public boolean settings() {
return this.settings;
return Metrics.SETTINGS.containedIn(requestedMetrics);
}

/**
* Should the node settings be returned.
*/
public NodesInfoRequest settings(boolean settings) {
this.settings = settings;
addOrRemoveMetric(settings, Metrics.SETTINGS.metricName());
return this;
}

/**
* Should the node OS be returned.
*/
public boolean os() {
return this.os;
return Metrics.OS.containedIn(requestedMetrics);
}

/**
* Should the node OS be returned.
*/
public NodesInfoRequest os(boolean os) {
this.os = os;
addOrRemoveMetric(os, Metrics.OS.metricName());
return this;
}

/**
* Should the node Process be returned.
*/
public boolean process() {
return this.process;
return Metrics.PROCESS.containedIn(requestedMetrics);
}

/**
* Should the node Process be returned.
*/
public NodesInfoRequest process(boolean process) {
this.process = process;
addOrRemoveMetric(process, Metrics.PROCESS.metricName());
return this;
}

/**
* Should the node JVM be returned.
*/
public boolean jvm() {
return this.jvm;
return Metrics.JVM.containedIn(requestedMetrics);
}

/**
* Should the node JVM be returned.
*/
public NodesInfoRequest jvm(boolean jvm) {
this.jvm = jvm;
addOrRemoveMetric(jvm, Metrics.JVM.metricName());
return this;
}

/**
* Should the node Thread Pool info be returned.
*/
public boolean threadPool() {
return this.threadPool;
return Metrics.THREAD_POOL.containedIn(requestedMetrics);
}

/**
* Should the node Thread Pool info be returned.
*/
public NodesInfoRequest threadPool(boolean threadPool) {
this.threadPool = threadPool;
addOrRemoveMetric(threadPool, Metrics.THREAD_POOL.metricName());
return this;
}

/**
* Should the node Transport be returned.
*/
public boolean transport() {
return this.transport;
return Metrics.TRANSPORT.containedIn(requestedMetrics);
}

/**
* Should the node Transport be returned.
*/
public NodesInfoRequest transport(boolean transport) {
this.transport = transport;
addOrRemoveMetric(transport, Metrics.TRANSPORT.metricName());
return this;
}

/**
* Should the node HTTP be returned.
*/
public boolean http() {
return this.http;
return Metrics.HTTP.containedIn(requestedMetrics);
}

/**
* Should the node HTTP be returned.
*/
public NodesInfoRequest http(boolean http) {
this.http = http;
addOrRemoveMetric(http, Metrics.HTTP.metricName());
return this;
}

Expand All @@ -208,61 +199,116 @@ public NodesInfoRequest http(boolean http) {
* @return The request
*/
public NodesInfoRequest plugins(boolean plugins) {
this.plugins = plugins;
addOrRemoveMetric(plugins, Metrics.PLUGINS.metricName());
return this;
}

/**
* @return true if information about plugins is requested
*/
public boolean plugins() {
return plugins;
return Metrics.PLUGINS.containedIn(requestedMetrics);
}

/**
* Should information about ingest be returned
* @param ingest true if you want info
*/
public NodesInfoRequest ingest(boolean ingest) {
this.ingest = ingest;
addOrRemoveMetric(ingest, Metrics.INGEST.metricName());
return this;
}

/**
* @return true if information about ingest is requested
*/
public boolean ingest() {
return ingest;
return Metrics.INGEST.containedIn(requestedMetrics);
}

/**
* Should information about indices (currently just indexing buffers) be returned
* @param indices true if you want info
*/
public NodesInfoRequest indices(boolean indices) {
this.indices = indices;
addOrRemoveMetric(indices, Metrics.INDICES.metricName());
return this;
}

/**
* @return true if information about indices (currently just indexing buffers)
*/
public boolean indices() {
return indices;
return Metrics.INDICES.containedIn(requestedMetrics);
}

/**
* Helper method for adding and removing metrics.
* @param includeMetric Whether or not to include a metric.
* @param metricName Name of the metric to include or remove.
*/
private void addOrRemoveMetric(boolean includeMetric, String metricName) {
if (includeMetric) {
requestedMetrics.add(metricName);
} else {
requestedMetrics.remove(metricName);
}
}

@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeBoolean(settings);
out.writeBoolean(os);
out.writeBoolean(process);
out.writeBoolean(jvm);
out.writeBoolean(threadPool);
out.writeBoolean(transport);
out.writeBoolean(http);
out.writeBoolean(plugins);
out.writeBoolean(ingest);
out.writeBoolean(indices);
if (out.getVersion().before(Version.V_7_7_0)){
// prior to version 8.x, a NodesInfoRequest was serialized as a list
// of booleans in a fixed order
out.writeBoolean(Metrics.SETTINGS.containedIn(requestedMetrics));
out.writeBoolean(Metrics.OS.containedIn(requestedMetrics));
out.writeBoolean(Metrics.PROCESS.containedIn(requestedMetrics));
out.writeBoolean(Metrics.JVM.containedIn(requestedMetrics));
out.writeBoolean(Metrics.THREAD_POOL.containedIn(requestedMetrics));
out.writeBoolean(Metrics.TRANSPORT.containedIn(requestedMetrics));
out.writeBoolean(Metrics.HTTP.containedIn(requestedMetrics));
out.writeBoolean(Metrics.PLUGINS.containedIn(requestedMetrics));
out.writeBoolean(Metrics.INGEST.containedIn(requestedMetrics));
out.writeBoolean(Metrics.INDICES.containedIn(requestedMetrics));
} else {
out.writeStringArray(requestedMetrics.toArray(String[]::new));
}
}

/**
* An enumeration of the "core" sections of metrics that may be requested
* from the nodes information endpoint. Eventually this list list will be
* pluggable.
*/
enum Metrics {
SETTINGS("settings"),
OS("os"),
PROCESS("process"),
JVM("jvm"),
THREAD_POOL("threadPool"),
TRANSPORT("transport"),
HTTP("http"),
PLUGINS("plugins"),
INGEST("ingest"),
INDICES("indices");

private String metricName;

Metrics(String name) {
this.metricName = name;
}

String metricName() {
return this.metricName;
}

boolean containedIn(Set<String> metricNames) {
return metricNames.contains(this.metricName());
}

static Set<String> allMetrics() {
return Arrays.stream(values()).map(Metrics::metricName).collect(Collectors.toSet());
}
}
}

0 comments on commit 4bd55ce

Please sign in to comment.