From f4a3d969adfeecbc8449d6c7e92c81c4a8c18b09 Mon Sep 17 00:00:00 2001 From: Jake Landis Date: Thu, 4 Jun 2020 16:44:36 -0500 Subject: [PATCH] [7.x] Ensure default watches are updated for rolling upgrades. (#57185) (#57563) For a rolling/mixed cluster upgrade (add new version to existing cluster then shutdown old instances), the watches that ship by default with monitoring may not get properly updated to the new version. Monitoring watches can only get published if the internal state is marked as dirty. If a node is not master, will also get marked as clean (e.g. not dirty). For a mixed cluster upgrade, it is possible for the new node to be added, not as master, the internal state gets marked as clean so that no more attempts can be made to publish the watches. This happens on all new nodes. Once the old nodes are de-commissioned one of the new version nodes in the cluster gets promoted to master. However, that new master node (with out intervention like restarting the node or removing/adding exporters) will never attempt to re-publish since the internal state was already marked as clean. This commit adds a cluster state listener to mark the resource dirty when a node is promoted to master. This will allow the new resource to be published without any intervention. --- .../monitoring/exporter/http/HttpExporter.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporter.java b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporter.java index 62b3d8ef127c8..562f427ca2cc6 100644 --- a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporter.java +++ b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporter.java @@ -21,6 +21,7 @@ import org.elasticsearch.client.RestClientBuilder; import org.elasticsearch.client.sniff.ElasticsearchNodesSniffer; import org.elasticsearch.client.sniff.Sniffer; +import org.elasticsearch.cluster.ClusterStateListener; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Strings; @@ -415,7 +416,7 @@ public Iterator> settings() { private static final ConcurrentHashMap SECURE_AUTH_PASSWORDS = new ConcurrentHashMap<>(); private final ThreadContext threadContext; private final DateFormatter dateTimeFormatter; - + private final ClusterStateListener onLocalMasterListener; /** * Create an {@link HttpExporter}. * @@ -476,6 +477,14 @@ public HttpExporter(final Config config, final SSLService sslService, final Thre // mark resources as dirty after any node failure or license change listener.setResource(resource); + + //for a mixed cluster upgrade, ensure that if master changes and this is the master, allow the resources to re-publish + onLocalMasterListener = clusterChangedEvent -> { + if (clusterChangedEvent.nodesDelta().masterNodeChanged() && clusterChangedEvent.localNodeMaster()) { + resource.markDirty(); + } + }; + config.clusterService().addListener(onLocalMasterListener); } /** @@ -935,9 +944,11 @@ public void openBulk(final ActionListener listener) { @Override public void doClose() { try { + config.clusterService().removeListener(onLocalMasterListener); if (sniffer != null) { sniffer.close(); } + } catch (Exception e) { logger.error("an error occurred while closing the internal client sniffer", e); } finally {