diff --git a/server/src/main/java/org/opensearch/Build.java b/server/src/main/java/org/opensearch/Build.java index 13c951b10cfe3..248e3403c436f 100644 --- a/server/src/main/java/org/opensearch/Build.java +++ b/server/src/main/java/org/opensearch/Build.java @@ -32,6 +32,8 @@ package org.opensearch; +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; import org.opensearch.common.Booleans; import org.opensearch.common.io.FileSystemUtils; import org.opensearch.common.io.stream.StreamInput; @@ -218,6 +220,18 @@ public static Build readBuild(StreamInput in) throws IOException { return new Build(type, hash, date, snapshot, version, distribution); } + public static Build readBuildProtobuf(CodedInputStream in) throws IOException { + // the following is new for opensearch: we write the distribution to support any "forks" + final String distribution = in.readString(); + // be lenient when reading on the wire, the enumeration values from other versions might be different than what we know + final Type type = Type.fromDisplayName(in.readString(), false); + String hash = in.readString(); + String date = in.readString(); + boolean snapshot = in.readBool(); + final String version = in.readString(); + return new Build(type, hash, date, snapshot, version, distribution); + } + public static void writeBuild(Build build, StreamOutput out) throws IOException { // the following is new for opensearch: we write the distribution name to support any "forks" of the code out.writeString(build.distribution); @@ -230,6 +244,18 @@ public static void writeBuild(Build build, StreamOutput out) throws IOException out.writeString(build.getQualifiedVersion()); } + public static void writeBuildProtobuf(Build build, CodedOutputStream out) throws IOException { + // the following is new for opensearch: we write the distribution name to support any "forks" of the code + out.writeStringNoTag(build.distribution); + + final Type buildType = build.type(); + out.writeStringNoTag(buildType.displayName()); + out.writeStringNoTag(build.hash()); + out.writeStringNoTag(build.date()); + out.writeBoolNoTag(build.isSnapshot()); + out.writeStringNoTag(build.getQualifiedVersion()); + } + /** * Get the distribution name (expected to be OpenSearch; empty if legacy; something else if forked) * @return distribution name as a string diff --git a/server/src/main/java/org/opensearch/ProtobufOpenSearchException.java b/server/src/main/java/org/opensearch/ProtobufOpenSearchException.java new file mode 100644 index 0000000000000..30c9e8be2cfb6 --- /dev/null +++ b/server/src/main/java/org/opensearch/ProtobufOpenSearchException.java @@ -0,0 +1,45 @@ +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +package org.opensearch; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import org.opensearch.common.io.stream.ProtobufWriteable; + +import java.io.IOException; + +/** + * Base exception for a failed node +* +* @opensearch.internal +*/ +public class ProtobufOpenSearchException extends RuntimeException implements ProtobufWriteable { + + private String message; + + public ProtobufOpenSearchException(String message) { + super(message); + this.message = message; + } + + public ProtobufOpenSearchException(CodedInputStream in) throws IOException { + super(in.readString()); + this.message = in.readString(); + } + + @Override + public void writeTo(CodedOutputStream out) throws IOException { + out.writeStringNoTag(this.getMessage()); + } + + public String getMessage() { + return this.message; + } + +} diff --git a/server/src/main/java/org/opensearch/Version.java b/server/src/main/java/org/opensearch/Version.java index 0aa2b91cfa478..814ec6c0d827e 100644 --- a/server/src/main/java/org/opensearch/Version.java +++ b/server/src/main/java/org/opensearch/Version.java @@ -32,6 +32,7 @@ package org.opensearch; +import com.google.protobuf.CodedInputStream; import org.opensearch.cluster.metadata.IndexMetadata; import org.opensearch.common.Strings; import org.opensearch.common.SuppressForbidden; @@ -100,6 +101,10 @@ public static Version readVersion(StreamInput in) throws IOException { return fromId(in.readVInt()); } + public static Version readVersionProtobuf(CodedInputStream in) throws IOException { + return fromId(in.readInt32()); + } + public static Version fromId(int id) { final Version known = LegacyESVersion.idToVersion.get(id); if (known != null) { diff --git a/server/src/main/java/org/opensearch/action/ProtobufActionRequest.java b/server/src/main/java/org/opensearch/action/ProtobufActionRequest.java new file mode 100644 index 0000000000000..013ac5cacb776 --- /dev/null +++ b/server/src/main/java/org/opensearch/action/ProtobufActionRequest.java @@ -0,0 +1,53 @@ +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +/* +* Modifications Copyright OpenSearch Contributors. See +* GitHub history for details. +*/ + +package org.opensearch.action; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import org.opensearch.transport.ProtobufTransportRequest; + +import java.io.IOException; + +/** + * Base action request implemented by plugins. +* +* @opensearch.api +*/ +public abstract class ProtobufActionRequest extends ProtobufTransportRequest { + + public ProtobufActionRequest() { + super(); + // this does not set the listenerThreaded API, if needed, its up to the caller to set it + // since most times, we actually want it to not be threaded... + // this.listenerThreaded = request.listenerThreaded(); + } + + public ProtobufActionRequest(CodedInputStream in) throws IOException { + super(in); + } + + public abstract ActionRequestValidationException validate(); + + /** + * Should this task store its result after it has finished? + */ + public boolean getShouldStoreResult() { + return false; + } + + @Override + public void writeTo(CodedOutputStream out) throws IOException { + super.writeTo(out); + } +} diff --git a/server/src/main/java/org/opensearch/action/ProtobufActionRequestBuilder.java b/server/src/main/java/org/opensearch/action/ProtobufActionRequestBuilder.java new file mode 100644 index 0000000000000..33c0e46f5fc92 --- /dev/null +++ b/server/src/main/java/org/opensearch/action/ProtobufActionRequestBuilder.java @@ -0,0 +1,67 @@ +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +package org.opensearch.action; + +import org.opensearch.client.OpenSearchClient; +import org.opensearch.client.ProtobufOpenSearchClient; +import org.opensearch.common.unit.TimeValue; + +import java.util.Objects; + +/** + * Base Action Request Builder +* +* @opensearch.api +*/ +public abstract class ProtobufActionRequestBuilder { + + protected final ProtobufActionType action; + protected final Request request; + protected final ProtobufOpenSearchClient client; + + protected ProtobufActionRequestBuilder(ProtobufOpenSearchClient client, ProtobufActionType action, Request request) { + Objects.requireNonNull(action, "action must not be null"); + this.action = action; + this.request = request; + this.client = client; + } + + public Request request() { + return this.request; + } + + public ActionFuture execute() { + return client.execute(action, request); + } + + /** + * Short version of execute().actionGet(). + */ + public Response get() { + return execute().actionGet(); + } + + /** + * Short version of execute().actionGet(). + */ + public Response get(TimeValue timeout) { + return execute().actionGet(timeout); + } + + /** + * Short version of execute().actionGet(). + */ + public Response get(String timeout) { + return execute().actionGet(timeout); + } + + public void execute(ActionListener listener) { + client.execute(action, request, listener); + } +} diff --git a/server/src/main/java/org/opensearch/action/ProtobufActionResponse.java b/server/src/main/java/org/opensearch/action/ProtobufActionResponse.java new file mode 100644 index 0000000000000..f6cf420cb86fd --- /dev/null +++ b/server/src/main/java/org/opensearch/action/ProtobufActionResponse.java @@ -0,0 +1,33 @@ +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +/* +* Modifications Copyright OpenSearch Contributors. See +* GitHub history for details. +*/ + +package org.opensearch.action; + +import com.google.protobuf.CodedInputStream; +import org.opensearch.transport.ProtobufTransportResponse; + +import java.io.IOException; + +/** + * Base class for responses to action requests implemented by plugins. +* +* @opensearch.api +*/ +public abstract class ProtobufActionResponse extends ProtobufTransportResponse { + + public ProtobufActionResponse() {} + + public ProtobufActionResponse(CodedInputStream in) throws IOException { + super(in); + } +} diff --git a/server/src/main/java/org/opensearch/action/ProtobufActionType.java b/server/src/main/java/org/opensearch/action/ProtobufActionType.java new file mode 100644 index 0000000000000..911419fb67677 --- /dev/null +++ b/server/src/main/java/org/opensearch/action/ProtobufActionType.java @@ -0,0 +1,65 @@ +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +package org.opensearch.action; + +import org.opensearch.common.io.stream.ProtobufWriteable; +import org.opensearch.common.io.stream.Writeable; +import org.opensearch.common.settings.Settings; +import org.opensearch.transport.TransportRequestOptions; + +/** + * A generic action. Should strive to make it a singleton. +* +* @opensearch.api +*/ +public class ProtobufActionType { + + private final String name; + private final ProtobufWriteable.Reader responseReader; + + /** + * @param name The name of the action, must be unique across actions. + * @param responseReader A reader for the response type + */ + public ProtobufActionType(String name, ProtobufWriteable.Reader responseReader) { + this.name = name; + this.responseReader = responseReader; + } + + /** + * The name of the action. Must be unique across actions. + */ + public String name() { + return this.name; + } + + /** + * Get a reader that can create a new instance of the class from a {@link org.opensearch.common.io.stream.StreamInput} + */ + public ProtobufWriteable.Reader getResponseReader() { + return responseReader; + } + + /** + * Optional request options for the action. + */ + public TransportRequestOptions transportOptions(Settings settings) { + return TransportRequestOptions.EMPTY; + } + + @Override + public boolean equals(Object o) { + return o instanceof ProtobufActionType && name.equals(((ProtobufActionType) o).name()); + } + + @Override + public int hashCode() { + return name.hashCode(); + } +} diff --git a/server/src/main/java/org/opensearch/action/ProtobufFailedNodeException.java b/server/src/main/java/org/opensearch/action/ProtobufFailedNodeException.java new file mode 100644 index 0000000000000..511d933391c00 --- /dev/null +++ b/server/src/main/java/org/opensearch/action/ProtobufFailedNodeException.java @@ -0,0 +1,46 @@ +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +package org.opensearch.action; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import org.opensearch.ProtobufOpenSearchException; +import org.opensearch.common.io.stream.ProtobufWriteable; + +import java.io.IOException; + +/** + * Base exception for a failed node +* +* @opensearch.internal +*/ +public class ProtobufFailedNodeException extends ProtobufOpenSearchException implements ProtobufWriteable { + + private final String nodeId; + + public ProtobufFailedNodeException(String nodeId, String msg, Throwable cause) { + super(msg); + this.nodeId = nodeId; + } + + public String nodeId() { + return this.nodeId; + } + + public ProtobufFailedNodeException(CodedInputStream in) throws IOException { + super(in); + nodeId = in.readString(); + } + + @Override + public void writeTo(CodedOutputStream out) throws IOException { + super.writeTo(out); + out.writeStringNoTag(nodeId); + } +} diff --git a/server/src/main/java/org/opensearch/action/admin/cluster/node/info/ProtobufNodeInfo.java b/server/src/main/java/org/opensearch/action/admin/cluster/node/info/ProtobufNodeInfo.java new file mode 100644 index 0000000000000..0d1b03ae29d07 --- /dev/null +++ b/server/src/main/java/org/opensearch/action/admin/cluster/node/info/ProtobufNodeInfo.java @@ -0,0 +1,335 @@ +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +/* +* Modifications Copyright OpenSearch Contributors. See +* GitHub history for details. +*/ + +package org.opensearch.action.admin.cluster.node.info; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import org.opensearch.Build; +import org.opensearch.Version; +import org.opensearch.action.support.nodes.ProtobufBaseNodeResponse; +import org.opensearch.cluster.node.ProtobufDiscoveryNode; +import org.opensearch.common.Nullable; +import org.opensearch.common.io.stream.ProtobufStreamInput; +import org.opensearch.common.io.stream.ProtobufStreamOutput; +import org.opensearch.common.settings.Settings; +import org.opensearch.common.unit.ByteSizeValue; +import org.opensearch.http.ProtobufHttpInfo; +import org.opensearch.ingest.ProtobufIngestInfo; +import org.opensearch.monitor.jvm.JvmInfo; +import org.opensearch.monitor.jvm.ProtobufJvmInfo; +import org.opensearch.monitor.os.OsInfo; +import org.opensearch.monitor.os.ProtobufOsInfo; +import org.opensearch.monitor.process.ProtobufProcessInfo; +import org.opensearch.node.ProtobufReportingService; +import org.opensearch.search.aggregations.support.ProtobufAggregationInfo; +import org.opensearch.search.pipeline.ProtobufSearchPipelineInfo; +import org.opensearch.threadpool.ProtobufThreadPoolInfo; +import org.opensearch.transport.ProtobufTransportInfo; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * Node information (static, does not change over time). +* +* @opensearch.internal +*/ +public class ProtobufNodeInfo extends ProtobufBaseNodeResponse { + + private Version version; + private Build build; + + @Nullable + private Settings settings; + + /** + * Do not expose this map to other classes. For type safety, use {@link #getInfo(Class)} + * to retrieve items from this map and {@link #addInfoIfNonNull(Class, ProtobufReportingService.ProtobufInfo)} + * to retrieve items from it. + */ + private Map, ProtobufReportingService.ProtobufInfo> infoMap = new HashMap<>(); + + @Nullable + private ByteSizeValue totalIndexingBuffer; + + public ProtobufNodeInfo(CodedInputStream in) throws IOException { + super(in); + ProtobufStreamInput protobufStreamInput = new ProtobufStreamInput(); + version = Version.readVersionProtobuf(in); + build = Build.readBuildProtobuf(in); + if (in.readBool()) { + totalIndexingBuffer = new ByteSizeValue(in.readInt64()); + } else { + totalIndexingBuffer = null; + } + if (in.readBool()) { + settings = Settings.readSettingsFromStreamProtobuf(in); + } + addInfoIfNonNull(ProtobufOsInfo.class, protobufStreamInput.readOptionalWriteable(ProtobufOsInfo::new, in)); + addInfoIfNonNull(ProtobufProcessInfo.class, protobufStreamInput.readOptionalWriteable(ProtobufProcessInfo::new, in)); + addInfoIfNonNull(ProtobufJvmInfo.class, protobufStreamInput.readOptionalWriteable(ProtobufJvmInfo::new, in)); + addInfoIfNonNull(ProtobufThreadPoolInfo.class, protobufStreamInput.readOptionalWriteable(ProtobufThreadPoolInfo::new, in)); + addInfoIfNonNull(ProtobufTransportInfo.class, protobufStreamInput.readOptionalWriteable(ProtobufTransportInfo::new, in)); + addInfoIfNonNull(ProtobufHttpInfo.class, protobufStreamInput.readOptionalWriteable(ProtobufHttpInfo::new, in)); + addInfoIfNonNull(ProtobufPluginsAndModules.class, protobufStreamInput.readOptionalWriteable(ProtobufPluginsAndModules::new, in)); + addInfoIfNonNull(ProtobufIngestInfo.class, protobufStreamInput.readOptionalWriteable(ProtobufIngestInfo::new, in)); + addInfoIfNonNull(ProtobufAggregationInfo.class, protobufStreamInput.readOptionalWriteable(ProtobufAggregationInfo::new, in)); + if (protobufStreamInput.getVersion().onOrAfter(Version.V_2_7_0)) { + addInfoIfNonNull( + ProtobufSearchPipelineInfo.class, + protobufStreamInput.readOptionalWriteable(ProtobufSearchPipelineInfo::new, in) + ); + } + } + + public ProtobufNodeInfo( + Version version, + Build build, + ProtobufDiscoveryNode node, + @Nullable Settings settings, + @Nullable ProtobufOsInfo os, + @Nullable ProtobufProcessInfo process, + @Nullable ProtobufJvmInfo jvm, + @Nullable ProtobufThreadPoolInfo threadPool, + @Nullable ProtobufTransportInfo transport, + @Nullable ProtobufHttpInfo http, + @Nullable ProtobufPluginsAndModules plugins, + @Nullable ProtobufIngestInfo ingest, + @Nullable ProtobufAggregationInfo aggsInfo, + @Nullable ByteSizeValue totalIndexingBuffer, + @Nullable ProtobufSearchPipelineInfo ProtobufSearchPipelineInfo + ) { + super(node); + this.version = version; + this.build = build; + this.settings = settings; + addInfoIfNonNull(ProtobufOsInfo.class, os); + addInfoIfNonNull(ProtobufProcessInfo.class, process); + addInfoIfNonNull(ProtobufJvmInfo.class, jvm); + addInfoIfNonNull(ProtobufThreadPoolInfo.class, threadPool); + addInfoIfNonNull(ProtobufTransportInfo.class, transport); + addInfoIfNonNull(ProtobufHttpInfo.class, http); + addInfoIfNonNull(ProtobufPluginsAndModules.class, plugins); + addInfoIfNonNull(ProtobufIngestInfo.class, ingest); + addInfoIfNonNull(ProtobufAggregationInfo.class, aggsInfo); + addInfoIfNonNull(ProtobufSearchPipelineInfo.class, ProtobufSearchPipelineInfo); + this.totalIndexingBuffer = totalIndexingBuffer; + } + + /** + * System's hostname. null in case of UnknownHostException + */ + @Nullable + public String getHostname() { + return getNode().getHostName(); + } + + /** + * The current OpenSearch version + */ + public Version getVersion() { + return version; + } + + /** + * The build version of the node. + */ + public Build getBuild() { + return this.build; + } + + /** + * The settings of the node. + */ + @Nullable + public Settings getSettings() { + return this.settings; + } + + /** + * Get a particular info object, e.g. {@link JvmInfo} or {@link OsInfo}. This + * generic method handles all casting in order to spare client classes the + * work of explicit casts. This {@link NodeInfo} class guarantees type + * safety for these stored info blocks. + * + * @param clazz Class for retrieval. + * @param Specific subtype of ReportingService.ProtobufInfo to retrieve. + * @return An object of type T. + */ + public T getInfo(Class clazz) { + return clazz.cast(infoMap.get(clazz)); + } + + @Nullable + public ByteSizeValue getTotalIndexingBuffer() { + return totalIndexingBuffer; + } + + /** + * Add a value to the map of information blocks. This method guarantees the + * type safety of the storage of heterogeneous types of reporting service information. + */ + private void addInfoIfNonNull(Class clazz, T info) { + if (info != null) { + infoMap.put(clazz, info); + } + } + + @Override + public void writeTo(CodedOutputStream out) throws IOException { + super.writeTo(out); + ProtobufStreamOutput protobufStreamOutput = new ProtobufStreamOutput(); + out.writeInt32NoTag(version.id); + Build.writeBuildProtobuf(build, out); + if (totalIndexingBuffer == null) { + out.writeBoolNoTag(false); + } else { + out.writeBoolNoTag(true); + out.writeInt64NoTag(totalIndexingBuffer.getBytes()); + } + if (settings == null) { + out.writeBoolNoTag(false); + } else { + out.writeBoolNoTag(true); + Settings.writeSettingsToStreamProtobuf(settings, out); + } + protobufStreamOutput.writeOptionalWriteable(getInfo(ProtobufOsInfo.class), out); + protobufStreamOutput.writeOptionalWriteable(getInfo(ProtobufProcessInfo.class), out); + protobufStreamOutput.writeOptionalWriteable(getInfo(ProtobufJvmInfo.class), out); + protobufStreamOutput.writeOptionalWriteable(getInfo(ProtobufThreadPoolInfo.class), out); + protobufStreamOutput.writeOptionalWriteable(getInfo(ProtobufTransportInfo.class), out); + protobufStreamOutput.writeOptionalWriteable(getInfo(ProtobufHttpInfo.class), out); + protobufStreamOutput.writeOptionalWriteable(getInfo(ProtobufPluginsAndModules.class), out); + protobufStreamOutput.writeOptionalWriteable(getInfo(ProtobufIngestInfo.class), out); + protobufStreamOutput.writeOptionalWriteable(getInfo(ProtobufAggregationInfo.class), out); + if (protobufStreamOutput.getVersion().onOrAfter(Version.V_2_7_0)) { + protobufStreamOutput.writeOptionalWriteable(getInfo(ProtobufSearchPipelineInfo.class), out); + } + } + + public static ProtobufNodeInfo.Builder builder(Version version, Build build, ProtobufDiscoveryNode node) { + return new Builder(version, build, node); + } + + /** + * Builder class to accommodate new Info types being added to NodeInfo. + */ + public static class Builder { + private final Version version; + private final Build build; + private final ProtobufDiscoveryNode node; + + private Builder(Version version, Build build, ProtobufDiscoveryNode node) { + this.version = version; + this.build = build; + this.node = node; + } + + private Settings settings; + private ProtobufOsInfo os; + private ProtobufProcessInfo process; + private ProtobufJvmInfo jvm; + private ProtobufThreadPoolInfo threadPool; + private ProtobufTransportInfo transport; + private ProtobufHttpInfo http; + private ProtobufPluginsAndModules plugins; + private ProtobufIngestInfo ingest; + private ProtobufAggregationInfo aggsInfo; + private ByteSizeValue totalIndexingBuffer; + private ProtobufSearchPipelineInfo ProtobufSearchPipelineInfo; + + public Builder setSettings(Settings settings) { + this.settings = settings; + return this; + } + + public Builder setOs(ProtobufOsInfo os) { + this.os = os; + return this; + } + + public Builder setProcess(ProtobufProcessInfo process) { + this.process = process; + return this; + } + + public Builder setJvm(ProtobufJvmInfo jvm) { + this.jvm = jvm; + return this; + } + + public Builder setThreadPool(ProtobufThreadPoolInfo threadPool) { + this.threadPool = threadPool; + return this; + } + + public Builder setTransport(ProtobufTransportInfo transport) { + this.transport = transport; + return this; + } + + public Builder setHttp(ProtobufHttpInfo http) { + this.http = http; + return this; + } + + public Builder setPlugins(ProtobufPluginsAndModules plugins) { + this.plugins = plugins; + return this; + } + + public Builder setIngest(ProtobufIngestInfo ingest) { + this.ingest = ingest; + return this; + } + + public Builder setAggsInfo(ProtobufAggregationInfo aggsInfo) { + this.aggsInfo = aggsInfo; + return this; + } + + public Builder setTotalIndexingBuffer(ByteSizeValue totalIndexingBuffer) { + this.totalIndexingBuffer = totalIndexingBuffer; + return this; + } + + public Builder setProtobufSearchPipelineInfo(ProtobufSearchPipelineInfo ProtobufSearchPipelineInfo) { + this.ProtobufSearchPipelineInfo = ProtobufSearchPipelineInfo; + return this; + } + + public ProtobufNodeInfo build() { + return new ProtobufNodeInfo( + version, + build, + node, + settings, + os, + process, + jvm, + threadPool, + transport, + http, + plugins, + ingest, + aggsInfo, + totalIndexingBuffer, + ProtobufSearchPipelineInfo + ); + } + + } + +} diff --git a/server/src/main/java/org/opensearch/action/admin/cluster/node/info/ProtobufNodesInfoRequest.java b/server/src/main/java/org/opensearch/action/admin/cluster/node/info/ProtobufNodesInfoRequest.java new file mode 100644 index 0000000000000..04de76bb281fe --- /dev/null +++ b/server/src/main/java/org/opensearch/action/admin/cluster/node/info/ProtobufNodesInfoRequest.java @@ -0,0 +1,165 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +/* + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.action.admin.cluster.node.info; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import org.opensearch.action.support.nodes.ProtobufBaseNodesRequest; +import org.opensearch.common.io.stream.ProtobufStreamInput; +import org.opensearch.common.io.stream.ProtobufStreamOutput; +import org.opensearch.common.io.stream.StreamInput; + +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.stream.Collectors; + +/** + * A request to get node (cluster) level information. + * + * @opensearch.internal + */ +public class ProtobufNodesInfoRequest extends ProtobufBaseNodesRequest { + + private Set requestedMetrics = Metric.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 ProtobufNodesInfoRequest(CodedInputStream in) throws IOException { + super(in); + ProtobufStreamInput protobufStreamInput = new ProtobufStreamInput(); + requestedMetrics.clear(); + requestedMetrics.addAll(Arrays.asList(protobufStreamInput.readStringArray(in))); + } + + /** + * Get information from nodes based on the nodes ids specified. If none are passed, information + * for all nodes will be returned. + */ + public ProtobufNodesInfoRequest(String... nodesIds) { + super(nodesIds); + all(); + } + + /** + * Clears all info flags. + */ + public ProtobufNodesInfoRequest clear() { + requestedMetrics.clear(); + return this; + } + + /** + * Sets to return all the data. + */ + public ProtobufNodesInfoRequest all() { + requestedMetrics.addAll(Metric.allMetrics()); + return this; + } + + /** + * Get the names of requested metrics + */ + public Set requestedMetrics() { + return new HashSet<>(requestedMetrics); + } + + /** + * Add metric + */ + public ProtobufNodesInfoRequest addMetric(String metric) { + if (Metric.allMetrics().contains(metric) == false) { + throw new IllegalStateException("Used an illegal metric: " + metric); + } + requestedMetrics.add(metric); + return this; + } + + /** + * Add multiple metrics + */ + public ProtobufNodesInfoRequest addMetrics(String... metrics) { + SortedSet metricsSet = new TreeSet<>(Arrays.asList(metrics)); + if (Metric.allMetrics().containsAll(metricsSet) == false) { + metricsSet.removeAll(Metric.allMetrics()); + String plural = metricsSet.size() == 1 ? "" : "s"; + throw new IllegalStateException("Used illegal metric" + plural + ": " + metricsSet); + } + requestedMetrics.addAll(metricsSet); + return this; + } + + /** + * Remove metric + */ + public ProtobufNodesInfoRequest removeMetric(String metric) { + if (Metric.allMetrics().contains(metric) == false) { + throw new IllegalStateException("Used an illegal metric: " + metric); + } + requestedMetrics.remove(metric); + return this; + } + + @Override + public void writeTo(CodedOutputStream out) throws IOException { + super.writeTo(out); + ProtobufStreamOutput protobufStreamOutput = new ProtobufStreamOutput(); + protobufStreamOutput.writeStringArray(requestedMetrics.toArray(new String[0]), out); + } + + /** + * An enumeration of the "core" sections of metrics that may be requested + * from the nodes information endpoint. Eventually this list list will be + * pluggable. + */ + public enum Metric { + SETTINGS("settings"), + OS("os"), + PROCESS("process"), + JVM("jvm"), + THREAD_POOL("thread_pool"), + TRANSPORT("transport"), + HTTP("http"), + PLUGINS("plugins"), + INGEST("ingest"), + AGGREGATIONS("aggregations"), + INDICES("indices"), + SEARCH_PIPELINES("search_pipelines"); + + private String metricName; + + Metric(String name) { + this.metricName = name; + } + + public String metricName() { + return this.metricName; + } + + boolean containedIn(Set metricNames) { + return metricNames.contains(this.metricName()); + } + + public static Set allMetrics() { + return Arrays.stream(values()).map(Metric::metricName).collect(Collectors.toSet()); + } + } +} diff --git a/server/src/main/java/org/opensearch/action/admin/cluster/node/info/ProtobufNodesInfoResponse.java b/server/src/main/java/org/opensearch/action/admin/cluster/node/info/ProtobufNodesInfoResponse.java new file mode 100644 index 0000000000000..a7d5274fcf09a --- /dev/null +++ b/server/src/main/java/org/opensearch/action/admin/cluster/node/info/ProtobufNodesInfoResponse.java @@ -0,0 +1,76 @@ +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +/* +* Licensed to Elasticsearch under one or more contributor +* license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright +* ownership. Elasticsearch licenses this file to you under +* the Apache License, Version 2.0 (the "License"); you may +* not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +/* +* Modifications Copyright OpenSearch Contributors. See +* GitHub history for details. +*/ + +package org.opensearch.action.admin.cluster.node.info; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import org.opensearch.action.ProtobufFailedNodeException; +import org.opensearch.action.support.nodes.ProtobufBaseNodesResponse; +import org.opensearch.cluster.ProtobufClusterName; +import org.opensearch.common.io.stream.ProtobufStreamInput; +import org.opensearch.common.io.stream.ProtobufStreamOutput; + +import java.io.IOException; +import java.util.List; + +/** + * Transport response for OpenSearch Node Information +* +* @opensearch.internal +*/ +public class ProtobufNodesInfoResponse extends ProtobufBaseNodesResponse { + + public ProtobufNodesInfoResponse(CodedInputStream in) throws IOException { + super(in); + } + + public ProtobufNodesInfoResponse( + ProtobufClusterName clusterName, + List nodes, + List failures + ) { + super(clusterName, nodes, failures); + } + + @Override + protected List readNodesFrom(CodedInputStream in) throws IOException { + ProtobufStreamInput protobufStreamInput = new ProtobufStreamInput(); + return protobufStreamInput.readList(ProtobufNodeInfo::new, in); + } + + @Override + protected void writeNodesTo(CodedOutputStream out, List nodes) throws IOException { + ProtobufStreamOutput protobufStreamOutput = new ProtobufStreamOutput(); + protobufStreamOutput.writeCollection(nodes, (o, v) -> v.writeTo(o), out); + } +} diff --git a/server/src/main/java/org/opensearch/action/admin/cluster/node/info/ProtobufPluginsAndModules.java b/server/src/main/java/org/opensearch/action/admin/cluster/node/info/ProtobufPluginsAndModules.java new file mode 100644 index 0000000000000..1df8383a78736 --- /dev/null +++ b/server/src/main/java/org/opensearch/action/admin/cluster/node/info/ProtobufPluginsAndModules.java @@ -0,0 +1,77 @@ +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +package org.opensearch.action.admin.cluster.node.info; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; + +import org.opensearch.common.io.stream.ProtobufStreamInput; +import org.opensearch.common.io.stream.ProtobufStreamOutput; +import org.opensearch.node.ProtobufReportingService; +import org.opensearch.plugins.ProtobufPluginInfo; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * Information about plugins and modules +* +* @opensearch.internal +*/ +public class ProtobufPluginsAndModules implements ProtobufReportingService.ProtobufInfo { + private final List plugins; + private final List modules; + + public ProtobufPluginsAndModules(List plugins, List modules) { + this.plugins = Collections.unmodifiableList(plugins); + this.modules = Collections.unmodifiableList(modules); + } + + public ProtobufPluginsAndModules(CodedInputStream in) throws IOException { + ProtobufStreamInput protobufStreamInput = new ProtobufStreamInput(); + this.plugins = Collections.unmodifiableList(protobufStreamInput.readList(ProtobufPluginInfo::new, in)); + this.modules = Collections.unmodifiableList(protobufStreamInput.readList(ProtobufPluginInfo::new, in)); + } + + @Override + public void writeTo(CodedOutputStream out) throws IOException { + ProtobufStreamOutput protobufStreamOutput = new ProtobufStreamOutput(); + protobufStreamOutput.writeCollection(plugins, (o, v) -> v.writeTo(o), out); + protobufStreamOutput.writeCollection(modules, (o, v) -> v.writeTo(o), out); + } + + /** + * Returns an ordered list based on plugins name + */ + public List getPluginInfos() { + List plugins = new ArrayList<>(this.plugins); + Collections.sort(plugins, Comparator.comparing(ProtobufPluginInfo::getName)); + return plugins; + } + + /** + * Returns an ordered list based on modules name + */ + public List getModuleInfos() { + List modules = new ArrayList<>(this.modules); + Collections.sort(modules, Comparator.comparing(ProtobufPluginInfo::getName)); + return modules; + } + + public void addPlugin(ProtobufPluginInfo info) { + plugins.add(info); + } + + public void addModule(ProtobufPluginInfo info) { + modules.add(info); + } +} diff --git a/server/src/main/java/org/opensearch/action/admin/cluster/node/stats/ProtobufNodesStatsRequest.java b/server/src/main/java/org/opensearch/action/admin/cluster/node/stats/ProtobufNodesStatsRequest.java new file mode 100644 index 0000000000000..d55b511eb0170 --- /dev/null +++ b/server/src/main/java/org/opensearch/action/admin/cluster/node/stats/ProtobufNodesStatsRequest.java @@ -0,0 +1,202 @@ +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +package org.opensearch.action.admin.cluster.node.stats; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import org.opensearch.action.admin.indices.stats.CommonStatsFlags; +import org.opensearch.action.admin.indices.stats.ProtobufCommonStatsFlags; +import org.opensearch.action.support.nodes.BaseNodesRequest; +import org.opensearch.action.support.nodes.ProtobufBaseNodesRequest; +import org.opensearch.common.io.stream.StreamInput; +import org.opensearch.common.io.stream.StreamOutput; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.stream.Collectors; + +/** + * A request to get node (cluster) level stats. +* +* @opensearch.internal +*/ +public class ProtobufNodesStatsRequest extends ProtobufBaseNodesRequest { + + private ProtobufCommonStatsFlags indices = new ProtobufCommonStatsFlags(); + private final Set requestedMetrics = new HashSet<>(); + + public ProtobufNodesStatsRequest() { + super((String[]) null); + } + + public ProtobufNodesStatsRequest(CodedInputStream in) throws IOException { + super(in); + + indices = new ProtobufCommonStatsFlags(in); + requestedMetrics.clear(); + requestedMetrics.addAll(in.readStringList()); + } + + /** + * Get stats from nodes based on the nodes ids specified. If none are passed, stats + * for all nodes will be returned. + */ + public ProtobufNodesStatsRequest(String... nodesIds) { + super(nodesIds); + } + + /** + * Sets all the request flags. + */ + public ProtobufNodesStatsRequest all() { + this.indices.all(); + this.requestedMetrics.addAll(Metric.allMetrics()); + return this; + } + + /** + * Clears all the request flags. + */ + public ProtobufNodesStatsRequest clear() { + this.indices.clear(); + this.requestedMetrics.clear(); + return this; + } + + /** + * Get indices. Handles separately from other metrics because it may or + * may not have submetrics. + * @return flags indicating which indices stats to return + */ + public ProtobufCommonStatsFlags indices() { + return indices; + } + + /** + * Set indices. Handles separately from other metrics because it may or + * may not involve submetrics. + * @param indices flags indicating which indices stats to return + * @return This object, for request chaining. + */ + public ProtobufNodesStatsRequest indices(ProtobufCommonStatsFlags indices) { + this.indices = indices; + return this; + } + + /** + * Should indices stats be returned. + */ + public ProtobufNodesStatsRequest indices(boolean indices) { + if (indices) { + this.indices.all(); + } else { + this.indices.clear(); + } + return this; + } + + /** + * Get the names of requested metrics, excluding indices, which are + * handled separately. + */ + public Set requestedMetrics() { + return new HashSet<>(requestedMetrics); + } + + /** + * Add metric + */ + public ProtobufNodesStatsRequest addMetric(String metric) { + if (Metric.allMetrics().contains(metric) == false) { + throw new IllegalStateException("Used an illegal metric: " + metric); + } + requestedMetrics.add(metric); + return this; + } + + /** + * Add an array of metric names + */ + public ProtobufNodesStatsRequest addMetrics(String... metrics) { + // use sorted set for reliable ordering in error messages + SortedSet metricsSet = new TreeSet<>(Arrays.asList(metrics)); + if (Metric.allMetrics().containsAll(metricsSet) == false) { + metricsSet.removeAll(Metric.allMetrics()); + String plural = metricsSet.size() == 1 ? "" : "s"; + throw new IllegalStateException("Used illegal metric" + plural + ": " + metricsSet); + } + requestedMetrics.addAll(metricsSet); + return this; + } + + /** + * Remove metric + */ + public ProtobufNodesStatsRequest removeMetric(String metric) { + if (Metric.allMetrics().contains(metric) == false) { + throw new IllegalStateException("Used an illegal metric: " + metric); + } + requestedMetrics.remove(metric); + return this; + } + + @Override + public void writeTo(CodedOutputStream out) throws IOException { + super.writeTo(out); + indices.writeTo(out); + out.writeStringArray(requestedMetrics.toArray(new String[0])); + } + + /** + * An enumeration of the "core" sections of metrics that may be requested + * from the nodes stats endpoint. Eventually this list will be pluggable. + */ + public enum Metric { + OS("os"), + PROCESS("process"), + JVM("jvm"), + THREAD_POOL("thread_pool"), + FS("fs"), + TRANSPORT("transport"), + HTTP("http"), + BREAKER("breaker"), + SCRIPT("script"), + DISCOVERY("discovery"), + INGEST("ingest"), + ADAPTIVE_SELECTION("adaptive_selection"), + SCRIPT_CACHE("script_cache"), + INDEXING_PRESSURE("indexing_pressure"), + SHARD_INDEXING_PRESSURE("shard_indexing_pressure"), + SEARCH_BACKPRESSURE("search_backpressure"), + CLUSTER_MANAGER_THROTTLING("cluster_manager_throttling"), + WEIGHTED_ROUTING_STATS("weighted_routing"), + FILE_CACHE_STATS("file_cache"); + + private String metricName; + + Metric(String name) { + this.metricName = name; + } + + public String metricName() { + return this.metricName; + } + + boolean containedIn(Set metricNames) { + return metricNames.contains(this.metricName()); + } + + static Set allMetrics() { + return Arrays.stream(values()).map(Metric::metricName).collect(Collectors.toSet()); + } + } +} diff --git a/server/src/main/java/org/opensearch/action/admin/cluster/state/ProtobufClusterStateAction.java b/server/src/main/java/org/opensearch/action/admin/cluster/state/ProtobufClusterStateAction.java new file mode 100644 index 0000000000000..5ab9aa023a298 --- /dev/null +++ b/server/src/main/java/org/opensearch/action/admin/cluster/state/ProtobufClusterStateAction.java @@ -0,0 +1,27 @@ +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +package org.opensearch.action.admin.cluster.state; + +import org.opensearch.action.ActionType; +import org.opensearch.action.ProtobufActionType; + +/** + * Transport action for obtaining cluster state +* +* @opensearch.internal +*/ +public class ProtobufClusterStateAction extends ProtobufActionType { + + public static final ProtobufClusterStateAction INSTANCE = new ProtobufClusterStateAction(); + public static final String NAME = "cluster:monitor/state"; + + private ProtobufClusterStateAction() { + super(NAME, ProtobufClusterStateResponse::new); + } +} diff --git a/server/src/main/java/org/opensearch/action/admin/cluster/state/ProtobufClusterStateRequest.java b/server/src/main/java/org/opensearch/action/admin/cluster/state/ProtobufClusterStateRequest.java new file mode 100644 index 0000000000000..6798c3b8c46e5 --- /dev/null +++ b/server/src/main/java/org/opensearch/action/admin/cluster/state/ProtobufClusterStateRequest.java @@ -0,0 +1,199 @@ +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +/* +* Modifications Copyright OpenSearch Contributors. See +* GitHub history for details. +*/ + +package org.opensearch.action.admin.cluster.state; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.action.IndicesRequest; +import org.opensearch.action.support.IndicesOptions; +import org.opensearch.action.support.clustermanager.ProtobufClusterManagerNodeReadRequest; +import org.opensearch.common.Strings; +import org.opensearch.common.io.stream.ProtobufStreamInput; +import org.opensearch.common.io.stream.ProtobufStreamOutput; +import org.opensearch.common.unit.TimeValue; + +import java.io.IOException; + +/** + * Transport request for obtaining cluster state +* +* @opensearch.internal +*/ +public class ProtobufClusterStateRequest extends ProtobufClusterManagerNodeReadRequest + implements + IndicesRequest.Replaceable { + + public static final TimeValue DEFAULT_WAIT_FOR_NODE_TIMEOUT = TimeValue.timeValueMinutes(1); + + private boolean routingTable = true; + private boolean nodes = true; + private boolean metadata = true; + private boolean blocks = true; + private boolean customs = true; + private Long waitForMetadataVersion; + private TimeValue waitForTimeout = DEFAULT_WAIT_FOR_NODE_TIMEOUT; + private String[] indices = Strings.EMPTY_ARRAY; + private IndicesOptions indicesOptions = IndicesOptions.lenientExpandOpen(); + + public ProtobufClusterStateRequest() {} + + public ProtobufClusterStateRequest(CodedInputStream in) throws IOException { + super(in); + ProtobufStreamInput protobufStreamInput = new ProtobufStreamInput(); + routingTable = in.readBool(); + nodes = in.readBool(); + metadata = in.readBool(); + blocks = in.readBool(); + customs = in.readBool(); + indices = protobufStreamInput.readStringArray(in); + indicesOptions = IndicesOptions.readIndicesOptionsProtobuf(in); + waitForTimeout = protobufStreamInput.readTimeValue(in); + waitForMetadataVersion = protobufStreamInput.readOptionalLong(in); + } + + @Override + public void writeTo(CodedOutputStream out) throws IOException { + super.writeTo(out); + ProtobufStreamOutput protobufStreamOutput = new ProtobufStreamOutput(); + out.writeBoolNoTag(routingTable); + out.writeBoolNoTag(nodes); + out.writeBoolNoTag(metadata); + out.writeBoolNoTag(blocks); + out.writeBoolNoTag(customs); + protobufStreamOutput.writeStringArray(indices, out); + indicesOptions.writeIndicesOptionsProtobuf(out); + protobufStreamOutput.writeTimeValue(waitForTimeout, out); + protobufStreamOutput.writeOptionalLong(waitForMetadataVersion, out); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + public ProtobufClusterStateRequest all() { + routingTable = true; + nodes = true; + metadata = true; + blocks = true; + customs = true; + indices = Strings.EMPTY_ARRAY; + return this; + } + + public ProtobufClusterStateRequest clear() { + routingTable = false; + nodes = false; + metadata = false; + blocks = false; + customs = false; + indices = Strings.EMPTY_ARRAY; + return this; + } + + public boolean routingTable() { + return routingTable; + } + + public ProtobufClusterStateRequest routingTable(boolean routingTable) { + this.routingTable = routingTable; + return this; + } + + public boolean nodes() { + return nodes; + } + + public ProtobufClusterStateRequest nodes(boolean nodes) { + this.nodes = nodes; + return this; + } + + public boolean metadata() { + return metadata; + } + + public ProtobufClusterStateRequest metadata(boolean metadata) { + this.metadata = metadata; + return this; + } + + public boolean blocks() { + return blocks; + } + + public ProtobufClusterStateRequest blocks(boolean blocks) { + this.blocks = blocks; + return this; + } + + @Override + public String[] indices() { + return indices; + } + + @Override + public ProtobufClusterStateRequest indices(String... indices) { + this.indices = indices; + return this; + } + + @Override + public IndicesOptions indicesOptions() { + return this.indicesOptions; + } + + public final ProtobufClusterStateRequest indicesOptions(IndicesOptions indicesOptions) { + this.indicesOptions = indicesOptions; + return this; + } + + @Override + public boolean includeDataStreams() { + return true; + } + + public ProtobufClusterStateRequest customs(boolean customs) { + this.customs = customs; + return this; + } + + public boolean customs() { + return customs; + } + + public TimeValue waitForTimeout() { + return waitForTimeout; + } + + public ProtobufClusterStateRequest waitForTimeout(TimeValue waitForTimeout) { + this.waitForTimeout = waitForTimeout; + return this; + } + + public Long waitForMetadataVersion() { + return waitForMetadataVersion; + } + + public ProtobufClusterStateRequest waitForMetadataVersion(long waitForMetadataVersion) { + if (waitForMetadataVersion < 1) { + throw new IllegalArgumentException( + "provided waitForMetadataVersion should be >= 1, but instead is [" + waitForMetadataVersion + "]" + ); + } + this.waitForMetadataVersion = waitForMetadataVersion; + return this; + } +} diff --git a/server/src/main/java/org/opensearch/action/admin/cluster/state/ProtobufClusterStateRequestBuilder.java b/server/src/main/java/org/opensearch/action/admin/cluster/state/ProtobufClusterStateRequestBuilder.java new file mode 100644 index 0000000000000..6255d47b9bd66 --- /dev/null +++ b/server/src/main/java/org/opensearch/action/admin/cluster/state/ProtobufClusterStateRequestBuilder.java @@ -0,0 +1,119 @@ +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +package org.opensearch.action.admin.cluster.state; + +import org.opensearch.action.support.IndicesOptions; +import org.opensearch.action.support.clustermanager.ClusterManagerNodeReadOperationRequestBuilder; +import org.opensearch.action.support.clustermanager.ProtobufClusterManagerNodeReadOperationRequestBuilder; +import org.opensearch.client.OpenSearchClient; +import org.opensearch.client.ProtobufOpenSearchClient; +import org.opensearch.common.unit.TimeValue; + +/** + * Transport request builder for obtaining cluster state +* +* @opensearch.internal +*/ +public class ProtobufClusterStateRequestBuilder extends ProtobufClusterManagerNodeReadOperationRequestBuilder< + ProtobufClusterStateRequest, + ProtobufClusterStateResponse, + ProtobufClusterStateRequestBuilder> { + + public ProtobufClusterStateRequestBuilder(ProtobufOpenSearchClient client, ProtobufClusterStateAction action) { + super(client, action, new ProtobufClusterStateRequest()); + } + + /** + * Include all data + */ + public ProtobufClusterStateRequestBuilder all() { + request.all(); + return this; + } + + /** + * Do not include any data + */ + public ProtobufClusterStateRequestBuilder clear() { + request.clear(); + return this; + } + + public ProtobufClusterStateRequestBuilder setBlocks(boolean filter) { + request.blocks(filter); + return this; + } + + /** + * Should the cluster state result include the {@link org.opensearch.cluster.metadata.Metadata}. Defaults + * to {@code true}. + */ + public ProtobufClusterStateRequestBuilder setMetadata(boolean filter) { + request.metadata(filter); + return this; + } + + /** + * Should the cluster state result include the {@link org.opensearch.cluster.node.DiscoveryNodes}. Defaults + * to {@code true}. + */ + public ProtobufClusterStateRequestBuilder setNodes(boolean filter) { + request.nodes(filter); + return this; + } + + /** + * Should the cluster state result include the {@link org.opensearch.cluster.ClusterState.Custom}. Defaults + * to {@code true}. + */ + public ProtobufClusterStateRequestBuilder setCustoms(boolean filter) { + request.customs(filter); + return this; + } + + /** + * Should the cluster state result include the {@link org.opensearch.cluster.routing.RoutingTable}. Defaults + * to {@code true}. + */ + public ProtobufClusterStateRequestBuilder setRoutingTable(boolean filter) { + request.routingTable(filter); + return this; + } + + /** + * When {@link #setMetadata(boolean)} is set, which indices to return the {@link org.opensearch.cluster.metadata.IndexMetadata} + * for. Defaults to all indices. + */ + public ProtobufClusterStateRequestBuilder setIndices(String... indices) { + request.indices(indices); + return this; + } + + public ProtobufClusterStateRequestBuilder setIndicesOptions(IndicesOptions indicesOptions) { + request.indicesOptions(indicesOptions); + return this; + } + + /** + * Causes the request to wait for the metadata version to advance to at least the given version. + * @param waitForMetadataVersion The metadata version for which to wait + */ + public ProtobufClusterStateRequestBuilder setWaitForMetadataVersion(long waitForMetadataVersion) { + request.waitForMetadataVersion(waitForMetadataVersion); + return this; + } + + /** + * If {@link ProtobufClusterStateRequest#waitForMetadataVersion()} is set then this determines how long to wait + */ + public ProtobufClusterStateRequestBuilder setWaitForTimeOut(TimeValue waitForTimeout) { + request.waitForTimeout(waitForTimeout); + return this; + } +} diff --git a/server/src/main/java/org/opensearch/action/admin/cluster/state/ProtobufClusterStateResponse.java b/server/src/main/java/org/opensearch/action/admin/cluster/state/ProtobufClusterStateResponse.java new file mode 100644 index 0000000000000..a88e42d78c66a --- /dev/null +++ b/server/src/main/java/org/opensearch/action/admin/cluster/state/ProtobufClusterStateResponse.java @@ -0,0 +1,85 @@ +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +/* +* Modifications Copyright OpenSearch Contributors. See +* GitHub history for details. +*/ + +package org.opensearch.action.admin.cluster.state; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import org.opensearch.action.ProtobufActionResponse; +import org.opensearch.cluster.ClusterState; +import org.opensearch.cluster.ProtobufClusterName; +import org.opensearch.cluster.ProtobufClusterState; +import org.opensearch.common.io.stream.ProtobufStreamInput; +import org.opensearch.common.io.stream.ProtobufStreamOutput; + +import java.io.IOException; + +/** + * The response for getting the cluster state. +* +* @opensearch.internal +*/ +public class ProtobufClusterStateResponse extends ProtobufActionResponse { + + private ProtobufClusterName clusterName; + private ProtobufClusterState clusterState; + private boolean waitForTimedOut = false; + + private final ProtobufStreamInput protobufStreamInput; + + public ProtobufClusterStateResponse(CodedInputStream in) throws IOException { + super(in); + protobufStreamInput = new ProtobufStreamInput(); + clusterName = new ProtobufClusterName(in); + clusterState = protobufStreamInput.readOptionalWriteable(innerIn -> ProtobufClusterState.readFrom(innerIn, null), in); + waitForTimedOut = in.readBool(); + } + + public ProtobufClusterStateResponse(ProtobufClusterName clusterName, ProtobufClusterState clusterState, boolean waitForTimedOut) { + this.clusterName = clusterName; + this.clusterState = clusterState; + this.waitForTimedOut = waitForTimedOut; + protobufStreamInput = new ProtobufStreamInput(); + } + + /** + * The requested cluster state. Only the parts of the cluster state that were + * requested are included in the returned {@link ClusterState} instance. + */ + public ProtobufClusterState getState() { + return this.clusterState; + } + + /** + * The name of the cluster. + */ + public ProtobufClusterName getClusterName() { + return this.clusterName; + } + + /** + * Returns whether the request timed out waiting for a cluster state with a metadata version equal or + * higher than the specified metadata. + */ + public boolean isWaitForTimedOut() { + return waitForTimedOut; + } + + @Override + public void writeTo(CodedOutputStream out) throws IOException { + ProtobufStreamOutput protobufStreamOutput = new ProtobufStreamOutput(); + clusterName.writeTo(out); + protobufStreamOutput.writeOptionalWriteable(clusterState, out); + out.writeBoolNoTag(waitForTimedOut); + } +} diff --git a/server/src/main/java/org/opensearch/action/admin/indices/stats/ProtobufCommonStatsFlags.java b/server/src/main/java/org/opensearch/action/admin/indices/stats/ProtobufCommonStatsFlags.java new file mode 100644 index 0000000000000..82df111cceda4 --- /dev/null +++ b/server/src/main/java/org/opensearch/action/admin/indices/stats/ProtobufCommonStatsFlags.java @@ -0,0 +1,279 @@ +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +package org.opensearch.action.admin.indices.stats; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import org.opensearch.Version; +import org.opensearch.common.Strings; +import org.opensearch.common.io.stream.ProtobufStreamInput; +import org.opensearch.common.io.stream.ProtobufStreamOutput; +import org.opensearch.common.io.stream.ProtobufWriteable; +import org.opensearch.common.io.stream.StreamInput; +import org.opensearch.common.io.stream.StreamOutput; +import org.opensearch.common.io.stream.Writeable; + +import java.io.IOException; +import java.util.Collections; +import java.util.EnumSet; + +/** + * Common Stats Flags for OpenSearch +* +* @opensearch.internal +*/ +public class ProtobufCommonStatsFlags implements ProtobufWriteable, Cloneable { + + public static final CommonStatsFlags ALL = new CommonStatsFlags().all(); + public static final CommonStatsFlags NONE = new CommonStatsFlags().clear(); + + private EnumSet flags = EnumSet.allOf(Flag.class); + private String[] groups = null; + private String[] fieldDataFields = null; + private String[] completionDataFields = null; + private boolean includeSegmentFileSizes = false; + private boolean includeUnloadedSegments = false; + private boolean includeAllShardIndexingPressureTrackers = false; + private boolean includeOnlyTopIndexingPressureMetrics = false; + + /** + * @param flags flags to set. If no flags are supplied, default flags will be set. + */ + public ProtobufCommonStatsFlags(Flag... flags) { + if (flags.length > 0) { + clear(); + Collections.addAll(this.flags, flags); + } + } + + public ProtobufCommonStatsFlags(CodedInputStream in) throws IOException { + ProtobufStreamInput protobufStreamInput = new ProtobufStreamInput(); + final long longFlags = in.readLong(); + flags.clear(); + for (Flag flag : Flag.values()) { + if ((longFlags & (1 << flag.getIndex())) != 0) { + flags.add(flag); + } + } + if (protobufStreamInput.getVersion().before(Version.V_2_0_0)) { + protobufStreamInput.readStringArray(in); + } + groups = protobufStreamInput.readStringArray(in); + fieldDataFields = protobufStreamInput.readStringArray(in); + completionDataFields = protobufStreamInput.readStringArray(in); + includeSegmentFileSizes = in.readBool(); + includeUnloadedSegments = in.readBool(); + includeAllShardIndexingPressureTrackers = in.readBool(); + includeOnlyTopIndexingPressureMetrics = in.readBool(); + } + + @Override + public void writeTo(CodedOutputStream out) throws IOException { + ProtobufStreamOutput protobufStreamOutput = new ProtobufStreamOutput(); + long longFlags = 0; + for (Flag flag : flags) { + longFlags |= (1 << flag.getIndex()); + } + out.writeInt64NoTag(longFlags); + + if (protobufStreamOutput.getVersion().before(Version.V_2_0_0)) { + protobufStreamOutput.writeStringArrayNullable(Strings.EMPTY_ARRAY, out); + } + protobufStreamOutput.writeStringArrayNullable(groups, out); + protobufStreamOutput.writeStringArrayNullable(fieldDataFields, out); + protobufStreamOutput.writeStringArrayNullable(completionDataFields, out); + out.writeBoolNoTag(includeSegmentFileSizes); + out.writeBoolNoTag(includeUnloadedSegments); + out.writeBoolNoTag(includeAllShardIndexingPressureTrackers); + out.writeBoolNoTag(includeOnlyTopIndexingPressureMetrics); + } + + /** + * Sets all flags to return all stats. + */ + public ProtobufCommonStatsFlags all() { + flags = EnumSet.allOf(Flag.class); + groups = null; + fieldDataFields = null; + completionDataFields = null; + includeSegmentFileSizes = false; + includeUnloadedSegments = false; + includeAllShardIndexingPressureTrackers = false; + includeOnlyTopIndexingPressureMetrics = false; + return this; + } + + /** + * Clears all stats. + */ + public ProtobufCommonStatsFlags clear() { + flags = EnumSet.noneOf(Flag.class); + groups = null; + fieldDataFields = null; + completionDataFields = null; + includeSegmentFileSizes = false; + includeUnloadedSegments = false; + includeAllShardIndexingPressureTrackers = false; + includeOnlyTopIndexingPressureMetrics = false; + return this; + } + + public boolean anySet() { + return !flags.isEmpty(); + } + + public Flag[] getFlags() { + return flags.toArray(new Flag[0]); + } + + /** + * Sets specific search group stats to retrieve the stats for. Mainly affects search + * when enabled. + */ + public ProtobufCommonStatsFlags groups(String... groups) { + this.groups = groups; + return this; + } + + public String[] groups() { + return this.groups; + } + + /** + * Sets specific search group stats to retrieve the stats for. Mainly affects search + * when enabled. + */ + public ProtobufCommonStatsFlags fieldDataFields(String... fieldDataFields) { + this.fieldDataFields = fieldDataFields; + return this; + } + + public String[] fieldDataFields() { + return this.fieldDataFields; + } + + public ProtobufCommonStatsFlags completionDataFields(String... completionDataFields) { + this.completionDataFields = completionDataFields; + return this; + } + + public String[] completionDataFields() { + return this.completionDataFields; + } + + public ProtobufCommonStatsFlags includeSegmentFileSizes(boolean includeSegmentFileSizes) { + this.includeSegmentFileSizes = includeSegmentFileSizes; + return this; + } + + public ProtobufCommonStatsFlags includeUnloadedSegments(boolean includeUnloadedSegments) { + this.includeUnloadedSegments = includeUnloadedSegments; + return this; + } + + public ProtobufCommonStatsFlags includeAllShardIndexingPressureTrackers(boolean includeAllShardPressureTrackers) { + this.includeAllShardIndexingPressureTrackers = includeAllShardPressureTrackers; + return this; + } + + public ProtobufCommonStatsFlags includeOnlyTopIndexingPressureMetrics(boolean includeOnlyTopIndexingPressureMetrics) { + this.includeOnlyTopIndexingPressureMetrics = includeOnlyTopIndexingPressureMetrics; + return this; + } + + public boolean includeUnloadedSegments() { + return this.includeUnloadedSegments; + } + + public boolean includeAllShardIndexingPressureTrackers() { + return this.includeAllShardIndexingPressureTrackers; + } + + public boolean includeOnlyTopIndexingPressureMetrics() { + return this.includeOnlyTopIndexingPressureMetrics; + } + + public boolean includeSegmentFileSizes() { + return this.includeSegmentFileSizes; + } + + public boolean isSet(Flag flag) { + return flags.contains(flag); + } + + boolean unSet(Flag flag) { + return flags.remove(flag); + } + + void set(Flag flag) { + flags.add(flag); + } + + public ProtobufCommonStatsFlags set(Flag flag, boolean add) { + if (add) { + set(flag); + } else { + unSet(flag); + } + return this; + } + + @Override + public ProtobufCommonStatsFlags clone() { + try { + ProtobufCommonStatsFlags cloned = (ProtobufCommonStatsFlags) super.clone(); + cloned.flags = flags.clone(); + return cloned; + } catch (CloneNotSupportedException e) { + throw new AssertionError(e); + } + } + + /** + * The flags. + * + * @opensearch.internal + */ + public enum Flag { + Store("store", 0), + Indexing("indexing", 1), + Get("get", 2), + Search("search", 3), + Merge("merge", 4), + Flush("flush", 5), + Refresh("refresh", 6), + QueryCache("query_cache", 7), + FieldData("fielddata", 8), + Docs("docs", 9), + Warmer("warmer", 10), + Completion("completion", 11), + Segments("segments", 12), + Translog("translog", 13), + // 14 was previously used for Suggest + RequestCache("request_cache", 15), + Recovery("recovery", 16); + + private final String restName; + private final int index; + + Flag(final String restName, final int index) { + this.restName = restName; + this.index = index; + } + + public String getRestName() { + return restName; + } + + private int getIndex() { + return index; + } + + } +} diff --git a/server/src/main/java/org/opensearch/action/support/IndicesOptions.java b/server/src/main/java/org/opensearch/action/support/IndicesOptions.java index fe1b2efc05b80..9828e168a8c94 100644 --- a/server/src/main/java/org/opensearch/action/support/IndicesOptions.java +++ b/server/src/main/java/org/opensearch/action/support/IndicesOptions.java @@ -31,8 +31,12 @@ package org.opensearch.action.support; +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; import org.opensearch.OpenSearchParseException; import org.opensearch.core.ParseField; +import org.opensearch.common.io.stream.ProtobufStreamInput; +import org.opensearch.common.io.stream.ProtobufStreamOutput; import org.opensearch.common.io.stream.StreamInput; import org.opensearch.common.io.stream.StreamOutput; import org.opensearch.core.xcontent.ToXContent; @@ -278,12 +282,26 @@ public void writeIndicesOptions(StreamOutput out) throws IOException { out.writeEnumSet(expandWildcards); } + public void writeIndicesOptionsProtobuf(CodedOutputStream out) throws IOException { + ProtobufStreamOutput protobufStreamOutput = new ProtobufStreamOutput(); + EnumSet