Skip to content

Commit 3ed2d9e

Browse files
committed
Make ILM IndexNameGenerator project-aware
Since this method needs to access both the routing table and the metadata, we need to make use of the `ProjectState` here.
1 parent eaa7329 commit 3ed2d9e

File tree

3 files changed

+62
-47
lines changed

3 files changed

+62
-47
lines changed

server/src/main/java/org/elasticsearch/common/IndexNameGenerator.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
package org.elasticsearch.common;
1111

1212
import org.elasticsearch.action.ActionRequestValidationException;
13-
import org.elasticsearch.cluster.ClusterState;
13+
import org.elasticsearch.cluster.ProjectState;
1414
import org.elasticsearch.cluster.metadata.MetadataCreateIndexService;
1515
import org.elasticsearch.core.Nullable;
1616
import org.elasticsearch.indices.InvalidIndexNameException;
@@ -60,17 +60,17 @@ public static String generateValidIndexSuffix(Supplier<String> randomGenerator)
6060
* Returns null for valid indices.
6161
*/
6262
@Nullable
63-
public static ActionRequestValidationException validateGeneratedIndexName(String generatedIndexName, ClusterState state) {
63+
public static ActionRequestValidationException validateGeneratedIndexName(String generatedIndexName, ProjectState projectState) {
6464
ActionRequestValidationException err = new ActionRequestValidationException();
6565
try {
6666
MetadataCreateIndexService.validateIndexOrAliasName(generatedIndexName, InvalidIndexNameException::new);
6767
} catch (InvalidIndexNameException e) {
6868
err.addValidationError(e.getMessage());
6969
}
70-
if (state.routingTable().hasIndex(generatedIndexName) || state.metadata().getProject().hasIndex(generatedIndexName)) {
70+
if (projectState.routingTable().hasIndex(generatedIndexName) || projectState.metadata().hasIndex(generatedIndexName)) {
7171
err.addValidationError("the index name we generated [" + generatedIndexName + "] already exists");
7272
}
73-
if (state.metadata().getProject().hasAlias(generatedIndexName)) {
73+
if (projectState.metadata().hasAlias(generatedIndexName)) {
7474
err.addValidationError("the index name we generated [" + generatedIndexName + "] already exists as alias");
7575
}
7676

server/src/test/java/org/elasticsearch/common/IndexNameGeneratorTests.java

Lines changed: 57 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@
1212
import org.elasticsearch.action.ActionRequestValidationException;
1313
import org.elasticsearch.cluster.ClusterName;
1414
import org.elasticsearch.cluster.ClusterState;
15+
import org.elasticsearch.cluster.ProjectState;
1516
import org.elasticsearch.cluster.TestShardRoutingRoleStrategies;
1617
import org.elasticsearch.cluster.metadata.AliasMetadata;
1718
import org.elasticsearch.cluster.metadata.IndexMetadata;
18-
import org.elasticsearch.cluster.metadata.Metadata;
1919
import org.elasticsearch.cluster.metadata.MetadataCreateIndexService;
20+
import org.elasticsearch.cluster.metadata.ProjectMetadata;
2021
import org.elasticsearch.cluster.routing.RoutingTable;
2122
import org.elasticsearch.index.IndexVersion;
2223
import org.elasticsearch.indices.InvalidIndexNameException;
@@ -75,20 +76,15 @@ public void testGenerateValidIndexSuffix() {
7576

7677
public void testValidateGeneratedIndexName() {
7778
{
78-
assertThat(
79-
validateGeneratedIndexName(
80-
generateValidIndexName(randomAlphaOfLengthBetween(5, 10), randomAlphaOfLengthBetween(5, 150)),
81-
ClusterState.EMPTY_STATE
82-
),
83-
nullValue()
84-
);
79+
String generatedIndexName = generateValidIndexName(randomAlphaOfLengthBetween(5, 10), randomAlphaOfLengthBetween(5, 150));
80+
assertThat(validateGeneratedIndexName(generatedIndexName, createState(generatedIndexName, false, false, false)), nullValue());
8581
}
8682

8783
{
8884
// index name is validated (invalid chars etc)
8985
String generatedIndexName = generateValidIndexName("_prefix-", randomAlphaOfLengthBetween(5, 150));
9086
assertThat(
91-
validateGeneratedIndexName(generatedIndexName, ClusterState.EMPTY_STATE).validationErrors(),
87+
validateGeneratedIndexName(generatedIndexName, createState(generatedIndexName, false, false, false)).validationErrors(),
9288
containsInAnyOrder("Invalid index name [" + generatedIndexName + "], must not start with '_', '-', or '+'")
9389
);
9490
}
@@ -97,24 +93,18 @@ public void testValidateGeneratedIndexName() {
9793
// index name is validated (invalid chars etc)
9894
String generatedIndexName = generateValidIndexName("shrink-", "shrink-indexName-random###");
9995
assertThat(
100-
validateGeneratedIndexName(generatedIndexName, ClusterState.EMPTY_STATE).validationErrors(),
96+
validateGeneratedIndexName(generatedIndexName, createState(generatedIndexName, false, false, false)).validationErrors(),
10197
containsInAnyOrder("Invalid index name [" + generatedIndexName + "], must not contain '#'")
10298
);
10399
}
104100

105101
{
106102
// generated index already exists as a standalone index
107103
String generatedIndexName = generateValidIndexName(randomAlphaOfLengthBetween(5, 10), randomAlphaOfLengthBetween(5, 150));
108-
IndexMetadata indexMetadata = IndexMetadata.builder(generatedIndexName)
109-
.settings(settings(IndexVersion.current()))
110-
.numberOfShards(randomIntBetween(1, 5))
111-
.numberOfReplicas(randomIntBetween(1, 5))
112-
.build();
113-
ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT)
114-
.metadata(Metadata.builder().put(indexMetadata, false))
115-
.build();
116-
117-
ActionRequestValidationException validationException = validateGeneratedIndexName(generatedIndexName, clusterState);
104+
ActionRequestValidationException validationException = validateGeneratedIndexName(
105+
generatedIndexName,
106+
createState(generatedIndexName, true, false, false)
107+
);
118108
assertThat(validationException, notNullValue());
119109
assertThat(
120110
validationException.validationErrors(),
@@ -125,17 +115,24 @@ public void testValidateGeneratedIndexName() {
125115
{
126116
// generated index name already exists as an index (cluster state routing table is also populated)
127117
String generatedIndexName = generateValidIndexName(randomAlphaOfLengthBetween(5, 10), randomAlphaOfLengthBetween(5, 150));
128-
IndexMetadata indexMetadata = IndexMetadata.builder(generatedIndexName)
129-
.settings(settings(IndexVersion.current()))
130-
.numberOfShards(randomIntBetween(1, 5))
131-
.numberOfReplicas(randomIntBetween(1, 5))
132-
.build();
133-
ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT)
134-
.routingTable(RoutingTable.builder(TestShardRoutingRoleStrategies.DEFAULT_ROLE_ONLY).addAsNew(indexMetadata).build())
135-
.metadata(Metadata.builder().put(indexMetadata, false))
136-
.build();
137-
138-
ActionRequestValidationException validationException = validateGeneratedIndexName(generatedIndexName, clusterState);
118+
ActionRequestValidationException validationException = validateGeneratedIndexName(
119+
generatedIndexName,
120+
createState(generatedIndexName, true, true, false)
121+
);
122+
assertThat(validationException, notNullValue());
123+
assertThat(
124+
validationException.validationErrors(),
125+
containsInAnyOrder("the index name we generated [" + generatedIndexName + "] already exists")
126+
);
127+
}
128+
129+
{
130+
// generated index name already exists as an index but only in routing table
131+
String generatedIndexName = generateValidIndexName(randomAlphaOfLengthBetween(5, 10), randomAlphaOfLengthBetween(5, 150));
132+
ActionRequestValidationException validationException = validateGeneratedIndexName(
133+
generatedIndexName,
134+
createState(generatedIndexName, false, true, false)
135+
);
139136
assertThat(validationException, notNullValue());
140137
assertThat(
141138
validationException.validationErrors(),
@@ -146,22 +143,40 @@ public void testValidateGeneratedIndexName() {
146143
{
147144
// generated index name already exists as an alias to another index
148145
String generatedIndexName = generateValidIndexName(randomAlphaOfLengthBetween(5, 10), randomAlphaOfLengthBetween(5, 150));
149-
IndexMetadata indexMetadata = IndexMetadata.builder(randomAlphaOfLengthBetween(10, 30))
150-
.settings(settings(IndexVersion.current()))
151-
.numberOfShards(randomIntBetween(1, 5))
152-
.numberOfReplicas(randomIntBetween(1, 5))
153-
.putAlias(AliasMetadata.builder(generatedIndexName).build())
154-
.build();
155-
ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT)
156-
.metadata(Metadata.builder().put(indexMetadata, false))
157-
.build();
158-
159-
ActionRequestValidationException validationException = validateGeneratedIndexName(generatedIndexName, clusterState);
146+
ActionRequestValidationException validationException = validateGeneratedIndexName(
147+
generatedIndexName,
148+
createState(generatedIndexName, true, false, true)
149+
);
160150
assertThat(validationException, notNullValue());
161151
assertThat(
162152
validationException.validationErrors(),
163153
containsInAnyOrder("the index name we generated [" + generatedIndexName + "] already exists as alias")
164154
);
165155
}
166156
}
157+
158+
private ProjectState createState(String generatedName, boolean addIndexToMetadata, boolean addIndexToRoutingTable, boolean addAlias) {
159+
final var indexName = addAlias ? randomAlphaOfLengthBetween(10, 30) : generatedName;
160+
final var indexMetadataBuilder = IndexMetadata.builder(indexName)
161+
.settings(settings(IndexVersion.current()))
162+
.numberOfShards(randomIntBetween(1, 5))
163+
.numberOfReplicas(randomIntBetween(1, 5));
164+
if (addAlias) {
165+
indexMetadataBuilder.putAlias(AliasMetadata.builder(generatedName).build());
166+
}
167+
final var indexMetadata = indexMetadataBuilder.build();
168+
final var projectId = randomProjectIdOrDefault();
169+
final var projectBuilder = ProjectMetadata.builder(projectId);
170+
final var clusterStateBuilder = ClusterState.builder(ClusterName.DEFAULT);
171+
if (addIndexToMetadata) {
172+
projectBuilder.put(indexMetadata, false);
173+
}
174+
if (addIndexToRoutingTable) {
175+
clusterStateBuilder.putRoutingTable(
176+
projectId,
177+
RoutingTable.builder(TestShardRoutingRoleStrategies.DEFAULT_ROLE_ONLY).addAsNew(indexMetadata).build()
178+
);
179+
}
180+
return clusterStateBuilder.putProjectMetadata(projectBuilder).build().projectState(projectId);
181+
}
167182
}

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/GenerateUniqueIndexNameStep.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public ClusterState performAction(Index index, ClusterState clusterState) {
7474
Builder newLifecycleState = LifecycleExecutionState.builder(lifecycleState);
7575
String policyName = indexMetadata.getLifecyclePolicyName();
7676
String generatedIndexName = generateIndexName(prefix, index.getName());
77-
ActionRequestValidationException validationException = validateGeneratedIndexName(generatedIndexName, clusterState);
77+
ActionRequestValidationException validationException = validateGeneratedIndexName(generatedIndexName, clusterState.projectState());
7878
if (validationException != null) {
7979
logger.warn(
8080
"unable to generate a valid index name as part of policy [{}] for index [{}] due to [{}]",

0 commit comments

Comments
 (0)