diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/NodeInfo.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/NodeInfo.java index 9e198cc6296..cb22c6352a7 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/NodeInfo.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/NodeInfo.java @@ -220,8 +220,7 @@ public class NodeInfo extends BaseNodeResponse { http = new HttpInfo(in); } if (in.readBoolean()) { - plugins = new PluginsAndModules(); - plugins.readFrom(in); + plugins = new PluginsAndModules(in); } if (in.readBoolean()) { ingest = new IngestInfo(in); diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/PluginsAndModules.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/PluginsAndModules.java index 3831fd24f3e..4c7fa7fa2ce 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/PluginsAndModules.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/PluginsAndModules.java @@ -21,7 +21,7 @@ package org.elasticsearch.action.admin.cluster.node.info; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Streamable; +import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.plugins.PluginInfo; @@ -34,13 +34,40 @@ import java.util.List; /** * Information about plugins and modules */ -public class PluginsAndModules implements Streamable, ToXContent { - private List plugins; - private List modules; +public class PluginsAndModules implements Writeable, ToXContent { + private final List plugins; + private final List modules; - public PluginsAndModules() { - plugins = new ArrayList<>(); - modules = new ArrayList<>(); + public PluginsAndModules(List plugins, List modules) { + this.plugins = Collections.unmodifiableList(plugins); + this.modules = Collections.unmodifiableList(modules); + } + + public PluginsAndModules(StreamInput in) throws IOException { + int pluginsSize = in.readInt(); + List plugins = new ArrayList<>(pluginsSize); + for (int i = 0; i < pluginsSize; i++) { + plugins.add(PluginInfo.readFromStream(in)); + } + this.plugins = Collections.unmodifiableList(plugins); + int modulesSize = in.readInt(); + List modules = new ArrayList<>(modulesSize); + for (int i = 0; i < modulesSize; i++) { + modules.add(PluginInfo.readFromStream(in)); + } + this.modules = Collections.unmodifiableList(modules); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeInt(plugins.size()); + for (PluginInfo plugin : getPluginInfos()) { + plugin.writeTo(out); + } + out.writeInt(modules.size()); + for (PluginInfo module : getModuleInfos()) { + module.writeTo(out); + } } /** @@ -69,33 +96,6 @@ public class PluginsAndModules implements Streamable, ToXContent { modules.add(info); } - @Override - public void readFrom(StreamInput in) throws IOException { - if (plugins.isEmpty() == false || modules.isEmpty() == false) { - throw new IllegalStateException("instance is already populated"); - } - int plugins_size = in.readInt(); - for (int i = 0; i < plugins_size; i++) { - plugins.add(PluginInfo.readFromStream(in)); - } - int modules_size = in.readInt(); - for (int i = 0; i < modules_size; i++) { - modules.add(PluginInfo.readFromStream(in)); - } - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeInt(plugins.size()); - for (PluginInfo plugin : getPluginInfos()) { - plugin.writeTo(out); - } - out.writeInt(modules.size()); - for (PluginInfo module : getModuleInfos()) { - module.writeTo(out); - } - } - @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startArray("plugins"); diff --git a/core/src/main/java/org/elasticsearch/plugins/PluginsService.java b/core/src/main/java/org/elasticsearch/plugins/PluginsService.java index e13bdbec879..01704e9ed86 100644 --- a/core/src/main/java/org/elasticsearch/plugins/PluginsService.java +++ b/core/src/main/java/org/elasticsearch/plugins/PluginsService.java @@ -108,10 +108,9 @@ public class PluginsService extends AbstractComponent { */ public PluginsService(Settings settings, Path modulesDirectory, Path pluginsDirectory, Collection> classpathPlugins) { super(settings); - info = new PluginsAndModules(); List> pluginsLoaded = new ArrayList<>(); - + List pluginsList = new ArrayList<>(); // first we load plugins that are on the classpath. this is for tests and transport clients for (Class pluginClass : classpathPlugins) { Plugin plugin = loadPlugin(pluginClass, settings); @@ -120,9 +119,10 @@ public class PluginsService extends AbstractComponent { logger.trace("plugin loaded from classpath [{}]", pluginInfo); } pluginsLoaded.add(new Tuple<>(pluginInfo, plugin)); - info.addPlugin(pluginInfo); + pluginsList.add(pluginInfo); } + List modulesList = new ArrayList<>(); // load modules if (modulesDirectory != null) { try { @@ -130,7 +130,7 @@ public class PluginsService extends AbstractComponent { List> loaded = loadBundles(bundles); pluginsLoaded.addAll(loaded); for (Tuple module : loaded) { - info.addModule(module.v1()); + modulesList.add(module.v1()); } } catch (IOException ex) { throw new IllegalStateException("Unable to initialize modules", ex); @@ -144,18 +144,19 @@ public class PluginsService extends AbstractComponent { List> loaded = loadBundles(bundles); pluginsLoaded.addAll(loaded); for (Tuple plugin : loaded) { - info.addPlugin(plugin.v1()); + pluginsList.add(plugin.v1()); } } catch (IOException ex) { throw new IllegalStateException("Unable to initialize plugins", ex); } } - plugins = Collections.unmodifiableList(pluginsLoaded); + this.info = new PluginsAndModules(pluginsList, modulesList); + this.plugins = Collections.unmodifiableList(pluginsLoaded); // We need to build a List of plugins for checking mandatory plugins Set pluginsNames = new HashSet<>(); - for (Tuple tuple : plugins) { + for (Tuple tuple : this.plugins) { pluginsNames.add(tuple.v1().getName()); } @@ -179,7 +180,7 @@ public class PluginsService extends AbstractComponent { logPluginInfo(info.getPluginInfos(), "plugin", logger); Map> onModuleReferences = new HashMap<>(); - for (Tuple pluginEntry : plugins) { + for (Tuple pluginEntry : this.plugins) { Plugin plugin = pluginEntry.v2(); List list = new ArrayList<>(); for (Method method : plugin.getClass().getMethods()) { diff --git a/core/src/test/java/org/elasticsearch/nodesinfo/NodeInfoStreamingTests.java b/core/src/test/java/org/elasticsearch/nodesinfo/NodeInfoStreamingTests.java index 7a3f8706dad..895cdebd68a 100644 --- a/core/src/test/java/org/elasticsearch/nodesinfo/NodeInfoStreamingTests.java +++ b/core/src/test/java/org/elasticsearch/nodesinfo/NodeInfoStreamingTests.java @@ -138,9 +138,9 @@ public class NodeInfoStreamingTests extends ESTestCase { profileAddresses.put("test_address", dummyBoundTransportAddress); TransportInfo transport = new TransportInfo(dummyBoundTransportAddress, profileAddresses); HttpInfo htttpInfo = new HttpInfo(dummyBoundTransportAddress, randomLong()); - PluginsAndModules plugins = new PluginsAndModules(); - plugins.addModule(DummyPluginInfo.INSTANCE); - plugins.addPlugin(DummyPluginInfo.INSTANCE); + + PluginsAndModules plugins = new PluginsAndModules(Collections.singletonList(DummyPluginInfo.INSTANCE), + Collections.singletonList(DummyPluginInfo.INSTANCE)); IngestInfo ingestInfo = new IngestInfo(Collections.emptyList()); ByteSizeValue indexingBuffer; if (random().nextBoolean()) { diff --git a/core/src/test/java/org/elasticsearch/plugins/PluginInfoTests.java b/core/src/test/java/org/elasticsearch/plugins/PluginInfoTests.java index 73b31b92637..4ad52be8866 100644 --- a/core/src/test/java/org/elasticsearch/plugins/PluginInfoTests.java +++ b/core/src/test/java/org/elasticsearch/plugins/PluginInfoTests.java @@ -23,8 +23,9 @@ import org.elasticsearch.Version; import org.elasticsearch.action.admin.cluster.node.info.PluginsAndModules; import org.elasticsearch.test.ESTestCase; -import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -201,15 +202,17 @@ public class PluginInfoTests extends ESTestCase { } public void testPluginListSorted() { - PluginsAndModules pluginsInfo = new PluginsAndModules(); - pluginsInfo.addPlugin(new PluginInfo("c", "foo", "dummy", "dummyclass")); - pluginsInfo.addPlugin(new PluginInfo("b", "foo", "dummy", "dummyclass")); - pluginsInfo.addPlugin(new PluginInfo("e", "foo", "dummy", "dummyclass")); - pluginsInfo.addPlugin(new PluginInfo("a", "foo", "dummy", "dummyclass")); - pluginsInfo.addPlugin(new PluginInfo("d", "foo", "dummy", "dummyclass")); + List plugins = new ArrayList<>(); + plugins.add(new PluginInfo("c", "foo", "dummy", "dummyclass")); + plugins.add(new PluginInfo("b", "foo", "dummy", "dummyclass")); + plugins.add(new PluginInfo("e", "foo", "dummy", "dummyclass")); + plugins.add(new PluginInfo("a", "foo", "dummy", "dummyclass")); + plugins.add(new PluginInfo("d", "foo", "dummy", "dummyclass")); + PluginsAndModules pluginsInfo = new PluginsAndModules(plugins, Collections.emptyList()); + final List infos = pluginsInfo.getPluginInfos(); - List names = infos.stream().map((input) -> input.getName()).collect(Collectors.toList()); + List names = infos.stream().map(PluginInfo::getName).collect(Collectors.toList()); assertThat(names, contains("a", "b", "c", "d", "e")); } }