From 3e585899e3b2b9a5ffe90f040cbcb9f838e0ab22 Mon Sep 17 00:00:00 2001 From: Jake Landis Date: Wed, 23 Oct 2019 11:21:11 -0500 Subject: [PATCH] =?UTF-8?q?Ensure=20SLM=20stats=20does=20not=20block=20an?= =?UTF-8?q?=20in-place=20upgrade=20from=207.4=20(=E2=80=A6=20(#48412)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 7.5+ for SLM requires [stats] object to exist in the cluster state. When doing an in-place upgrade from 7.4 to 7.5+ [stats] does not exist in cluster state, result in an exception on startup [1]. This commit moves the [stats] to be an optional object in the parser and if not found will default to an empty stats object. [1] Caused by: java.lang.IllegalArgumentException: Required [stats] --- .../core/slm/SnapshotLifecycleMetadata.java | 4 +- .../xpack/restart/FullClusterRestartIT.java | 43 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/SnapshotLifecycleMetadata.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/SnapshotLifecycleMetadata.java index 71e33f9c8d70c..8ce7b4c8b6072 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/SnapshotLifecycleMetadata.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/SnapshotLifecycleMetadata.java @@ -62,7 +62,7 @@ public class SnapshotLifecycleMetadata implements XPackMetaDataCustom { throw new IllegalArgumentException("ordered " + POLICIES_FIELD.getPreferredName() + " are not supported"); }, POLICIES_FIELD); PARSER.declareString(ConstructingObjectParser.constructorArg(), OPERATION_MODE_FIELD); - PARSER.declareObject(ConstructingObjectParser.constructorArg(), (v, o) -> SnapshotLifecycleStats.parse(v), STATS_FIELD); + PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (v, o) -> SnapshotLifecycleStats.parse(v), STATS_FIELD); } private final Map snapshotConfigurations; @@ -74,7 +74,7 @@ public SnapshotLifecycleMetadata(Map sn SnapshotLifecycleStats slmStats) { this.snapshotConfigurations = new HashMap<>(snapshotConfigurations); this.operationMode = operationMode; - this.slmStats = slmStats; + this.slmStats = slmStats != null ? slmStats : new SnapshotLifecycleStats(); } public SnapshotLifecycleMetadata(StreamInput in) throws IOException { diff --git a/x-pack/qa/full-cluster-restart/src/test/java/org/elasticsearch/xpack/restart/FullClusterRestartIT.java b/x-pack/qa/full-cluster-restart/src/test/java/org/elasticsearch/xpack/restart/FullClusterRestartIT.java index a2ff126298afc..87c17f1911062 100644 --- a/x-pack/qa/full-cluster-restart/src/test/java/org/elasticsearch/xpack/restart/FullClusterRestartIT.java +++ b/x-pack/qa/full-cluster-restart/src/test/java/org/elasticsearch/xpack/restart/FullClusterRestartIT.java @@ -10,9 +10,16 @@ import org.elasticsearch.client.Request; import org.elasticsearch.client.Response; import org.elasticsearch.client.ResponseException; +import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; +import org.elasticsearch.common.xcontent.DeprecationHandler; +import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.ObjectPath; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.rest.action.document.RestGetAction; @@ -21,6 +28,8 @@ import org.elasticsearch.test.StreamsUtils; import org.elasticsearch.test.rest.ESRestTestCase; import org.elasticsearch.upgrades.AbstractFullClusterRestartTestCase; +import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicy; +import org.elasticsearch.xpack.slm.SnapshotLifecycleStats; import org.hamcrest.Matcher; import org.junit.Before; @@ -28,6 +37,7 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Base64; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; @@ -293,6 +303,39 @@ public void testRollupAfterRestart() throws Exception { assertRollUpJob("rollup-job-test"); } } + + public void testSlmStats() throws IOException { + SnapshotLifecyclePolicy slmPolicy = new SnapshotLifecyclePolicy("test-policy", "test-policy", "* * * 31 FEB ? *", "test-repo", + Collections.singletonMap("indices", Collections.singletonList("*")), null); + if (isRunningAgainstOldCluster() && getOldClusterVersion().onOrAfter(Version.V_7_4_0)) { + Request createRepoRequest = new Request("PUT", "_snapshot/test-repo"); + String repoCreateJson = "{" + + " \"type\": \"fs\"," + + " \"settings\": {" + + " \"location\": \"test-repo\"" + + " }" + + "}"; + createRepoRequest.setJsonEntity(repoCreateJson); + Request createSlmPolicyRequest = new Request("PUT", "_slm/policy/test-policy"); + try (XContentBuilder builder = JsonXContent.contentBuilder()) { + String createSlmPolicyJson = Strings.toString(slmPolicy.toXContent(builder, null)); + createSlmPolicyRequest.setJsonEntity(createSlmPolicyJson); + } + + client().performRequest(createRepoRequest); + client().performRequest(createSlmPolicyRequest); + } + + if (isRunningAgainstOldCluster() == false || getOldClusterVersion().onOrAfter(Version.V_7_5_0)) { + Response response = client().performRequest(new Request("GET", "_slm/stats")); + XContentType xContentType = XContentType.fromMediaTypeOrFormat(response.getEntity().getContentType().getValue()); + try (XContentParser parser = xContentType.xContent().createParser(NamedXContentRegistry.EMPTY, + DeprecationHandler.THROW_UNSUPPORTED_OPERATION, response.getEntity().getContent())) { + assertEquals(new SnapshotLifecycleStats(), SnapshotLifecycleStats.parse(parser)); + } + } + + } public void testRollupIDSchemeAfterRestart() throws Exception { assumeTrue("Rollup can be tested with 6.3.0 and onwards", getOldClusterVersion().onOrAfter(Version.V_6_3_0));