Skip to content

Commit 633790f

Browse files
NodeInfo response should use a collection rather than fields (#54460)
This is a first cut at giving NodeInfo the ability to carry a flexible list of heterogeneous info responses. The trick is to be able to serialize and deserialize an arbitrary list of blocks of information. It is convenient to be able to deserialize into usable Java objects so that we can aggregate nodes stats for the cluster stats endpoint. In order to provide a little bit of clarity about which objects can and can't be used as info blocks, I've introduced a new interface called "ReportingService." I have removed the hard-coded getters (e.g., getOs()) in favor of a flexible method that can return heterogeneous kinds of info blocks (e.g., getInfo(OsInfo.class)). Taking a class as an argument removes the need to cast in the client code.
1 parent 79e5033 commit 633790f

File tree

40 files changed

+287
-191
lines changed

40 files changed

+287
-191
lines changed

modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexFromRemoteWithAuthTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
4343
import org.elasticsearch.env.Environment;
4444
import org.elasticsearch.env.NodeEnvironment;
45+
import org.elasticsearch.http.HttpInfo;
4546
import org.elasticsearch.plugins.ActionPlugin;
4647
import org.elasticsearch.plugins.Plugin;
4748
import org.elasticsearch.rest.RestHeaderDefinition;
@@ -99,7 +100,7 @@ public void setupSourceIndex() {
99100
@Before
100101
public void fetchTransportAddress() {
101102
NodeInfo nodeInfo = client().admin().cluster().prepareNodesInfo().get().getNodes().get(0);
102-
address = nodeInfo.getHttp().getAddress().publishAddress();
103+
address = nodeInfo.getInfo(HttpInfo.class).getAddress().publishAddress();
103104
}
104105

105106
/**

modules/reindex/src/test/java/org/elasticsearch/index/reindex/RetryTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.elasticsearch.common.settings.Settings;
3232
import org.elasticsearch.common.transport.TransportAddress;
3333
import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException;
34+
import org.elasticsearch.http.HttpInfo;
3435
import org.elasticsearch.index.query.QueryBuilders;
3536
import org.elasticsearch.plugins.Plugin;
3637
import org.elasticsearch.test.ESIntegTestCase;
@@ -116,7 +117,7 @@ public void testReindexFromRemote() throws Exception {
116117
}
117118
assertNotNull(masterNode);
118119

119-
TransportAddress address = masterNode.getHttp().getAddress().publishAddress();
120+
TransportAddress address = masterNode.getInfo(HttpInfo.class).getAddress().publishAddress();
120121
RemoteInfo remote =
121122
new RemoteInfo("http", address.getAddress(), address.getPort(), null,
122123
new BytesArray("{\"match_all\":{}}"), null, null, emptyMap(),

modules/transport-netty4/src/test/java/org/elasticsearch/transport/netty4/Netty4TransportMultiPortIntegrationIT.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
2929
import org.elasticsearch.test.ESIntegTestCase.Scope;
3030
import org.elasticsearch.test.junit.annotations.Network;
31+
import org.elasticsearch.transport.TransportInfo;
3132

3233
import java.util.Locale;
3334

@@ -65,9 +66,9 @@ protected Settings nodeSettings(int nodeOrdinal) {
6566
public void testThatInfosAreExposed() throws Exception {
6667
NodesInfoResponse response = client().admin().cluster().prepareNodesInfo().clear().setTransport(true).get();
6768
for (NodeInfo nodeInfo : response.getNodes()) {
68-
assertThat(nodeInfo.getTransport().getProfileAddresses().keySet(), hasSize(1));
69-
assertThat(nodeInfo.getTransport().getProfileAddresses(), hasKey("client1"));
70-
BoundTransportAddress boundTransportAddress = nodeInfo.getTransport().getProfileAddresses().get("client1");
69+
assertThat(nodeInfo.getInfo(TransportInfo.class).getProfileAddresses().keySet(), hasSize(1));
70+
assertThat(nodeInfo.getInfo(TransportInfo.class).getProfileAddresses(), hasKey("client1"));
71+
BoundTransportAddress boundTransportAddress = nodeInfo.getInfo(TransportInfo.class).getProfileAddresses().get("client1");
7172
for (TransportAddress transportAddress : boundTransportAddress.boundAddresses()) {
7273
assertThat(transportAddress, instanceOf(TransportAddress.class));
7374
}

modules/transport-netty4/src/test/java/org/elasticsearch/transport/netty4/Netty4TransportPublishAddressIT.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.elasticsearch.common.transport.TransportAddress;
3030
import org.elasticsearch.test.ESIntegTestCase;
3131
import org.elasticsearch.transport.Netty4Plugin;
32+
import org.elasticsearch.transport.TransportInfo;
3233

3334
import java.net.Inet4Address;
3435

@@ -68,7 +69,7 @@ public void testDifferentPorts() throws Exception {
6869
logger.info("--> checking if boundAddress matching publishAddress has same port");
6970
NodesInfoResponse nodesInfoResponse = client().admin().cluster().prepareNodesInfo().get();
7071
for (NodeInfo nodeInfo : nodesInfoResponse.getNodes()) {
71-
BoundTransportAddress boundTransportAddress = nodeInfo.getTransport().getAddress();
72+
BoundTransportAddress boundTransportAddress = nodeInfo.getInfo(TransportInfo.class).getAddress();
7273
if (nodeInfo.getNode().getName().equals(ipv4OnlyNode)) {
7374
assertThat(boundTransportAddress.boundAddresses().length, equalTo(1));
7475
assertThat(boundTransportAddress.boundAddresses()[0].getPort(), equalTo(boundTransportAddress.publishAddress().getPort()));

server/src/main/java/org/elasticsearch/action/admin/cluster/node/info/NodeInfo.java

Lines changed: 51 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,13 @@
3333
import org.elasticsearch.monitor.jvm.JvmInfo;
3434
import org.elasticsearch.monitor.os.OsInfo;
3535
import org.elasticsearch.monitor.process.ProcessInfo;
36+
import org.elasticsearch.node.ReportingService;
3637
import org.elasticsearch.threadpool.ThreadPoolInfo;
3738
import org.elasticsearch.transport.TransportInfo;
3839

3940
import java.io.IOException;
41+
import java.util.HashMap;
42+
import java.util.Map;
4043

4144
/**
4245
* Node information (static, does not change over time).
@@ -49,29 +52,12 @@ public class NodeInfo extends BaseNodeResponse {
4952
@Nullable
5053
private Settings settings;
5154

52-
@Nullable
53-
private OsInfo os;
54-
55-
@Nullable
56-
private ProcessInfo process;
57-
58-
@Nullable
59-
private JvmInfo jvm;
60-
61-
@Nullable
62-
private ThreadPoolInfo threadPool;
63-
64-
@Nullable
65-
private TransportInfo transport;
66-
67-
@Nullable
68-
private HttpInfo http;
69-
70-
@Nullable
71-
private PluginsAndModules plugins;
72-
73-
@Nullable
74-
private IngestInfo ingest;
55+
/**
56+
* Do not expose this map to other classes. For type safety, use {@link #getInfo(Class)}
57+
* to retrieve items from this map and {@link #addInfoIfNonNull(Class, ReportingService.Info)}
58+
* to retrieve items from it.
59+
*/
60+
private Map<Class<? extends ReportingService.Info>, ReportingService.Info> infoMap = new HashMap<>();
7561

7662
@Nullable
7763
private ByteSizeValue totalIndexingBuffer;
@@ -88,14 +74,14 @@ public NodeInfo(StreamInput in) throws IOException {
8874
if (in.readBoolean()) {
8975
settings = Settings.readSettingsFromStream(in);
9076
}
91-
os = in.readOptionalWriteable(OsInfo::new);
92-
process = in.readOptionalWriteable(ProcessInfo::new);
93-
jvm = in.readOptionalWriteable(JvmInfo::new);
94-
threadPool = in.readOptionalWriteable(ThreadPoolInfo::new);
95-
transport = in.readOptionalWriteable(TransportInfo::new);
96-
http = in.readOptionalWriteable(HttpInfo::new);
97-
plugins = in.readOptionalWriteable(PluginsAndModules::new);
98-
ingest = in.readOptionalWriteable(IngestInfo::new);
77+
addInfoIfNonNull(OsInfo.class, in.readOptionalWriteable(OsInfo::new));
78+
addInfoIfNonNull(ProcessInfo.class, in.readOptionalWriteable(ProcessInfo::new));
79+
addInfoIfNonNull(JvmInfo.class, in.readOptionalWriteable(JvmInfo::new));
80+
addInfoIfNonNull(ThreadPoolInfo.class, in.readOptionalWriteable(ThreadPoolInfo::new));
81+
addInfoIfNonNull(TransportInfo.class, in.readOptionalWriteable(TransportInfo::new));
82+
addInfoIfNonNull(HttpInfo.class, in.readOptionalWriteable(HttpInfo::new));
83+
addInfoIfNonNull(PluginsAndModules.class, in.readOptionalWriteable(PluginsAndModules::new));
84+
addInfoIfNonNull(IngestInfo.class, in.readOptionalWriteable(IngestInfo::new));
9985
}
10086

10187
public NodeInfo(Version version, Build build, DiscoveryNode node, @Nullable Settings settings,
@@ -106,14 +92,14 @@ public NodeInfo(Version version, Build build, DiscoveryNode node, @Nullable Sett
10692
this.version = version;
10793
this.build = build;
10894
this.settings = settings;
109-
this.os = os;
110-
this.process = process;
111-
this.jvm = jvm;
112-
this.threadPool = threadPool;
113-
this.transport = transport;
114-
this.http = http;
115-
this.plugins = plugins;
116-
this.ingest = ingest;
95+
addInfoIfNonNull(OsInfo.class, os);
96+
addInfoIfNonNull(ProcessInfo.class, process);
97+
addInfoIfNonNull(JvmInfo.class, jvm);
98+
addInfoIfNonNull(ThreadPoolInfo.class, threadPool);
99+
addInfoIfNonNull(TransportInfo.class, transport);
100+
addInfoIfNonNull(HttpInfo.class, http);
101+
addInfoIfNonNull(PluginsAndModules.class, plugins);
102+
addInfoIfNonNull(IngestInfo.class, ingest);
117103
this.totalIndexingBuffer = totalIndexingBuffer;
118104
}
119105

@@ -148,57 +134,32 @@ public Settings getSettings() {
148134
}
149135

150136
/**
151-
* Operating System level information.
137+
* Get a particular info object, e.g. {@link JvmInfo} or {@link OsInfo}. This
138+
* generic method handles all casting in order to spare client classes the
139+
* work of explicit casts. This {@link NodeInfo} class guarantees type
140+
* safety for these stored info blocks.
141+
*
142+
* @param clazz Class for retrieval.
143+
* @param <T> Specific subtype of ReportingService.Info to retrieve.
144+
* @return An object of type T.
152145
*/
153-
@Nullable
154-
public OsInfo getOs() {
155-
return this.os;
146+
public <T extends ReportingService.Info> T getInfo(Class<T> clazz) {
147+
return clazz.cast(infoMap.get(clazz));
156148
}
157149

158-
/**
159-
* Process level information.
160-
*/
161150
@Nullable
162-
public ProcessInfo getProcess() {
163-
return process;
151+
public ByteSizeValue getTotalIndexingBuffer() {
152+
return totalIndexingBuffer;
164153
}
165154

166155
/**
167-
* JVM level information.
156+
* Add a value to the map of information blocks. This method guarantees the
157+
* type safety of the storage of heterogeneous types of reporting service information.
168158
*/
169-
@Nullable
170-
public JvmInfo getJvm() {
171-
return jvm;
172-
}
173-
174-
@Nullable
175-
public ThreadPoolInfo getThreadPool() {
176-
return this.threadPool;
177-
}
178-
179-
@Nullable
180-
public TransportInfo getTransport() {
181-
return transport;
182-
}
183-
184-
@Nullable
185-
public HttpInfo getHttp() {
186-
return http;
187-
}
188-
189-
@Nullable
190-
public PluginsAndModules getPlugins() {
191-
return this.plugins;
192-
}
193-
194-
@Nullable
195-
public IngestInfo getIngest() {
196-
return ingest;
197-
}
198-
199-
@Nullable
200-
public ByteSizeValue getTotalIndexingBuffer() {
201-
return totalIndexingBuffer;
159+
private <T extends ReportingService.Info> void addInfoIfNonNull(Class<T> clazz, T info) {
160+
if (info != null) {
161+
infoMap.put(clazz, info);
162+
}
202163
}
203164

204165
@Override
@@ -218,13 +179,13 @@ public void writeTo(StreamOutput out) throws IOException {
218179
out.writeBoolean(true);
219180
Settings.writeSettingsToStream(settings, out);
220181
}
221-
out.writeOptionalWriteable(os);
222-
out.writeOptionalWriteable(process);
223-
out.writeOptionalWriteable(jvm);
224-
out.writeOptionalWriteable(threadPool);
225-
out.writeOptionalWriteable(transport);
226-
out.writeOptionalWriteable(http);
227-
out.writeOptionalWriteable(plugins);
228-
out.writeOptionalWriteable(ingest);
182+
out.writeOptionalWriteable(getInfo(OsInfo.class));
183+
out.writeOptionalWriteable(getInfo(ProcessInfo.class));
184+
out.writeOptionalWriteable(getInfo(JvmInfo.class));
185+
out.writeOptionalWriteable(getInfo(ThreadPoolInfo.class));
186+
out.writeOptionalWriteable(getInfo(TransportInfo.class));
187+
out.writeOptionalWriteable(getInfo(HttpInfo.class));
188+
out.writeOptionalWriteable(getInfo(PluginsAndModules.class));
189+
out.writeOptionalWriteable(getInfo(IngestInfo.class));
229190
}
230191
}

server/src/main/java/org/elasticsearch/action/admin/cluster/node/info/NodesInfoResponse.java

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@
3030
import org.elasticsearch.common.xcontent.ToXContentFragment;
3131
import org.elasticsearch.common.xcontent.XContentBuilder;
3232
import org.elasticsearch.common.xcontent.XContentFactory;
33+
import org.elasticsearch.http.HttpInfo;
34+
import org.elasticsearch.ingest.IngestInfo;
35+
import org.elasticsearch.monitor.jvm.JvmInfo;
36+
import org.elasticsearch.monitor.os.OsInfo;
37+
import org.elasticsearch.monitor.process.ProcessInfo;
38+
import org.elasticsearch.threadpool.ThreadPoolInfo;
39+
import org.elasticsearch.transport.TransportInfo;
3340

3441
import java.io.IOException;
3542
import java.util.List;
@@ -95,29 +102,29 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
95102
builder.endObject();
96103
}
97104

98-
if (nodeInfo.getOs() != null) {
99-
nodeInfo.getOs().toXContent(builder, params);
105+
if (nodeInfo.getInfo(OsInfo.class) != null) {
106+
nodeInfo.getInfo(OsInfo.class).toXContent(builder, params);
100107
}
101-
if (nodeInfo.getProcess() != null) {
102-
nodeInfo.getProcess().toXContent(builder, params);
108+
if (nodeInfo.getInfo(ProcessInfo.class) != null) {
109+
nodeInfo.getInfo(ProcessInfo.class).toXContent(builder, params);
103110
}
104-
if (nodeInfo.getJvm() != null) {
105-
nodeInfo.getJvm().toXContent(builder, params);
111+
if (nodeInfo.getInfo(JvmInfo.class) != null) {
112+
nodeInfo.getInfo(JvmInfo.class).toXContent(builder, params);
106113
}
107-
if (nodeInfo.getThreadPool() != null) {
108-
nodeInfo.getThreadPool().toXContent(builder, params);
114+
if (nodeInfo.getInfo(ThreadPoolInfo.class) != null) {
115+
nodeInfo.getInfo(ThreadPoolInfo.class).toXContent(builder, params);
109116
}
110-
if (nodeInfo.getTransport() != null) {
111-
nodeInfo.getTransport().toXContent(builder, params);
117+
if (nodeInfo.getInfo(TransportInfo.class) != null) {
118+
nodeInfo.getInfo(TransportInfo.class).toXContent(builder, params);
112119
}
113-
if (nodeInfo.getHttp() != null) {
114-
nodeInfo.getHttp().toXContent(builder, params);
120+
if (nodeInfo.getInfo(HttpInfo.class) != null) {
121+
nodeInfo.getInfo(HttpInfo.class).toXContent(builder, params);
115122
}
116-
if (nodeInfo.getPlugins() != null) {
117-
nodeInfo.getPlugins().toXContent(builder, params);
123+
if (nodeInfo.getInfo(PluginsAndModules.class) != null) {
124+
nodeInfo.getInfo(PluginsAndModules.class).toXContent(builder, params);
118125
}
119-
if (nodeInfo.getIngest() != null) {
120-
nodeInfo.getIngest().toXContent(builder, params);
126+
if (nodeInfo.getInfo(IngestInfo.class) != null) {
127+
nodeInfo.getInfo(IngestInfo.class).toXContent(builder, params);
121128
}
122129

123130
builder.endObject();

server/src/main/java/org/elasticsearch/action/admin/cluster/node/info/PluginsAndModules.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,8 @@
2121

2222
import org.elasticsearch.common.io.stream.StreamInput;
2323
import org.elasticsearch.common.io.stream.StreamOutput;
24-
import org.elasticsearch.common.io.stream.Writeable;
25-
import org.elasticsearch.common.xcontent.ToXContent.Params;
26-
import org.elasticsearch.common.xcontent.ToXContentFragment;
2724
import org.elasticsearch.common.xcontent.XContentBuilder;
25+
import org.elasticsearch.node.ReportingService;
2826
import org.elasticsearch.plugins.PluginInfo;
2927

3028
import java.io.IOException;
@@ -36,7 +34,7 @@
3634
/**
3735
* Information about plugins and modules
3836
*/
39-
public class PluginsAndModules implements Writeable, ToXContentFragment {
37+
public class PluginsAndModules implements ReportingService.Info {
4038
private final List<PluginInfo> plugins;
4139
private final List<PluginInfo> modules;
4240

0 commit comments

Comments
 (0)