From 7b01378bca010267ca5f2b3b28f8d5788c3be7a2 Mon Sep 17 00:00:00 2001 From: Martijn van Groningen Date: Mon, 8 Mar 2021 14:50:42 +0100 Subject: [PATCH] Adjust RolloverAction serialization of maxPrimaryShardSize during an upgrade. If node doesn't support maxPrimaryShardSize then serialize maxPrimaryShardSize as maxSize. This should fix a problematic situation if an older node doesn't support maxPrimaryShardSize and this is the only condition specified then the older node ends up with a instance without any conditions. This could lead to upgrade failures, new nodes not able to start because local cluster state can't be read. Relates to #69918 --- .../xpack/core/ilm/RolloverAction.java | 9 +++++++-- .../xpack/core/ilm/RolloverActionTests.java | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/RolloverAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/RolloverAction.java index c0664ea57fab8..51f79ea6eeb8f 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/RolloverAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/RolloverAction.java @@ -96,12 +96,17 @@ public RolloverAction(StreamInput in) throws IOException { @Override public void writeTo(StreamOutput out) throws IOException { boolean hasMaxSize = maxSize != null; - out.writeBoolean(hasMaxSize); + boolean hasMaxPrimaryShardSize = maxPrimaryShardSize != null; if (hasMaxSize) { + out.writeBoolean(true); maxSize.writeTo(out); + } else if (hasMaxPrimaryShardSize && out.getVersion().before(Version.V_7_13_0)) { + out.writeBoolean(true); + maxPrimaryShardSize.writeTo(out); + } else { + out.writeBoolean(false); } if (out.getVersion().onOrAfter(Version.V_7_13_0)) { - boolean hasMaxPrimaryShardSize = maxPrimaryShardSize != null; out.writeBoolean(hasMaxPrimaryShardSize); if (hasMaxPrimaryShardSize) { maxPrimaryShardSize.writeTo(out); diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/RolloverActionTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/RolloverActionTests.java index e349f2050dbe8..82cf8f7eaecfd 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/RolloverActionTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/RolloverActionTests.java @@ -6,6 +6,7 @@ */ package org.elasticsearch.xpack.core.ilm; +import org.elasticsearch.Version; import org.elasticsearch.common.io.stream.Writeable.Reader; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; @@ -16,6 +17,9 @@ import java.io.IOException; import java.util.List; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.nullValue; + public class RolloverActionTests extends AbstractActionTestCase { @Override @@ -118,4 +122,18 @@ public void testToSteps() { assertEquals(action.getMaxDocs(), firstStep.getMaxDocs()); assertEquals(nextStepKey, fifthStep.getNextStepKey()); } + + public void testBwcSerializationWithMaxPrimaryShardSize() throws Exception { + // In case of serializing to node with older version, replace maxPrimaryShardSize with maxSize. + RolloverAction instance = new RolloverAction(null, new ByteSizeValue(1L), null, null); + RolloverAction deserializedInstance = copyInstance(instance, Version.V_7_11_2); + assertThat(deserializedInstance.getMaxPrimaryShardSize(), nullValue()); + assertThat(deserializedInstance.getMaxSize(), equalTo(instance.getMaxPrimaryShardSize())); + + // But not if maxSize is also specified: + instance = new RolloverAction(new ByteSizeValue(1L), new ByteSizeValue(2L), null, null); + deserializedInstance = copyInstance(instance, Version.V_7_11_2); + assertThat(deserializedInstance.getMaxPrimaryShardSize(), nullValue()); + assertThat(deserializedInstance.getMaxSize(), equalTo(instance.getMaxSize())); + } }