diff --git a/docs/changelog/80981.yaml b/docs/changelog/80981.yaml new file mode 100644 index 0000000000000..759a4b9462231 --- /dev/null +++ b/docs/changelog/80981.yaml @@ -0,0 +1,5 @@ +pr: 80981 +summary: Rollover add max_primary_shard_docs condition +area: ILM+SLM +type: enhancement +issues: [] diff --git a/docs/reference/ilm/actions/ilm-rollover.asciidoc b/docs/reference/ilm/actions/ilm-rollover.asciidoc index d6c2d70a5ac1e..b4678beaf3ad8 100644 --- a/docs/reference/ilm/actions/ilm-rollover.asciidoc +++ b/docs/reference/ilm/actions/ilm-rollover.asciidoc @@ -81,6 +81,15 @@ replicas are ignored. TIP: To see the current shard size, use the <> API. The `store` value shows the size each shard, and `prirep` indicates whether a shard is a primary (`p`) or a replica (`r`). + +`max_primary_shard_docs`:: +(Optional, integer) +Triggers rollover when the largest primary shard in the index reaches a certain number of documents. +This is the maximum docs of the primary shards in the index. As with `max_docs`, +replicas are ignored. ++ +TIP: To see the current shard docs, use the <> API. +The `docs` value shows the number of documents each shard. // end::rollover-conditions[] [[ilm-rollover-ex]] @@ -155,6 +164,29 @@ PUT _ilm/policy/my_policy } -------------------------------------------------- +[ilm-rollover-documents-ex]] +===== Roll over based on document count of the largest primary shard + +This example rolls the index over when it contains at least ten million documents of the largest primary shard. + +[source,console] +-------------------------------------------------- +PUT _ilm/policy/my_policy +{ + "policy": { + "phases": { + "hot": { + "actions": { + "rollover" : { + "max_primary_shard_docs": 10000000 + } + } + } + } + } +} +-------------------------------------------------- + [ilm-rollover-age-ex]] ===== Roll over based on index age diff --git a/docs/reference/indices/rollover-index.asciidoc b/docs/reference/indices/rollover-index.asciidoc index 36378ca804922..d8d67c29a540e 100644 --- a/docs/reference/indices/rollover-index.asciidoc +++ b/docs/reference/indices/rollover-index.asciidoc @@ -79,7 +79,7 @@ If you use an index alias for time series data, you can use date. For example, you can create an alias that points to an index named ``. If you create the index on May 6, 2099, the index's name is `my-index-2099.05.06-000001`. If you roll over the alias on May 7, 2099, -the new index's name is `my-index-2099.05.07-000002`. For an example, see +the new index's name is `my-index-2099.05.07-000002`. For an example, see <>. **** @@ -233,7 +233,8 @@ POST my-data-stream/_rollover "conditions": { "max_age": "7d", "max_docs": 1000, - "max_primary_shard_size": "50gb" + "max_primary_shard_size": "50gb", + "max_primary_shard_docs": "2000" } } ---- @@ -255,7 +256,8 @@ The API returns: "conditions": { "[max_age: 7d]": false, "[max_docs: 1000]": true, - "[max_primary_shard_size: 50gb]": false + "[max_primary_shard_size: 50gb]": false, + "[max_primary_shard_docs: 2000]": false } } ---- @@ -302,7 +304,8 @@ POST my-alias/_rollover "conditions": { "max_age": "7d", "max_docs": 1000, - "max_primary_shard_size": "50gb" + "max_primary_shard_size": "50gb", + "max_primary_shard_docs": "2000" } } ---- @@ -324,7 +327,8 @@ The API returns: "conditions": { "[max_age: 7d]": false, "[max_docs: 1000]": true, - "[max_primary_shard_size: 50gb]": false + "[max_primary_shard_size: 50gb]": false, + "[max_primary_shard_docs: 2000]": false } } ---- @@ -371,7 +375,8 @@ POST my-write-alias/_rollover "conditions": { "max_age": "7d", "max_docs": 1000, - "max_primary_shard_size": "50gb" + "max_primary_shard_size": "50gb", + "max_primary_shard_docs": "2000" } } ---- @@ -393,7 +398,8 @@ The API returns: "conditions": { "[max_age: 7d]": false, "[max_docs: 1000]": true, - "[max_primary_shard_size: 50gb]": false + "[max_primary_shard_size: 50gb]": false, + "[max_primary_shard_docs: 2000]": false } } ---- diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.rollover/25_max_shard_doc_condition.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.rollover/25_max_shard_doc_condition.yml new file mode 100644 index 0000000000000..36d33175881fa --- /dev/null +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.rollover/25_max_shard_doc_condition.yml @@ -0,0 +1,59 @@ +--- +"Rollover with max_primary_shard_docs condition": + - skip: + version: " - 8.1.99" + reason: introduced in 8.2.0 + + # create index with alias and replica + - do: + indices.create: + index: logs-1 + wait_for_active_shards: 1 + body: + settings: + index: + number_of_shards: 1 + number_of_replicas: 0 + aliases: + logs_search: {} + + # index first document and wait for refresh + - do: + index: + index: logs-1 + id: "1" + body: { "foo": "hello world" } + refresh: true + + # perform alias rollover with no result + - do: + indices.rollover: + alias: "logs_search" + wait_for_active_shards: 1 + body: + conditions: + max_primary_shard_docs: 2 + + - match: { conditions: { "[max_primary_shard_docs: 2]": false } } + - match: { rolled_over: false } + + # index second document and wait for refresh + - do: + index: + index: logs-1 + id: "2" + body: { "foo": "hello world" } + refresh: true + + # perform alias rollover + - do: + indices.rollover: + alias: "logs_search" + wait_for_active_shards: 1 + body: + conditions: + max_primary_shard_docs: 2 + + - match: { conditions: { "[max_primary_shard_docs: 2]": true } } + - match: { rolled_over: true } + diff --git a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/rollover/RolloverIT.java b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/rollover/RolloverIT.java index fd81cb37aa67a..d88d67f77dba0 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/rollover/RolloverIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/rollover/RolloverIT.java @@ -542,6 +542,71 @@ public void testRolloverMaxPrimaryShardSize() throws Exception { } } + public void testRolloverMaxPrimaryShardDocs() throws Exception { + assertAcked( + prepareCreate("test-1").setSettings(Settings.builder().put("index.number_of_shards", 1)).addAlias(new Alias("test_alias")).get() + ); + int numDocs = randomIntBetween(10, 20); + for (int i = 0; i < numDocs; i++) { + indexDoc("test-1", Integer.toString(i), "field", "foo-" + i); + } + flush("test-1"); + refresh("test_alias"); + + // A large max_primary_shard_docs + { + final RolloverResponse response = client().admin() + .indices() + .prepareRolloverIndex("test_alias") + .addMaxPrimaryShardDocsCondition(randomIntBetween(21, 30)) + .get(); + assertThat(response.getOldIndex(), equalTo("test-1")); + assertThat(response.getNewIndex(), equalTo("test-000002")); + assertThat("No rollover with a large max_primary_shard_docs condition", response.isRolledOver(), equalTo(false)); + final IndexMetadata oldIndex = client().admin().cluster().prepareState().get().getState().metadata().index("test-1"); + assertThat(oldIndex.getRolloverInfos().size(), equalTo(0)); + } + + // A small max_primary_shard_docs + { + MaxPrimaryShardDocsCondition maxPrimaryShardDocsCondition = new MaxPrimaryShardDocsCondition(randomLongBetween(1, 9)); + long beforeTime = client().threadPool().absoluteTimeInMillis() - 1000L; + final RolloverResponse response = client().admin() + .indices() + .prepareRolloverIndex("test_alias") + .addMaxPrimaryShardDocsCondition(maxPrimaryShardDocsCondition.value) + .get(); + assertThat(response.getOldIndex(), equalTo("test-1")); + assertThat(response.getNewIndex(), equalTo("test-000002")); + assertThat("Should rollover with a small max_primary_shard_docs condition", response.isRolledOver(), equalTo(true)); + final IndexMetadata oldIndex = client().admin().cluster().prepareState().get().getState().metadata().index("test-1"); + List> metConditions = oldIndex.getRolloverInfos().get("test_alias").getMetConditions(); + assertThat(metConditions.size(), equalTo(1)); + assertThat( + metConditions.get(0).toString(), + equalTo(new MaxPrimaryShardDocsCondition(maxPrimaryShardDocsCondition.value).toString()) + ); + assertThat( + oldIndex.getRolloverInfos().get("test_alias").getTime(), + is(both(greaterThanOrEqualTo(beforeTime)).and(lessThanOrEqualTo(client().threadPool().absoluteTimeInMillis() + 1000L))) + ); + } + + // An empty index + { + final RolloverResponse response = client().admin() + .indices() + .prepareRolloverIndex("test_alias") + .addMaxPrimaryShardDocsCondition(randomNonNegativeLong()) + .get(); + assertThat(response.getOldIndex(), equalTo("test-000002")); + assertThat(response.getNewIndex(), equalTo("test-000003")); + assertThat("No rollover with an empty index", response.isRolledOver(), equalTo(false)); + final IndexMetadata oldIndex = client().admin().cluster().prepareState().get().getState().metadata().index("test-000002"); + assertThat(oldIndex.getRolloverInfos().size(), equalTo(0)); + } + } + public void testRejectIfAliasFoundInTemplate() throws Exception { client().admin() .indices() diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/Condition.java b/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/Condition.java index 196825b9daec3..dd30274a1cc0d 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/Condition.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/Condition.java @@ -70,7 +70,13 @@ public String name() { /** * Holder for index stats used to evaluate conditions */ - public record Stats(long numDocs, long indexCreated, ByteSizeValue indexSize, ByteSizeValue maxPrimaryShardSize) {} + public record Stats( + long numDocs, + long indexCreated, + ByteSizeValue indexSize, + ByteSizeValue maxPrimaryShardSize, + long maxPrimaryShardDocs + ) {} /** * Holder for evaluated condition result diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/MaxPrimaryShardDocsCondition.java b/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/MaxPrimaryShardDocsCondition.java new file mode 100644 index 0000000000000..ed0b2ff13685a --- /dev/null +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/MaxPrimaryShardDocsCondition.java @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.action.admin.indices.rollover; + +import org.elasticsearch.Version; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xcontent.XContentParser; + +import java.io.IOException; + +public class MaxPrimaryShardDocsCondition extends Condition { + public static final String NAME = "max_primary_shard_docs"; + + public MaxPrimaryShardDocsCondition(Long value) { + super(NAME); + this.value = value; + } + + public MaxPrimaryShardDocsCondition(StreamInput in) throws IOException { + super(NAME); + this.value = in.readLong(); + } + + @Override + public Result evaluate(Stats stats) { + return new Result(this, this.value <= stats.maxPrimaryShardDocs()); + } + + @Override + public String getWriteableName() { + return NAME; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeLong(value); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + return builder.field(NAME, value); + } + + public static MaxPrimaryShardDocsCondition fromXContent(XContentParser parser) throws IOException { + if (parser.nextToken() == XContentParser.Token.VALUE_NUMBER) { + return new MaxPrimaryShardDocsCondition(parser.longValue()); + } else { + throw new IllegalArgumentException("invalid token: " + parser.currentToken()); + } + } + + @Override + boolean includedInVersion(Version version) { + return version.onOrAfter(Version.V_8_2_0); + } +} diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequest.java b/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequest.java index 7a7f98de797e4..70ffaef453ee2 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequest.java @@ -46,6 +46,7 @@ public class RolloverRequest extends AcknowledgedRequest implem private static final ParseField MAX_DOCS_CONDITION = new ParseField(MaxDocsCondition.NAME); private static final ParseField MAX_SIZE_CONDITION = new ParseField(MaxSizeCondition.NAME); private static final ParseField MAX_PRIMARY_SHARD_SIZE_CONDITION = new ParseField(MaxPrimaryShardSizeCondition.NAME); + private static final ParseField MAX_PRIMARY_SHARD_DOCS_CONDITION = new ParseField(MaxPrimaryShardDocsCondition.NAME); static { CONDITION_PARSER.declareString( @@ -70,6 +71,10 @@ public class RolloverRequest extends AcknowledgedRequest implem ), MAX_PRIMARY_SHARD_SIZE_CONDITION ); + CONDITION_PARSER.declareLong( + (conditions, value) -> conditions.put(MaxPrimaryShardDocsCondition.NAME, new MaxPrimaryShardDocsCondition(value)), + MAX_PRIMARY_SHARD_DOCS_CONDITION + ); PARSER.declareField( (parser, request, context) -> CONDITION_PARSER.parse(parser, request.conditions, null), @@ -256,6 +261,17 @@ public void addMaxPrimaryShardSizeCondition(ByteSizeValue size) { this.conditions.put(maxPrimaryShardSizeCondition.name, maxPrimaryShardSizeCondition); } + /** + * Adds a size-based condition to check if the docs of the largest primary shard has at least numDocs + */ + public void addMaxPrimaryShardDocsCondition(long numDocs) { + MaxPrimaryShardDocsCondition maxPrimaryShardDocsCondition = new MaxPrimaryShardDocsCondition(numDocs); + if (this.conditions.containsKey(maxPrimaryShardDocsCondition.name)) { + throw new IllegalArgumentException(maxPrimaryShardDocsCondition.name + " condition is already set"); + } + this.conditions.put(maxPrimaryShardDocsCondition.name, maxPrimaryShardDocsCondition); + } + public boolean isDryRun() { return dryRun; } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestBuilder.java b/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestBuilder.java index 7efb4f95e39f3..27300b6213f56 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestBuilder.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestBuilder.java @@ -50,6 +50,11 @@ public RolloverRequestBuilder addMaxPrimaryShardSizeCondition(ByteSizeValue size return this; } + public RolloverRequestBuilder addMaxPrimaryShardDocsCondition(long docs) { + this.request.addMaxPrimaryShardDocsCondition(docs); + return this; + } + public RolloverRequestBuilder dryRun(boolean dryRun) { this.request.dryRun(dryRun); return this; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/TransportRolloverAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/TransportRolloverAction.java index aadbd728385d1..8a57f56f6777d 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/TransportRolloverAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/rollover/TransportRolloverAction.java @@ -222,11 +222,22 @@ static Condition.Stats buildStats(@Nullable final IndexMetadata metadata, @Nulla .max() .orElse(0); + final long maxPrimaryShardDocs = indexStats.stream() + .map(IndexStats::getShards) + .filter(Objects::nonNull) + .flatMap(Arrays::stream) + .filter(shard -> shard.getShardRouting().primary()) + .map(ShardStats::getStats) + .mapToLong(shard -> shard.docs.getCount()) + .max() + .orElse(0); + return new Condition.Stats( docsStats == null ? 0 : docsStats.getCount(), metadata.getCreationDate(), new ByteSizeValue(docsStats == null ? 0 : docsStats.getTotalSizeInBytes()), - new ByteSizeValue(maxPrimaryShardSize) + new ByteSizeValue(maxPrimaryShardSize), + maxPrimaryShardDocs ); } } diff --git a/server/src/main/java/org/elasticsearch/indices/IndicesModule.java b/server/src/main/java/org/elasticsearch/indices/IndicesModule.java index 917f261c219ea..f67727d67f449 100644 --- a/server/src/main/java/org/elasticsearch/indices/IndicesModule.java +++ b/server/src/main/java/org/elasticsearch/indices/IndicesModule.java @@ -11,6 +11,7 @@ import org.elasticsearch.action.admin.indices.rollover.Condition; import org.elasticsearch.action.admin.indices.rollover.MaxAgeCondition; import org.elasticsearch.action.admin.indices.rollover.MaxDocsCondition; +import org.elasticsearch.action.admin.indices.rollover.MaxPrimaryShardDocsCondition; import org.elasticsearch.action.admin.indices.rollover.MaxPrimaryShardSizeCondition; import org.elasticsearch.action.admin.indices.rollover.MaxSizeCondition; import org.elasticsearch.action.resync.TransportResyncReplicationAction; @@ -93,7 +94,8 @@ public static List getNamedWriteables() { new NamedWriteableRegistry.Entry(Condition.class, MaxAgeCondition.NAME, MaxAgeCondition::new), new NamedWriteableRegistry.Entry(Condition.class, MaxDocsCondition.NAME, MaxDocsCondition::new), new NamedWriteableRegistry.Entry(Condition.class, MaxSizeCondition.NAME, MaxSizeCondition::new), - new NamedWriteableRegistry.Entry(Condition.class, MaxPrimaryShardSizeCondition.NAME, MaxPrimaryShardSizeCondition::new) + new NamedWriteableRegistry.Entry(Condition.class, MaxPrimaryShardSizeCondition.NAME, MaxPrimaryShardSizeCondition::new), + new NamedWriteableRegistry.Entry(Condition.class, MaxPrimaryShardDocsCondition.NAME, MaxPrimaryShardDocsCondition::new) ); } @@ -118,6 +120,11 @@ public static List getNamedXContents() { Condition.class, new ParseField(MaxPrimaryShardSizeCondition.NAME), (p, c) -> MaxPrimaryShardSizeCondition.fromXContent(p) + ), + new NamedXContentRegistry.Entry( + Condition.class, + new ParseField(MaxPrimaryShardDocsCondition.NAME), + (p, c) -> MaxPrimaryShardDocsCondition.fromXContent(p) ) ); } diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/ConditionTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/ConditionTests.java index d4a4b79307331..ae3cbdfedcdad 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/ConditionTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/ConditionTests.java @@ -21,12 +21,16 @@ public void testMaxAge() { final MaxAgeCondition maxAgeCondition = new MaxAgeCondition(TimeValue.timeValueHours(1)); long indexCreatedMatch = System.currentTimeMillis() - TimeValue.timeValueMinutes(61).getMillis(); - Condition.Result evaluate = maxAgeCondition.evaluate(new Condition.Stats(0, indexCreatedMatch, randomByteSize(), randomByteSize())); + Condition.Result evaluate = maxAgeCondition.evaluate( + new Condition.Stats(0, indexCreatedMatch, randomByteSize(), randomByteSize(), randomNonNegativeLong()) + ); assertThat(evaluate.condition(), equalTo(maxAgeCondition)); assertThat(evaluate.matched(), equalTo(true)); long indexCreatedNotMatch = System.currentTimeMillis() - TimeValue.timeValueMinutes(59).getMillis(); - evaluate = maxAgeCondition.evaluate(new Condition.Stats(0, indexCreatedNotMatch, randomByteSize(), randomByteSize())); + evaluate = maxAgeCondition.evaluate( + new Condition.Stats(0, indexCreatedNotMatch, randomByteSize(), randomByteSize(), randomNonNegativeLong()) + ); assertThat(evaluate.condition(), equalTo(maxAgeCondition)); assertThat(evaluate.matched(), equalTo(false)); } @@ -35,12 +39,16 @@ public void testMaxDocs() { final MaxDocsCondition maxDocsCondition = new MaxDocsCondition(100L); long maxDocsMatch = randomIntBetween(100, 1000); - Condition.Result evaluate = maxDocsCondition.evaluate(new Condition.Stats(maxDocsMatch, 0, randomByteSize(), randomByteSize())); + Condition.Result evaluate = maxDocsCondition.evaluate( + new Condition.Stats(maxDocsMatch, 0, randomByteSize(), randomByteSize(), randomNonNegativeLong()) + ); assertThat(evaluate.condition(), equalTo(maxDocsCondition)); assertThat(evaluate.matched(), equalTo(true)); long maxDocsNotMatch = randomIntBetween(0, 99); - evaluate = maxDocsCondition.evaluate(new Condition.Stats(maxDocsNotMatch, 0, randomByteSize(), randomByteSize())); + evaluate = maxDocsCondition.evaluate( + new Condition.Stats(maxDocsNotMatch, 0, randomByteSize(), randomByteSize(), randomNonNegativeLong()) + ); assertThat(evaluate.condition(), equalTo(maxDocsCondition)); assertThat(evaluate.matched(), equalTo(false)); } @@ -49,7 +57,13 @@ public void testMaxSize() { MaxSizeCondition maxSizeCondition = new MaxSizeCondition(ByteSizeValue.ofMb(randomIntBetween(10, 20))); Condition.Result result = maxSizeCondition.evaluate( - new Condition.Stats(randomNonNegativeLong(), randomNonNegativeLong(), ByteSizeValue.ofMb(0), randomByteSize()) + new Condition.Stats( + randomNonNegativeLong(), + randomNonNegativeLong(), + ByteSizeValue.ofMb(0), + randomByteSize(), + randomNonNegativeLong() + ) ); assertThat(result.matched(), equalTo(false)); @@ -58,7 +72,8 @@ public void testMaxSize() { randomNonNegativeLong(), randomNonNegativeLong(), ByteSizeValue.ofMb(randomIntBetween(0, 9)), - randomByteSize() + randomByteSize(), + randomNonNegativeLong() ) ); assertThat(result.matched(), equalTo(false)); @@ -68,7 +83,8 @@ public void testMaxSize() { randomNonNegativeLong(), randomNonNegativeLong(), ByteSizeValue.ofMb(randomIntBetween(20, 1000)), - randomByteSize() + randomByteSize(), + randomNonNegativeLong() ) ); assertThat(result.matched(), equalTo(true)); @@ -80,7 +96,13 @@ public void testMaxPrimaryShardSize() { ); Condition.Result result = maxPrimaryShardSizeCondition.evaluate( - new Condition.Stats(randomNonNegativeLong(), randomNonNegativeLong(), randomByteSize(), ByteSizeValue.ofMb(0)) + new Condition.Stats( + randomNonNegativeLong(), + randomNonNegativeLong(), + randomByteSize(), + ByteSizeValue.ofMb(0), + randomNonNegativeLong() + ) ); assertThat(result.matched(), equalTo(false)); @@ -89,7 +111,8 @@ public void testMaxPrimaryShardSize() { randomNonNegativeLong(), randomNonNegativeLong(), randomByteSize(), - ByteSizeValue.ofMb(randomIntBetween(0, 9)) + ByteSizeValue.ofMb(randomIntBetween(0, 9)), + randomNonNegativeLong() ) ); assertThat(result.matched(), equalTo(false)); @@ -99,12 +122,31 @@ public void testMaxPrimaryShardSize() { randomNonNegativeLong(), randomNonNegativeLong(), randomByteSize(), - ByteSizeValue.ofMb(randomIntBetween(20, 1000)) + ByteSizeValue.ofMb(randomIntBetween(20, 1000)), + randomNonNegativeLong() ) ); assertThat(result.matched(), equalTo(true)); } + public void testMaxPrimaryShardDocs() { + final MaxPrimaryShardDocsCondition maxPrimaryShardDocsCondition = new MaxPrimaryShardDocsCondition(100L); + + long maxPrimaryShardDocsMatch = randomIntBetween(100, 1000); + Condition.Result evaluate = maxPrimaryShardDocsCondition.evaluate( + new Condition.Stats(randomNonNegativeLong(), 0, randomByteSize(), randomByteSize(), maxPrimaryShardDocsMatch) + ); + assertThat(evaluate.condition(), equalTo(maxPrimaryShardDocsCondition)); + assertThat(evaluate.matched(), equalTo(true)); + + long maxPrimaryShardDocsNotMatch = randomIntBetween(0, 99); + evaluate = maxPrimaryShardDocsCondition.evaluate( + new Condition.Stats(randomNonNegativeLong(), 0, randomByteSize(), randomByteSize(), maxPrimaryShardDocsNotMatch) + ); + assertThat(evaluate.condition(), equalTo(maxPrimaryShardDocsCondition)); + assertThat(evaluate.matched(), equalTo(false)); + } + public void testEqualsAndHashCode() { MaxAgeCondition maxAgeCondition = new MaxAgeCondition(new TimeValue(randomNonNegativeLong())); EqualsHashCodeTestUtils.checkEqualsAndHashCode( @@ -133,6 +175,13 @@ public void testEqualsAndHashCode() { condition -> new MaxPrimaryShardSizeCondition(condition.value), condition -> new MaxPrimaryShardSizeCondition(randomByteSize()) ); + + MaxPrimaryShardDocsCondition maxPrimaryShardDocsCondition = new MaxPrimaryShardDocsCondition(randomNonNegativeLong()); + EqualsHashCodeTestUtils.checkEqualsAndHashCode( + maxPrimaryShardDocsCondition, + condition -> new MaxPrimaryShardDocsCondition(condition.value), + condition -> new MaxPrimaryShardDocsCondition(randomNonNegativeLong()) + ); } private static ByteSizeValue randomByteSize() { diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestTests.java index 44ef109df9d44..05cb665824b3b 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestTests.java @@ -61,11 +61,12 @@ public void testConditionsParsing() throws Exception { .field("max_docs", 100) .field("max_size", "45gb") .field("max_primary_shard_size", "55gb") + .field("max_primary_shard_docs", 10) .endObject() .endObject(); request.fromXContent(false, createParser(builder)); Map> conditions = request.getConditions(); - assertThat(conditions.size(), equalTo(4)); + assertThat(conditions.size(), equalTo(5)); MaxAgeCondition maxAgeCondition = (MaxAgeCondition) conditions.get(MaxAgeCondition.NAME); assertThat(maxAgeCondition.value.getMillis(), equalTo(TimeValue.timeValueHours(24 * 10).getMillis())); MaxDocsCondition maxDocsCondition = (MaxDocsCondition) conditions.get(MaxDocsCondition.NAME); @@ -76,6 +77,10 @@ public void testConditionsParsing() throws Exception { MaxPrimaryShardSizeCondition.NAME ); assertThat(maxPrimaryShardSizeCondition.value.getBytes(), equalTo(ByteSizeUnit.GB.toBytes(55))); + MaxPrimaryShardDocsCondition maxPrimaryShardDocsCondition = (MaxPrimaryShardDocsCondition) conditions.get( + MaxPrimaryShardDocsCondition.NAME + ); + assertThat(maxPrimaryShardDocsCondition.value, equalTo(10L)); } public void testParsingWithIndexSettings() throws Exception { @@ -85,6 +90,7 @@ public void testParsingWithIndexSettings() throws Exception { .startObject("conditions") .field("max_age", "10d") .field("max_docs", 100) + .field("max_primary_shard_docs", 10) .endObject() .startObject("mappings") .startObject("properties") @@ -104,7 +110,7 @@ public void testParsingWithIndexSettings() throws Exception { .endObject(); request.fromXContent(false, createParser(builder)); Map> conditions = request.getConditions(); - assertThat(conditions.size(), equalTo(2)); + assertThat(conditions.size(), equalTo(3)); assertThat(request.getCreateIndexRequest().mappings(), containsString("not_analyzed")); assertThat(request.getCreateIndexRequest().aliases().size(), equalTo(1)); assertThat(request.getCreateIndexRequest().settings().getAsInt("number_of_shards", 0), equalTo(10)); @@ -142,6 +148,7 @@ public void testSerialize() throws Exception { originalRequest.addMaxIndexDocsCondition(randomNonNegativeLong()); originalRequest.addMaxIndexAgeCondition(TimeValue.timeValueNanos(randomNonNegativeLong())); originalRequest.addMaxIndexSizeCondition(new ByteSizeValue(randomNonNegativeLong())); + originalRequest.addMaxPrimaryShardDocsCondition(randomNonNegativeLong()); try (BytesStreamOutput out = new BytesStreamOutput()) { originalRequest.writeTo(out); BytesReference bytes = out.bytes(); diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverResponseTests.java index 651a6d8dd4f06..fbd5ced1e0a37 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverResponseTests.java @@ -54,6 +54,7 @@ private static Map randomResults(boolean allowNoItems) { conditionSuppliers.add(() -> new MaxDocsCondition(randomNonNegativeLong())); conditionSuppliers.add(() -> new MaxSizeCondition(new ByteSizeValue(randomNonNegativeLong()))); conditionSuppliers.add(() -> new MaxPrimaryShardSizeCondition(new ByteSizeValue(randomNonNegativeLong()))); + conditionSuppliers.add(() -> new MaxPrimaryShardDocsCondition(randomNonNegativeLong())); } @Override diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/TransportRolloverActionTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/TransportRolloverActionTests.java index 0fc3b77660bb7..bcd0614d1f136 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/TransportRolloverActionTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/TransportRolloverActionTests.java @@ -107,38 +107,47 @@ public void testEvaluateConditions() { MaxPrimaryShardSizeCondition maxPrimaryShardSizeCondition = new MaxPrimaryShardSizeCondition( ByteSizeValue.ofMb(randomIntBetween(10, 100)) ); - final Set> conditions = Set.of(maxAgeCondition, maxDocsCondition, maxSizeCondition, maxPrimaryShardSizeCondition); + MaxPrimaryShardDocsCondition maxPrimaryShardDocsCondition = new MaxPrimaryShardDocsCondition(10L); + final Set> conditions = Set.of( + maxAgeCondition, + maxDocsCondition, + maxSizeCondition, + maxPrimaryShardSizeCondition, + maxPrimaryShardDocsCondition + ); long matchMaxDocs = randomIntBetween(100, 1000); long notMatchMaxDocs = randomIntBetween(0, 99); ByteSizeValue notMatchMaxSize = ByteSizeValue.ofMb(randomIntBetween(0, 9)); long indexCreated = TimeValue.timeValueHours(3).getMillis(); + long matchMaxPrimaryShardDocs = randomIntBetween(10, 100); + long notMatchMaxPrimaryShardDocs = randomIntBetween(0, 9); expectThrows( NullPointerException.class, - () -> evaluateConditions(null, new Condition.Stats(0, 0, ByteSizeValue.ofMb(0), ByteSizeValue.ofMb(0))) + () -> evaluateConditions(null, new Condition.Stats(0, 0, ByteSizeValue.ofMb(0), ByteSizeValue.ofMb(0), 0)) ); Map results = evaluateConditions(conditions, null); - assertThat(results.size(), equalTo(4)); + assertThat(results.size(), equalTo(5)); for (Boolean matched : results.values()) { assertThat(matched, equalTo(false)); } results = evaluateConditions( conditions, - new Condition.Stats(matchMaxDocs, indexCreated, ByteSizeValue.ofMb(120), ByteSizeValue.ofMb(120)) + new Condition.Stats(matchMaxDocs, indexCreated, ByteSizeValue.ofMb(120), ByteSizeValue.ofMb(120), matchMaxPrimaryShardDocs) ); - assertThat(results.size(), equalTo(4)); + assertThat(results.size(), equalTo(5)); for (Boolean matched : results.values()) { assertThat(matched, equalTo(true)); } results = evaluateConditions( conditions, - new Condition.Stats(notMatchMaxDocs, indexCreated, notMatchMaxSize, ByteSizeValue.ofMb(0)) + new Condition.Stats(notMatchMaxDocs, indexCreated, notMatchMaxSize, ByteSizeValue.ofMb(0), notMatchMaxPrimaryShardDocs) ); - assertThat(results.size(), equalTo(4)); + assertThat(results.size(), equalTo(5)); for (Map.Entry entry : results.entrySet()) { if (entry.getKey().equals(maxAgeCondition.toString())) { assertThat(entry.getValue(), equalTo(true)); @@ -148,6 +157,8 @@ public void testEvaluateConditions() { assertThat(entry.getValue(), equalTo(false)); } else if (entry.getKey().equals(maxPrimaryShardSizeCondition.toString())) { assertThat(entry.getValue(), equalTo(false)); + } else if (entry.getKey().equals(maxPrimaryShardDocsCondition.toString())) { + assertThat(entry.getValue(), equalTo(false)); } else { fail("unknown condition result found " + entry.getKey()); } @@ -161,7 +172,14 @@ public void testEvaluateWithoutStats() { MaxPrimaryShardSizeCondition maxPrimaryShardSizeCondition = new MaxPrimaryShardSizeCondition( new ByteSizeValue(randomNonNegativeLong()) ); - final Set> conditions = Set.of(maxAgeCondition, maxDocsCondition, maxSizeCondition, maxPrimaryShardSizeCondition); + MaxPrimaryShardDocsCondition maxPrimaryShardDocsCondition = new MaxPrimaryShardDocsCondition(randomNonNegativeLong()); + final Set> conditions = Set.of( + maxAgeCondition, + maxDocsCondition, + maxSizeCondition, + maxPrimaryShardSizeCondition, + maxPrimaryShardDocsCondition + ); final Settings settings = Settings.builder() .put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT) @@ -175,7 +193,7 @@ public void testEvaluateWithoutStats() { .settings(settings) .build(); Map results = evaluateConditions(conditions, buildStats(metadata, null)); - assertThat(results.size(), equalTo(4)); + assertThat(results.size(), equalTo(5)); for (Map.Entry entry : results.entrySet()) { if (entry.getKey().equals(maxAgeCondition.toString())) { @@ -186,6 +204,8 @@ public void testEvaluateWithoutStats() { assertThat(entry.getValue(), equalTo(false)); } else if (entry.getKey().equals(maxPrimaryShardSizeCondition.toString())) { assertThat(entry.getValue(), equalTo(false)); + } else if (entry.getKey().equals(maxPrimaryShardDocsCondition.toString())) { + assertThat(entry.getValue(), equalTo(false)); } else { fail("unknown condition result found " + entry.getKey()); } @@ -199,7 +219,14 @@ public void testEvaluateWithoutMetadata() { MaxPrimaryShardSizeCondition maxPrimaryShardSizeCondition = new MaxPrimaryShardSizeCondition( ByteSizeValue.ofMb(randomIntBetween(10, 100)) ); - final Set> conditions = Set.of(maxAgeCondition, maxDocsCondition, maxSizeCondition, maxPrimaryShardSizeCondition); + MaxPrimaryShardDocsCondition maxPrimaryShardDocsCondition = new MaxPrimaryShardDocsCondition(10L); + final Set> conditions = Set.of( + maxAgeCondition, + maxDocsCondition, + maxSizeCondition, + maxPrimaryShardSizeCondition, + maxPrimaryShardDocsCondition + ); final Settings settings = Settings.builder() .put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT) @@ -214,7 +241,7 @@ public void testEvaluateWithoutMetadata() { .build(); IndicesStatsResponse indicesStats = randomIndicesStatsResponse(new IndexMetadata[] { metadata }); Map results = evaluateConditions(conditions, buildStats(null, indicesStats)); - assertThat(results.size(), equalTo(4)); + assertThat(results.size(), equalTo(5)); results.forEach((k, v) -> assertFalse(v)); } diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/IndexMetadataTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/IndexMetadataTests.java index 4fb6402dd3ffa..4f606a91a8c8d 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/IndexMetadataTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/IndexMetadataTests.java @@ -11,6 +11,7 @@ import org.elasticsearch.Version; import org.elasticsearch.action.admin.indices.rollover.MaxAgeCondition; import org.elasticsearch.action.admin.indices.rollover.MaxDocsCondition; +import org.elasticsearch.action.admin.indices.rollover.MaxPrimaryShardDocsCondition; import org.elasticsearch.action.admin.indices.rollover.MaxPrimaryShardSizeCondition; import org.elasticsearch.action.admin.indices.rollover.MaxSizeCondition; import org.elasticsearch.action.admin.indices.rollover.RolloverInfo; @@ -92,7 +93,8 @@ public void testIndexMetadataSerialization() throws IOException { new MaxAgeCondition(TimeValue.timeValueMillis(randomNonNegativeLong())), new MaxDocsCondition(randomNonNegativeLong()), new MaxSizeCondition(new ByteSizeValue(randomNonNegativeLong())), - new MaxPrimaryShardSizeCondition(new ByteSizeValue(randomNonNegativeLong())) + new MaxPrimaryShardSizeCondition(new ByteSizeValue(randomNonNegativeLong())), + new MaxPrimaryShardDocsCondition(randomNonNegativeLong()) ), randomNonNegativeLong() ) diff --git a/server/src/test/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommandTests.java b/server/src/test/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommandTests.java index 067323ebc4020..8bf35d15c72d7 100644 --- a/server/src/test/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommandTests.java +++ b/server/src/test/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommandTests.java @@ -17,6 +17,7 @@ import org.elasticsearch.action.admin.indices.rollover.Condition; import org.elasticsearch.action.admin.indices.rollover.MaxAgeCondition; import org.elasticsearch.action.admin.indices.rollover.MaxDocsCondition; +import org.elasticsearch.action.admin.indices.rollover.MaxPrimaryShardDocsCondition; import org.elasticsearch.action.admin.indices.rollover.MaxPrimaryShardSizeCondition; import org.elasticsearch.action.admin.indices.rollover.MaxSizeCondition; import org.elasticsearch.action.admin.indices.rollover.RolloverInfo; @@ -134,7 +135,8 @@ public void setup() throws IOException { new MaxAgeCondition(new TimeValue(randomNonNegativeLong())), new MaxDocsCondition(randomNonNegativeLong()), new MaxPrimaryShardSizeCondition(new ByteSizeValue(randomNonNegativeLong())), - new MaxSizeCondition(new ByteSizeValue(randomNonNegativeLong())) + new MaxSizeCondition(new ByteSizeValue(randomNonNegativeLong())), + new MaxPrimaryShardDocsCondition(randomNonNegativeLong()) ); final IndexMetadata.Builder metadata = IndexMetadata.builder(routing.getIndexName()) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/IndexLifecycleFeatureSetUsage.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/IndexLifecycleFeatureSetUsage.java index 1c134fdd82452..bfa8fde321844 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/IndexLifecycleFeatureSetUsage.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/IndexLifecycleFeatureSetUsage.java @@ -228,6 +228,7 @@ public static final class ActionConfigStats implements ToXContentObject, Writeab private final Integer forceMergeMaxNumberOfSegments; private final TimeValue rolloverMaxAge; private final Long rolloverMaxDocs; + private final Long rolloverMaxPrimaryShardDocs; private final ByteSizeValue rolloverMaxPrimaryShardSize; private final ByteSizeValue rolloverMaxSize; private final Integer setPriorityPriority; @@ -247,6 +248,7 @@ public static final class Builder { private Integer forceMergeMaxNumberOfSegments; private TimeValue rolloverMaxAge; private Long rolloverMaxDocs; + private Long rolloverMaxPrimaryShardDocs; private ByteSizeValue rolloverMaxPrimaryShardSize; private ByteSizeValue rolloverMaxSize; private Integer setPriorityPriority; @@ -260,6 +262,7 @@ public Builder(ActionConfigStats existing) { this.forceMergeMaxNumberOfSegments = existing.forceMergeMaxNumberOfSegments; this.rolloverMaxAge = existing.rolloverMaxAge; this.rolloverMaxDocs = existing.rolloverMaxDocs; + this.rolloverMaxPrimaryShardDocs = existing.rolloverMaxPrimaryShardDocs; this.rolloverMaxPrimaryShardSize = existing.rolloverMaxPrimaryShardSize; this.rolloverMaxSize = existing.rolloverMaxSize; this.setPriorityPriority = existing.setPriorityPriority; @@ -287,6 +290,10 @@ public Builder setRolloverMaxDocs(Long rolloverMaxDocs) { return this; } + public void setRolloverMaxPrimaryShardDocs(Long rolloverMaxPrimaryShardDocs) { + this.rolloverMaxPrimaryShardDocs = rolloverMaxPrimaryShardDocs; + } + public Builder setRolloverMaxPrimaryShardSize(ByteSizeValue rolloverMaxPrimaryShardSize) { this.rolloverMaxPrimaryShardSize = rolloverMaxPrimaryShardSize; return this; @@ -318,6 +325,7 @@ public ActionConfigStats build() { forceMergeMaxNumberOfSegments, rolloverMaxAge, rolloverMaxDocs, + rolloverMaxPrimaryShardDocs, rolloverMaxPrimaryShardSize, rolloverMaxSize, setPriorityPriority, @@ -332,6 +340,7 @@ public ActionConfigStats( Integer forceMergeMaxNumberOfSegments, TimeValue rolloverMaxAge, Long rolloverMaxDocs, + Long rolloverMaxPrimaryShardDocs, ByteSizeValue rolloverMaxPrimaryShardSize, ByteSizeValue rolloverMaxSize, Integer setPriorityPriority, @@ -342,6 +351,7 @@ public ActionConfigStats( this.forceMergeMaxNumberOfSegments = forceMergeMaxNumberOfSegments; this.rolloverMaxAge = rolloverMaxAge; this.rolloverMaxDocs = rolloverMaxDocs; + this.rolloverMaxPrimaryShardDocs = rolloverMaxPrimaryShardDocs; this.rolloverMaxPrimaryShardSize = rolloverMaxPrimaryShardSize; this.rolloverMaxSize = rolloverMaxSize; this.setPriorityPriority = setPriorityPriority; @@ -359,6 +369,11 @@ public ActionConfigStats(StreamInput in) throws IOException { this.setPriorityPriority = in.readOptionalVInt(); this.shrinkMaxPrimaryShardSize = in.readOptionalWriteable(ByteSizeValue::new); this.shrinkNumberOfShards = in.readOptionalVInt(); + if (in.getVersion().onOrAfter(Version.V_8_2_0)) { + this.rolloverMaxPrimaryShardDocs = in.readOptionalVLong(); + } else { + this.rolloverMaxPrimaryShardDocs = null; + } } @Override @@ -372,6 +387,9 @@ public void writeTo(StreamOutput out) throws IOException { out.writeOptionalVInt(setPriorityPriority); out.writeOptionalWriteable(shrinkMaxPrimaryShardSize); out.writeOptionalVInt(shrinkNumberOfShards); + if (out.getVersion().onOrAfter(Version.V_8_2_0)) { + out.writeOptionalVLong(rolloverMaxPrimaryShardDocs); + } } @Override @@ -387,7 +405,11 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.field(ForceMergeAction.MAX_NUM_SEGMENTS_FIELD.getPreferredName(), forceMergeMaxNumberOfSegments); builder.endObject(); } - if (rolloverMaxAge != null || rolloverMaxDocs != null || rolloverMaxSize != null || rolloverMaxPrimaryShardSize != null) { + if (rolloverMaxAge != null + || rolloverMaxDocs != null + || rolloverMaxPrimaryShardDocs != null + || rolloverMaxSize != null + || rolloverMaxPrimaryShardSize != null) { builder.startObject(RolloverAction.NAME); if (rolloverMaxAge != null) { builder.field(RolloverAction.MAX_AGE_FIELD.getPreferredName(), rolloverMaxAge.getStringRep()); @@ -396,6 +418,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws if (rolloverMaxDocs != null) { builder.field(RolloverAction.MAX_DOCS_FIELD.getPreferredName(), rolloverMaxDocs); } + if (rolloverMaxPrimaryShardDocs != null) { + builder.field(RolloverAction.MAX_PRIMARY_SHARD_DOCS_FIELD.getPreferredName(), rolloverMaxPrimaryShardDocs); + } if (rolloverMaxSize != null) { builder.field(RolloverAction.MAX_SIZE_FIELD.getPreferredName(), rolloverMaxSize.getStringRep()); builder.field(RolloverAction.MAX_SIZE_FIELD.getPreferredName() + "_bytes", rolloverMaxSize.getBytes()); @@ -448,6 +473,10 @@ public Long getRolloverMaxDocs() { return rolloverMaxDocs; } + public Long getRolloverMaxPrimaryShardDocs() { + return rolloverMaxPrimaryShardDocs; + } + public ByteSizeValue getRolloverMaxPrimaryShardSize() { return rolloverMaxPrimaryShardSize; } 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 f4dda7e453771..52a2c239a4fe2 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 @@ -6,6 +6,7 @@ */ package org.elasticsearch.xpack.core.ilm; +import org.elasticsearch.Version; import org.elasticsearch.client.internal.Client; import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.stream.StreamInput; @@ -37,6 +38,7 @@ public class RolloverAction implements LifecycleAction { public static final ParseField MAX_PRIMARY_SHARD_SIZE_FIELD = new ParseField("max_primary_shard_size"); public static final ParseField MAX_DOCS_FIELD = new ParseField("max_docs"); public static final ParseField MAX_AGE_FIELD = new ParseField("max_age"); + public static final ParseField MAX_PRIMARY_SHARD_DOCS_FIELD = new ParseField("max_primary_shard_docs"); public static final String LIFECYCLE_ROLLOVER_ALIAS = "index.lifecycle.rollover_alias"; public static final Setting LIFECYCLE_ROLLOVER_ALIAS_SETTING = Setting.simpleString( LIFECYCLE_ROLLOVER_ALIAS, @@ -48,7 +50,7 @@ public class RolloverAction implements LifecycleAction { private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( NAME, - a -> new RolloverAction((ByteSizeValue) a[0], (ByteSizeValue) a[1], (TimeValue) a[2], (Long) a[3]) + a -> new RolloverAction((ByteSizeValue) a[0], (ByteSizeValue) a[1], (TimeValue) a[2], (Long) a[3], (Long) a[4]) ); static { @@ -71,12 +73,14 @@ public class RolloverAction implements LifecycleAction { ValueType.VALUE ); PARSER.declareLong(ConstructingObjectParser.optionalConstructorArg(), MAX_DOCS_FIELD); + PARSER.declareLong(ConstructingObjectParser.optionalConstructorArg(), MAX_PRIMARY_SHARD_DOCS_FIELD); } private final ByteSizeValue maxSize; private final ByteSizeValue maxPrimaryShardSize; private final Long maxDocs; private final TimeValue maxAge; + private final Long maxPrimaryShardDocs; public static RolloverAction parse(XContentParser parser) { return PARSER.apply(parser, null); @@ -86,15 +90,17 @@ public RolloverAction( @Nullable ByteSizeValue maxSize, @Nullable ByteSizeValue maxPrimaryShardSize, @Nullable TimeValue maxAge, - @Nullable Long maxDocs + @Nullable Long maxDocs, + @Nullable Long maxPrimaryShardDocs ) { - if (maxSize == null && maxPrimaryShardSize == null && maxAge == null && maxDocs == null) { + if (maxSize == null && maxPrimaryShardSize == null && maxAge == null && maxDocs == null && maxPrimaryShardDocs == null) { throw new IllegalArgumentException("At least one rollover condition must be set."); } this.maxSize = maxSize; this.maxPrimaryShardSize = maxPrimaryShardSize; this.maxAge = maxAge; this.maxDocs = maxDocs; + this.maxPrimaryShardDocs = maxPrimaryShardDocs; } public RolloverAction(StreamInput in) throws IOException { @@ -110,6 +116,11 @@ public RolloverAction(StreamInput in) throws IOException { } maxAge = in.readOptionalTimeValue(); maxDocs = in.readOptionalVLong(); + if (in.getVersion().onOrAfter(Version.V_8_2_0)) { + maxPrimaryShardDocs = in.readOptionalVLong(); + } else { + maxPrimaryShardDocs = null; + } } @Override @@ -126,6 +137,9 @@ public void writeTo(StreamOutput out) throws IOException { } out.writeOptionalTimeValue(maxAge); out.writeOptionalVLong(maxDocs); + if (out.getVersion().onOrAfter(Version.V_8_2_0)) { + out.writeOptionalVLong(maxPrimaryShardDocs); + } } @Override @@ -149,6 +163,10 @@ public Long getMaxDocs() { return maxDocs; } + public Long getMaxPrimaryShardDocs() { + return maxPrimaryShardDocs; + } + @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); @@ -164,6 +182,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws if (maxDocs != null) { builder.field(MAX_DOCS_FIELD.getPreferredName(), maxDocs); } + if (maxPrimaryShardDocs != null) { + builder.field(MAX_PRIMARY_SHARD_DOCS_FIELD.getPreferredName(), maxPrimaryShardDocs); + } builder.endObject(); return builder; } @@ -188,7 +209,8 @@ public List toSteps(Client client, String phase, Step.StepKey nextStepKey) maxSize, maxPrimaryShardSize, maxAge, - maxDocs + maxDocs, + maxPrimaryShardDocs ); RolloverStep rolloverStep = new RolloverStep(rolloverStepKey, waitForActiveShardsKey, client); WaitForActiveShardsStep waitForActiveShardsStep = new WaitForActiveShardsStep(waitForActiveShardsKey, updateDateStepKey); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStep.java index cfd8c7a23475b..1a1257746c819 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStep.java @@ -38,6 +38,7 @@ public class WaitForRolloverReadyStep extends AsyncWaitStep { private final ByteSizeValue maxPrimaryShardSize; private final TimeValue maxAge; private final Long maxDocs; + private final Long maxPrimaryShardDocs; public WaitForRolloverReadyStep( StepKey key, @@ -46,13 +47,15 @@ public WaitForRolloverReadyStep( ByteSizeValue maxSize, ByteSizeValue maxPrimaryShardSize, TimeValue maxAge, - Long maxDocs + Long maxDocs, + Long maxPrimaryShardDocs ) { super(key, nextStepKey, client); this.maxSize = maxSize; this.maxPrimaryShardSize = maxPrimaryShardSize; this.maxAge = maxAge; this.maxDocs = maxDocs; + this.maxPrimaryShardDocs = maxPrimaryShardDocs; } @Override @@ -192,6 +195,9 @@ public void evaluateCondition(Metadata metadata, Index index, Listener listener, if (maxDocs != null) { rolloverRequest.addMaxIndexDocsCondition(maxDocs); } + if (maxPrimaryShardDocs != null) { + rolloverRequest.addMaxPrimaryShardDocsCondition(maxPrimaryShardDocs); + } getClient().admin() .indices() .rolloverIndex( @@ -219,9 +225,13 @@ Long getMaxDocs() { return maxDocs; } + public Long getMaxPrimaryShardDocs() { + return maxPrimaryShardDocs; + } + @Override public int hashCode() { - return Objects.hash(super.hashCode(), maxSize, maxPrimaryShardSize, maxAge, maxDocs); + return Objects.hash(super.hashCode(), maxSize, maxPrimaryShardSize, maxAge, maxDocs, maxPrimaryShardDocs); } @Override @@ -237,7 +247,8 @@ public boolean equals(Object obj) { && Objects.equals(maxSize, other.maxSize) && Objects.equals(maxPrimaryShardSize, other.maxPrimaryShardSize) && Objects.equals(maxAge, other.maxAge) - && Objects.equals(maxDocs, other.maxDocs); + && Objects.equals(maxDocs, other.maxDocs) + && Objects.equals(maxPrimaryShardDocs, other.maxPrimaryShardDocs); } // We currently have no information to provide for this AsyncWaitStep, so this is an empty object diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ActionConfigStatsTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ActionConfigStatsTests.java index e59f01e93a1cc..ad1e141f394f1 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ActionConfigStatsTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ActionConfigStatsTests.java @@ -37,6 +37,9 @@ public static ActionConfigStats createRandomInstance() { if (randomBoolean()) { builder.setRolloverMaxDocs(randomLongBetween(0, Long.MAX_VALUE)); } + if (randomBoolean()) { + builder.setRolloverMaxPrimaryShardDocs(randomLongBetween(0, Long.MAX_VALUE)); + } if (randomBoolean()) { ByteSizeValue randomByteSize = ByteSizeValue.ofBytes(randomLongBetween(0, 1024L * 1024L * 1024L * 50L)); builder.setRolloverMaxPrimaryShardSize(randomByteSize); @@ -99,6 +102,7 @@ protected ActionConfigStats mutateInstance(ActionConfigStats instance) throws IO case 8 -> builder.setShrinkNumberOfShards( randomValueOtherThan(instance.getShrinkNumberOfShards(), () -> randomIntBetween(0, 50)) ); + case 9 -> builder.setRolloverMaxPrimaryShardDocs(randomLongBetween(0, Long.MAX_VALUE)); default -> throw new IllegalStateException("Illegal randomization branch"); } return builder.build(); diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/PhaseCacheManagementTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/PhaseCacheManagementTests.java index 6b3752ee72246..bc6e248930e5a 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/PhaseCacheManagementTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/PhaseCacheManagementTests.java @@ -82,7 +82,7 @@ public void testRefreshPhaseJson() throws IOException { String indexName = meta.getIndex().getName(); Map actions = new HashMap<>(); - actions.put("rollover", new RolloverAction(null, null, null, 1L)); + actions.put("rollover", new RolloverAction(null, null, null, 1L, null)); actions.put("set_priority", new SetPriorityAction(100)); Phase hotPhase = new Phase("hot", TimeValue.ZERO, actions); Map phases = Collections.singletonMap("hot", hotPhase); @@ -317,7 +317,7 @@ public void testIndexCanBeSafelyUpdated() { IndexMetadata meta = mkMeta().putCustom(ILM_CUSTOM_METADATA_KEY, exState.asMap()).build(); Map actions = new HashMap<>(); - actions.put("rollover", new RolloverAction(null, null, null, 1L)); + actions.put("rollover", new RolloverAction(null, null, null, 1L, null)); actions.put("set_priority", new SetPriorityAction(100)); Phase hotPhase = new Phase("hot", TimeValue.ZERO, actions); Map phases = Collections.singletonMap("hot", hotPhase); @@ -390,7 +390,7 @@ public void testIndexCanBeSafelyUpdated() { IndexMetadata meta = mkMeta().putCustom(ILM_CUSTOM_METADATA_KEY, exState.asMap()).build(); Map actions = new HashMap<>(); - actions.put("rollover", new RolloverAction(null, null, TimeValue.timeValueSeconds(5), null)); + actions.put("rollover", new RolloverAction(null, null, TimeValue.timeValueSeconds(5), null, null)); Phase hotPhase = new Phase("hot", TimeValue.ZERO, actions); Map phases = Collections.singletonMap("hot", hotPhase); LifecyclePolicy newPolicy = new LifecyclePolicy("my-policy", phases); @@ -421,7 +421,7 @@ public void testIndexCanBeSafelyUpdated() { IndexMetadata meta = mkMeta().putCustom(ILM_CUSTOM_METADATA_KEY, exState.asMap()).build(); Map actions = new HashMap<>(); - actions.put("rollover", new RolloverAction(null, null, null, 1L)); + actions.put("rollover", new RolloverAction(null, null, null, 1L, null)); actions.put("set_priority", new SetPriorityAction(100)); Phase hotPhase = new Phase("hot", TimeValue.ZERO, actions); Map phases = Collections.singletonMap("hot", hotPhase); @@ -442,7 +442,7 @@ public void testIndexCanBeSafelyUpdated() { IndexMetadata meta = mkMeta().putCustom(ILM_CUSTOM_METADATA_KEY, exState.asMap()).build(); Map actions = new HashMap<>(); - actions.put("rollover", new RolloverAction(null, null, null, 1L)); + actions.put("rollover", new RolloverAction(null, null, null, 1L, null)); actions.put("set_priority", new SetPriorityAction(100)); Phase hotPhase = new Phase("hot", TimeValue.ZERO, actions); Map phases = Collections.singletonMap("hot", hotPhase); @@ -481,14 +481,14 @@ public void testUpdateIndicesForPolicy() throws IOException { assertTrue(eligibleToCheckForRefresh(meta)); Map oldActions = new HashMap<>(); - oldActions.put("rollover", new RolloverAction(null, null, null, 1L)); + oldActions.put("rollover", new RolloverAction(null, null, null, 1L, null)); oldActions.put("set_priority", new SetPriorityAction(100)); Phase oldHotPhase = new Phase("hot", TimeValue.ZERO, oldActions); Map oldPhases = Collections.singletonMap("hot", oldHotPhase); LifecyclePolicy oldPolicy = new LifecyclePolicy("my-policy", oldPhases); Map actions = new HashMap<>(); - actions.put("rollover", new RolloverAction(null, null, null, 1L)); + actions.put("rollover", new RolloverAction(null, null, null, 1L, null)); actions.put("set_priority", new SetPriorityAction(100)); Phase hotPhase = new Phase("hot", TimeValue.ZERO, actions); Map phases = Collections.singletonMap("hot", hotPhase); @@ -508,7 +508,7 @@ public void testUpdateIndicesForPolicy() throws IOException { assertThat(updatedState, equalTo(existingState)); actions = new HashMap<>(); - actions.put("rollover", new RolloverAction(null, null, null, 2L)); + actions.put("rollover", new RolloverAction(null, null, null, 2L, null)); actions.put("set_priority", new SetPriorityAction(150)); hotPhase = new Phase("hot", TimeValue.ZERO, actions); phases = Collections.singletonMap("hot", hotPhase); 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 e063b14c9b366..8a4ba79b21cb9 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 @@ -39,7 +43,10 @@ public static RolloverAction randomInstance() { TimeValue maxAge = (maxDocs == null && maxSize == null || randomBoolean()) ? TimeValue.parseTimeValue(randomPositiveTimeValue(), "rollover_action_test") : null; - return new RolloverAction(maxSize, maxPrimaryShardSize, maxAge, maxDocs); + Long maxPrimaryShardDocs = (maxSize == null && maxPrimaryShardSize == null && maxAge == null && maxDocs == null || randomBoolean()) + ? randomNonNegativeLong() + : null; + return new RolloverAction(maxSize, maxPrimaryShardSize, maxAge, maxDocs, maxPrimaryShardDocs); } @Override @@ -53,6 +60,7 @@ protected RolloverAction mutateInstance(RolloverAction instance) throws IOExcept ByteSizeValue maxPrimaryShardSize = instance.getMaxPrimaryShardSize(); TimeValue maxAge = instance.getMaxAge(); Long maxDocs = instance.getMaxDocs(); + Long maxPrimaryShardDocs = instance.getMaxPrimaryShardDocs(); switch (between(0, 3)) { case 0 -> maxSize = randomValueOtherThan(maxSize, () -> { ByteSizeUnit maxSizeUnit = randomFrom(ByteSizeUnit.values()); @@ -67,13 +75,17 @@ protected RolloverAction mutateInstance(RolloverAction instance) throws IOExcept () -> TimeValue.parseTimeValue(randomPositiveTimeValue(), "rollover_action_test") ); case 3 -> maxDocs = maxDocs == null ? randomNonNegativeLong() : maxDocs + 1; + case 4 -> maxPrimaryShardDocs = maxPrimaryShardDocs == null ? randomNonNegativeLong() : maxPrimaryShardDocs + 1; default -> throw new AssertionError("Illegal randomisation branch"); } - return new RolloverAction(maxSize, maxPrimaryShardSize, maxAge, maxDocs); + return new RolloverAction(maxSize, maxPrimaryShardSize, maxAge, maxDocs, maxPrimaryShardDocs); } public void testNoConditions() { - IllegalArgumentException exception = expectThrows(IllegalArgumentException.class, () -> new RolloverAction(null, null, null, null)); + IllegalArgumentException exception = expectThrows( + IllegalArgumentException.class, + () -> new RolloverAction(null, null, null, null, null) + ); assertEquals("At least one rollover condition must be set.", exception.getMessage()); } @@ -111,6 +123,20 @@ public void testToSteps() { assertEquals(action.getMaxPrimaryShardSize(), firstStep.getMaxPrimaryShardSize()); assertEquals(action.getMaxAge(), firstStep.getMaxAge()); assertEquals(action.getMaxDocs(), firstStep.getMaxDocs()); + assertEquals(action.getMaxPrimaryShardDocs(), firstStep.getMaxPrimaryShardDocs()); assertEquals(nextStepKey, fifthStep.getNextStepKey()); } + + public void testBwcSerializationWithMaxPrimaryShardDocs() throws Exception { + // In case of serializing to node with older version, replace maxPrimaryShardDocs with maxDocs. + RolloverAction instance = new RolloverAction(null, null, null, null, 1L); + RolloverAction deserializedInstance = copyInstance(instance, Version.V_8_1_0); + assertThat(deserializedInstance.getMaxPrimaryShardDocs(), nullValue()); + + // But not if maxSize is also specified: + instance = new RolloverAction(null, null, null, 2L, 1L); + deserializedInstance = copyInstance(instance, Version.V_8_1_0); + assertThat(deserializedInstance.getMaxPrimaryShardDocs(), nullValue()); + assertThat(deserializedInstance.getMaxDocs(), equalTo(instance.getMaxDocs())); + } } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleTypeTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleTypeTests.java index 543e9d6daebcf..3f76916f83f04 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleTypeTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleTypeTests.java @@ -66,7 +66,7 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase { private static final WaitForSnapshotAction TEST_WAIT_FOR_SNAPSHOT_ACTION = new WaitForSnapshotAction("policy"); private static final ForceMergeAction TEST_FORCE_MERGE_ACTION = new ForceMergeAction(1, null); - private static final RolloverAction TEST_ROLLOVER_ACTION = new RolloverAction(new ByteSizeValue(1), null, null, null); + private static final RolloverAction TEST_ROLLOVER_ACTION = new RolloverAction(new ByteSizeValue(1), null, null, null, null); private static final ShrinkAction TEST_SHRINK_ACTION = new ShrinkAction(1, null); private static final ReadOnlyAction TEST_READ_ONLY_ACTION = new ReadOnlyAction(); private static final SetPriorityAction TEST_PRIORITY_ACTION = new SetPriorityAction(0); @@ -325,7 +325,7 @@ public void testValidateActionsFollowingSearchableSnapshot() { TimeValue.ZERO, Map.of( RolloverAction.NAME, - new RolloverAction(null, null, null, 1L), + new RolloverAction(null, null, null, 1L, null), SearchableSnapshotAction.NAME, new SearchableSnapshotAction(randomAlphaOfLengthBetween(4, 10)) ) @@ -1100,6 +1100,7 @@ private ConcurrentMap convertActionNamesToActions(Strin ByteSizeValue.parseBytesSizeValue("0b", "test"), ByteSizeValue.parseBytesSizeValue("0b", "test"), TimeValue.ZERO, + 1L, 1L ); case ShrinkAction.NAME -> new ShrinkAction(1, null); diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStepTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStepTests.java index 4373c106f8d1d..491fcf46d8af9 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStepTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStepTests.java @@ -13,6 +13,7 @@ import org.elasticsearch.action.admin.indices.rollover.Condition; import org.elasticsearch.action.admin.indices.rollover.MaxAgeCondition; import org.elasticsearch.action.admin.indices.rollover.MaxDocsCondition; +import org.elasticsearch.action.admin.indices.rollover.MaxPrimaryShardDocsCondition; import org.elasticsearch.action.admin.indices.rollover.MaxPrimaryShardSizeCondition; import org.elasticsearch.action.admin.indices.rollover.MaxSizeCondition; import org.elasticsearch.action.admin.indices.rollover.RolloverInfo; @@ -60,7 +61,17 @@ protected WaitForRolloverReadyStep createRandomInstance() { TimeValue maxAge = (maxDocs == null && maxSize == null || randomBoolean()) ? TimeValue.parseTimeValue(randomPositiveTimeValue(), "rollover_action_test") : null; - return new WaitForRolloverReadyStep(stepKey, nextStepKey, client, maxSize, maxPrimaryShardSize, maxAge, maxDocs); + Long maxPrimaryShardDocs = randomBoolean() ? null : randomNonNegativeLong(); + return new WaitForRolloverReadyStep( + stepKey, + nextStepKey, + client, + maxSize, + maxPrimaryShardSize, + maxAge, + maxDocs, + maxPrimaryShardDocs + ); } @Override @@ -71,6 +82,7 @@ protected WaitForRolloverReadyStep mutateInstance(WaitForRolloverReadyStep insta ByteSizeValue maxPrimaryShardSize = instance.getMaxPrimaryShardSize(); TimeValue maxAge = instance.getMaxAge(); Long maxDocs = instance.getMaxDocs(); + Long maxPrimaryShardDocs = instance.getMaxPrimaryShardDocs(); switch (between(0, 5)) { case 0 -> key = new Step.StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5)); @@ -88,9 +100,19 @@ protected WaitForRolloverReadyStep mutateInstance(WaitForRolloverReadyStep insta () -> TimeValue.parseTimeValue(randomPositiveTimeValue(), "rollover_action_test") ); case 5 -> maxDocs = randomValueOtherThan(maxDocs, () -> randomNonNegativeLong()); + case 6 -> maxPrimaryShardDocs = randomValueOtherThan(maxPrimaryShardDocs, () -> randomNonNegativeLong()); default -> throw new AssertionError("Illegal randomisation branch"); } - return new WaitForRolloverReadyStep(key, nextKey, instance.getClient(), maxSize, maxPrimaryShardSize, maxAge, maxDocs); + return new WaitForRolloverReadyStep( + key, + nextKey, + instance.getClient(), + maxSize, + maxPrimaryShardSize, + maxAge, + maxDocs, + maxPrimaryShardDocs + ); } @Override @@ -102,7 +124,8 @@ protected WaitForRolloverReadyStep copyInstance(WaitForRolloverReadyStep instanc instance.getMaxSize(), instance.getMaxPrimaryShardSize(), instance.getMaxAge(), - instance.getMaxDocs() + instance.getMaxDocs(), + instance.getMaxPrimaryShardDocs() ); } @@ -254,6 +277,9 @@ private void mockRolloverIndexCall(String rolloverTarget, WaitForRolloverReadySt if (step.getMaxDocs() != null) { expectedConditions.add(new MaxDocsCondition(step.getMaxDocs())); } + if (step.getMaxPrimaryShardDocs() != null) { + expectedConditions.add(new MaxPrimaryShardDocsCondition(step.getMaxPrimaryShardDocs())); + } assertRolloverIndexRequest(request, rolloverTarget, expectedConditions); Map conditionResults = expectedConditions.stream() .collect(Collectors.toMap(Condition::toString, condition -> true)); @@ -456,6 +482,9 @@ public void testPerformActionNotComplete() { if (step.getMaxDocs() != null) { expectedConditions.add(new MaxDocsCondition(step.getMaxDocs())); } + if (step.getMaxPrimaryShardDocs() != null) { + expectedConditions.add(new MaxPrimaryShardDocsCondition(step.getMaxPrimaryShardDocs())); + } assertRolloverIndexRequest(request, alias, expectedConditions); Map conditionResults = expectedConditions.stream() .collect(Collectors.toMap(Condition::toString, condition -> false)); @@ -512,6 +541,9 @@ public void testPerformActionFailure() { if (step.getMaxDocs() != null) { expectedConditions.add(new MaxDocsCondition(step.getMaxDocs())); } + if (step.getMaxPrimaryShardDocs() != null) { + expectedConditions.add(new MaxPrimaryShardDocsCondition(step.getMaxPrimaryShardDocs())); + } assertRolloverIndexRequest(request, alias, expectedConditions); listener.onFailure(exception); return null; diff --git a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/MigrateToDataTiersIT.java b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/MigrateToDataTiersIT.java index 829c9153501dd..f0488da081386 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/MigrateToDataTiersIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/MigrateToDataTiersIT.java @@ -140,7 +140,7 @@ public void testMigrateToDataTiersAction() throws Exception { // let's also have a policy that doesn't need migrating String rolloverOnlyPolicyName = "rollover-policy"; - createNewSingletonPolicy(client(), rolloverOnlyPolicyName, "hot", new RolloverAction(null, null, null, 1L)); + createNewSingletonPolicy(client(), rolloverOnlyPolicyName, "hot", new RolloverAction(null, null, null, 1L, null)); String rolloverIndexPrefix = "rolloverpolicytest_index"; for (int i = 1; i <= 2; i++) { diff --git a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/TimeSeriesRestDriver.java b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/TimeSeriesRestDriver.java index 2486b4e4cd50d..48f21f23ccecb 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/TimeSeriesRestDriver.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/TimeSeriesRestDriver.java @@ -174,7 +174,7 @@ public static void rolloverMaxOneDocCondition(RestClient client, String indexAbs public static void createFullPolicy(RestClient client, String policyName, TimeValue hotTime) throws IOException { Map hotActions = new HashMap<>(); hotActions.put(SetPriorityAction.NAME, new SetPriorityAction(100)); - hotActions.put(RolloverAction.NAME, new RolloverAction(null, null, null, 1L)); + hotActions.put(RolloverAction.NAME, new RolloverAction(null, null, null, 1L, null)); Map warmActions = new HashMap<>(); warmActions.put(SetPriorityAction.NAME, new SetPriorityAction(50)); warmActions.put(ForceMergeAction.NAME, new ForceMergeAction(1, null)); diff --git a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/ChangePolicyForIndexIT.java b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/ChangePolicyForIndexIT.java index 437de0de2c697..d23999449f9bf 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/ChangePolicyForIndexIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/ChangePolicyForIndexIT.java @@ -62,7 +62,10 @@ public void testChangePolicyForIndex() throws Exception { String indexName = "test-000001"; // create policy_1 and policy_2 Map phases1 = new HashMap<>(); - phases1.put("hot", new Phase("hot", TimeValue.ZERO, singletonMap(RolloverAction.NAME, new RolloverAction(null, null, null, 1L)))); + phases1.put( + "hot", + new Phase("hot", TimeValue.ZERO, singletonMap(RolloverAction.NAME, new RolloverAction(null, null, null, 1L, null))) + ); phases1.put( "warm", new Phase( @@ -75,7 +78,7 @@ public void testChangePolicyForIndex() throws Exception { Map phases2 = new HashMap<>(); phases2.put( "hot", - new Phase("hot", TimeValue.ZERO, singletonMap(RolloverAction.NAME, new RolloverAction(null, null, null, 1000L))) + new Phase("hot", TimeValue.ZERO, singletonMap(RolloverAction.NAME, new RolloverAction(null, null, null, 1000L, null))) ); phases2.put( "warm", @@ -167,7 +170,7 @@ public void testILMHonoursTheCachedPhaseAfterPolicyUpdate() throws Exception { String indexName = "test-000001"; String policyName = "rolloverPolicy"; String alias = "thealias"; - createNewSingletonPolicy(client(), policyName, "hot", new RolloverAction(null, null, null, 1L)); + createNewSingletonPolicy(client(), policyName, "hot", new RolloverAction(null, null, null, 1L, null)); createIndexWithSettings( client(), diff --git a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesDataStreamsIT.java b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesDataStreamsIT.java index bba2cca77f75d..1f380f7ab9031 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesDataStreamsIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesDataStreamsIT.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.ilm; +import org.apache.lucene.util.LuceneTestCase.AwaitsFix; import org.elasticsearch.client.Request; import org.elasticsearch.client.Response; import org.elasticsearch.cluster.metadata.DataStream; @@ -70,7 +71,7 @@ public void refreshAbstractions() { } public void testRolloverAction() throws Exception { - createNewSingletonPolicy(client(), policyName, "hot", new RolloverAction(null, null, null, 1L)); + createNewSingletonPolicy(client(), policyName, "hot", new RolloverAction(null, null, null, 1L, null)); createComposableTemplate(client(), template, dataStream + "*", getTemplate(policyName)); @@ -93,7 +94,7 @@ public void testRolloverAction() throws Exception { } public void testRolloverIsSkippedOnManualDataStreamRollover() throws Exception { - createNewSingletonPolicy(client(), policyName, "hot", new RolloverAction(null, null, null, 2L)); + createNewSingletonPolicy(client(), policyName, "hot", new RolloverAction(null, null, null, 2L, null)); createComposableTemplate(client(), template, dataStream + "*", getTemplate(policyName)); diff --git a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java index 8c4a6d5e32692..87c633ea0f060 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java @@ -177,7 +177,7 @@ public void testUpdatePolicyToNotContainFailedStep() throws Exception { assertTrue(indexExists(index)); // updating the policy to not contain the delete phase at all - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L)); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L, null)); // ILM must honour the cached delete phase and eventually delete the index Request request = new Request("PUT", index + "/_settings"); @@ -568,7 +568,7 @@ public void testNonexistentPolicy() throws Exception { client().performRequest(templateRequest); policy = randomAlphaOfLengthBetween(5, 20); - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L)); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L, null)); index = indexPrefix + "-000001"; final StringEntity putIndex = new StringEntity(""" @@ -692,7 +692,7 @@ public void testRemoveAndReaddPolicy() throws Exception { String originalIndex = index + "-000001"; String secondIndex = index + "-000002"; // Set up a policy with rollover - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L)); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L, null)); createIndexWithSettings( client(), originalIndex, @@ -774,7 +774,7 @@ public void testWaitForActiveShardsStep() throws Exception { ); // create policy - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L)); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L, null)); // update policy on index updatePolicy(client(), originalIndex, policy); Request createIndexTemplate = new Request("PUT", "_template/rolling_indexes"); @@ -802,7 +802,7 @@ public void testWaitForActiveShardsStep() throws Exception { } public void testHistoryIsWrittenWithSuccess() throws Exception { - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L)); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L, null)); Request createIndexTemplate = new Request("PUT", "_template/rolling_indexes"); createIndexTemplate.setJsonEntity(""" { @@ -836,7 +836,7 @@ public void testHistoryIsWrittenWithSuccess() throws Exception { public void testHistoryIsWrittenWithFailure() throws Exception { createIndexWithSettings(client(), index + "-1", alias, Settings.builder(), false); - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L)); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L, null)); updatePolicy(client(), index + "-1", policy); // Index a document @@ -911,7 +911,7 @@ public void testRetryableInitializationStep() throws Exception { public void testRefreshablePhaseJson() throws Exception { String index = "refresh-index"; - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 100L)); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 100L, null)); Request createIndexTemplate = new Request("PUT", "_template/rolling_indexes"); createIndexTemplate.setJsonEntity(""" { @@ -941,7 +941,7 @@ public void testRefreshablePhaseJson() throws Exception { assertBusy(() -> assertThat(getStepKeyForIndex(client(), index + "-1").getName(), equalTo(WaitForRolloverReadyStep.NAME))); // Update the policy to allow rollover at 1 document instead of 100 - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L)); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L, null)); // Index should now have been able to roll over, creating the new index and proceeding to the "complete" step assertBusy(() -> assertThat(indexExists(index + "-000002"), is(true))); diff --git a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeseriesMoveToStepIT.java b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeseriesMoveToStepIT.java index a1382af072bf0..c4f6e86e20421 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeseriesMoveToStepIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeseriesMoveToStepIT.java @@ -189,7 +189,7 @@ public void testMoveToStepRereadsPolicy() throws Exception { client(), policy, "hot", - new RolloverAction(null, null, TimeValue.timeValueHours(1), null), + new RolloverAction(null, null, TimeValue.timeValueHours(1), null, null), TimeValue.ZERO ); @@ -211,7 +211,7 @@ public void testMoveToStepRereadsPolicy() throws Exception { TimeUnit.SECONDS ); - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L), TimeValue.ZERO); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L, null), TimeValue.ZERO); // Move to the same step, which should re-read the policy Request moveToStepRequest = new Request("POST", "_ilm/move/test-1"); diff --git a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/ReadonlyActionIT.java b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/ReadonlyActionIT.java index 180c40ae6d467..b2a39f2a2e1df 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/ReadonlyActionIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/ReadonlyActionIT.java @@ -73,7 +73,7 @@ public void testReadOnlyInTheHotPhase() throws Exception { // add a policy Map hotActions = Map.of( RolloverAction.NAME, - new RolloverAction(null, null, null, 1L), + new RolloverAction(null, null, null, 1L, null), ReadOnlyAction.NAME, new ReadOnlyAction() ); diff --git a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/RolloverActionIT.java b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/RolloverActionIT.java index 6edacb78accac..eab4b442868e0 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/RolloverActionIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/RolloverActionIT.java @@ -67,7 +67,7 @@ public void testRolloverAction() throws Exception { ); // create policy - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L)); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L, null)); // update policy on index updatePolicy(client(), originalIndex, policy); // index document {"foo": "bar"} to trigger rollover @@ -118,7 +118,7 @@ public void testRolloverActionWithIndexingComplete() throws Exception { client().performRequest(updateAliasRequest); // create policy - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L)); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L, null)); // update policy on index updatePolicy(client(), originalIndex, policy); // index document {"foo": "bar"} to trigger rollover @@ -148,7 +148,35 @@ public void testRolloverActionWithMaxPrimaryShardSize() throws Exception { index(client(), originalIndex, "_id", "foo", "bar"); // create policy - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, ByteSizeValue.ofBytes(1), null, null)); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, ByteSizeValue.ofBytes(1), null, null, null)); + // update policy on index + updatePolicy(client(), originalIndex, policy); + + assertBusy(() -> { + assertThat(getStepKeyForIndex(client(), originalIndex), equalTo(PhaseCompleteStep.finalStep("hot").getKey())); + assertTrue(indexExists(secondIndex)); + assertTrue(indexExists(originalIndex)); + assertEquals("true", getOnlyIndexSettings(client(), originalIndex).get(LifecycleSettings.LIFECYCLE_INDEXING_COMPLETE)); + }, 30, TimeUnit.SECONDS); + } + + public void testRolloverActionWithMaxPrimaryDocsSize() throws Exception { + String originalIndex = index + "-000001"; + String secondIndex = index + "-000002"; + createIndexWithSettings( + client(), + originalIndex, + alias, + Settings.builder() + .put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 3) + .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0) + .put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias) + ); + + index(client(), originalIndex, "_id", "foo", "bar"); + + // create policy + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, null, 1L)); // update policy on index updatePolicy(client(), originalIndex, policy); @@ -163,7 +191,7 @@ public void testRolloverActionWithMaxPrimaryShardSize() throws Exception { public void testILMRolloverRetriesOnReadOnlyBlock() throws Exception { String firstIndex = index + "-000001"; - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, TimeValue.timeValueSeconds(1), null)); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, TimeValue.timeValueSeconds(1), null, null)); // create the index as readonly and associate the ILM policy to it createIndexWithSettings( @@ -203,7 +231,7 @@ public void testILMRolloverOnManuallyRolledIndex() throws Exception { String thirdIndex = index + "-000003"; // Set up a policy with rollover - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 2L)); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 2L, null)); Request createIndexTemplate = new Request("PUT", "_template/rolling_indexes"); createIndexTemplate.setJsonEntity(""" { @@ -261,7 +289,7 @@ public void testRolloverStepRetriesUntilRolledOverIndexIsDeleted() throws Except String index = this.index + "-000001"; String rolledIndex = this.index + "-000002"; - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, TimeValue.timeValueSeconds(1), null)); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, TimeValue.timeValueSeconds(1), null, null)); // create the rolled index so the rollover of the first index fails createIndexWithSettings( @@ -343,7 +371,7 @@ public void testRolloverStepRetriesUntilRolledOverIndexIsDeleted() throws Except public void testUpdateRolloverLifecycleDateStepRetriesWhenRolloverInfoIsMissing() throws Exception { String index = this.index + "-000001"; - createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L)); + createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, null, null, 1L, null)); createIndexWithSettings( client(), diff --git a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/SearchableSnapshotActionIT.java b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/SearchableSnapshotActionIT.java index 5662f992cef80..b17b096d289d7 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/SearchableSnapshotActionIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/SearchableSnapshotActionIT.java @@ -244,7 +244,7 @@ public void testCreateInvalidPolicy() { TimeValue.ZERO, Map.of( RolloverAction.NAME, - new RolloverAction(null, null, null, 1L), + new RolloverAction(null, null, null, 1L, null), SearchableSnapshotAction.NAME, new SearchableSnapshotAction(randomAlphaOfLengthBetween(4, 10)) ) @@ -275,7 +275,7 @@ public void testUpdatePolicyToAddPhasesYieldsInvalidActionsToBeSkipped() throws TimeValue.ZERO, Map.of( RolloverAction.NAME, - new RolloverAction(null, null, null, 1L), + new RolloverAction(null, null, null, 1L, null), SearchableSnapshotAction.NAME, new SearchableSnapshotAction(snapshotRepo) ) @@ -354,7 +354,7 @@ public void testRestoredIndexManagedByLocalPolicySkipsIllegalActions() throws Ex TimeValue.ZERO, Map.of( RolloverAction.NAME, - new RolloverAction(null, null, null, 1L), + new RolloverAction(null, null, null, 1L, null), SearchableSnapshotAction.NAME, new SearchableSnapshotAction(snapshotRepo) ) @@ -446,7 +446,7 @@ public void testIdenticalSearchableSnapshotActionIsNoop() throws Exception { String index = "myindex-" + randomAlphaOfLength(4).toLowerCase(Locale.ROOT) + "-000001"; createSnapshotRepo(client(), snapshotRepo, randomBoolean()); Map hotActions = new HashMap<>(); - hotActions.put(RolloverAction.NAME, new RolloverAction(null, null, null, 1L)); + hotActions.put(RolloverAction.NAME, new RolloverAction(null, null, null, 1L, null)); hotActions.put(SearchableSnapshotAction.NAME, new SearchableSnapshotAction(snapshotRepo, randomBoolean())); createPolicy( client(), @@ -614,7 +614,7 @@ public void testSearchableSnapshotsInHotPhasePinnedToHotNodes() throws Exception TimeValue.ZERO, Map.of( RolloverAction.NAME, - new RolloverAction(null, null, null, 1L), + new RolloverAction(null, null, null, 1L, null), SearchableSnapshotAction.NAME, new SearchableSnapshotAction(snapshotRepo, randomBoolean()) ) diff --git a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/ShrinkActionIT.java b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/ShrinkActionIT.java index c58fecc26dd39..670640268407d 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/ShrinkActionIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/ShrinkActionIT.java @@ -9,6 +9,7 @@ import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; +import org.apache.lucene.util.LuceneTestCase.AwaitsFix; import org.elasticsearch.client.Request; import org.elasticsearch.client.ResponseException; import org.elasticsearch.cluster.metadata.IndexMetadata; @@ -184,7 +185,7 @@ public void testShrinkActionInTheHotPhase() throws Exception { // add a policy Map hotActions = Map.of( RolloverAction.NAME, - new RolloverAction(null, null, null, 1L), + new RolloverAction(null, null, null, 1L, null), ShrinkAction.NAME, new ShrinkAction(expectedFinalShards, null) ); diff --git a/x-pack/plugin/ilm/qa/with-security/src/javaRestTest/java/org/elasticsearch/xpack/security/PermissionsIT.java b/x-pack/plugin/ilm/qa/with-security/src/javaRestTest/java/org/elasticsearch/xpack/security/PermissionsIT.java index 59971dfafc74e..04cd0731c9062 100644 --- a/x-pack/plugin/ilm/qa/with-security/src/javaRestTest/java/org/elasticsearch/xpack/security/PermissionsIT.java +++ b/x-pack/plugin/ilm/qa/with-security/src/javaRestTest/java/org/elasticsearch/xpack/security/PermissionsIT.java @@ -275,7 +275,7 @@ public void testWhenUserLimitedByOnlyAliasOfIndexCanWriteToIndexWhichWasRolledov * - Create role with just write and manage privileges on alias * - Create user and assign newly created role. */ - createNewSingletonPolicy(adminClient(), "foo-policy", "hot", new RolloverAction(null, null, null, 2L)); + createNewSingletonPolicy(adminClient(), "foo-policy", "hot", new RolloverAction(null, null, null, 2L, null)); createIndexTemplate("foo-template", "foo-logs-*", "foo_alias", "foo-policy"); createIndexAsAdmin("foo-logs-000001", "foo_alias", randomBoolean()); createRole("foo_alias_role", "foo_alias"); diff --git a/x-pack/plugin/ilm/src/internalClusterTest/java/org/elasticsearch/xpack/ilm/ILMMultiNodeIT.java b/x-pack/plugin/ilm/src/internalClusterTest/java/org/elasticsearch/xpack/ilm/ILMMultiNodeIT.java index 90faf271fbc70..c03b083741801 100644 --- a/x-pack/plugin/ilm/src/internalClusterTest/java/org/elasticsearch/xpack/ilm/ILMMultiNodeIT.java +++ b/x-pack/plugin/ilm/src/internalClusterTest/java/org/elasticsearch/xpack/ilm/ILMMultiNodeIT.java @@ -76,7 +76,7 @@ public void testShrinkOnTiers() throws Exception { startWarmOnlyNode(); ensureGreen(); - RolloverAction rolloverAction = new RolloverAction(null, null, null, 1L); + RolloverAction rolloverAction = new RolloverAction(null, null, null, 1L, null); Phase hotPhase = new Phase("hot", TimeValue.ZERO, Collections.singletonMap(rolloverAction.getWriteableName(), rolloverAction)); ShrinkAction shrinkAction = new ShrinkAction(1, null); Phase warmPhase = new Phase("warm", TimeValue.ZERO, Collections.singletonMap(shrinkAction.getWriteableName(), shrinkAction)); diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleTransitionTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleTransitionTests.java index f392e4fc36943..05f8d3139048c 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleTransitionTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleTransitionTests.java @@ -603,7 +603,7 @@ public void testValidateTransitionToCachedStepMissingFromPolicy() { try (Client client = new NoOpClient(getTestName())) { Step.StepKey currentStepKey = new Step.StepKey("hot", RolloverAction.NAME, WaitForRolloverReadyStep.NAME); Step.StepKey nextStepKey = new Step.StepKey("hot", RolloverAction.NAME, RolloverStep.NAME); - Step currentStep = new WaitForRolloverReadyStep(currentStepKey, nextStepKey, client, null, null, null, 1L); + Step currentStep = new WaitForRolloverReadyStep(currentStepKey, nextStepKey, client, null, null, null, 1L, null); try { IndexLifecycleTransition.validateTransition( meta, @@ -906,7 +906,7 @@ public void testRefreshPhaseJson() throws IOException { String index = meta.getIndex().getName(); Map actions = new HashMap<>(); - actions.put("rollover", new RolloverAction(null, null, null, 1L)); + actions.put("rollover", new RolloverAction(null, null, null, 1L, null)); actions.put("set_priority", new SetPriorityAction(100)); Phase hotPhase = new Phase("hot", TimeValue.ZERO, actions); Map phases = Collections.singletonMap("hot", hotPhase); @@ -1057,7 +1057,7 @@ public void testMoveStateToNextActionAndUpdateCachedPhase() { IndexMetadata meta = buildIndexMetadata("my-policy", currentExecutionState); Map actions = new HashMap<>(); - actions.put("rollover", new RolloverAction(null, null, null, 1L)); + actions.put("rollover", new RolloverAction(null, null, null, 1L, null)); actions.put("set_priority", new SetPriorityAction(100)); Phase hotPhase = new Phase("hot", TimeValue.ZERO, actions); Map phases = Collections.singletonMap("hot", hotPhase); @@ -1105,7 +1105,7 @@ public void testMoveStateToNextActionAndUpdateCachedPhase() { // the expected new state is that the index is moved into the next action (could be the complete one) and the cached phase // definition is updated Map actionsWitoutSetPriority = new HashMap<>(); - actionsWitoutSetPriority.put("rollover", new RolloverAction(null, null, null, 1L)); + actionsWitoutSetPriority.put("rollover", new RolloverAction(null, null, null, 1L, null)); Phase hotPhaseNoSetPriority = new Phase("hot", TimeValue.ZERO, actionsWitoutSetPriority); Map phasesWithoutSetPriority = Collections.singletonMap("hot", hotPhaseNoSetPriority); LifecyclePolicyMetadata updatedPolicyMetadata = new LifecyclePolicyMetadata(