Reduce use of deprecated Metadata builder method (#124290)

This removes all non-test usage of

     Metadata.Builder.put(IndexMetadata.Builder)

And replaces it with appropriate calls to the equivalent method on
`ProjectMetadata.Builder`

In most cases this _does not_ make the code project aware, but does
reduce the number of deprecated methods in use
This commit is contained in:
Tim Vernum 2025-04-11 18:36:19 +10:00 committed by GitHub
parent 788cd26a0f
commit a0dd4e76ec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 149 additions and 49 deletions

View file

@ -14,7 +14,10 @@ import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.metadata.Metadata;
import org.elasticsearch.cluster.metadata.ProjectId;
import org.elasticsearch.cluster.metadata.ProjectMetadata;
import org.elasticsearch.cluster.node.DiscoveryNodes; import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.cluster.routing.GlobalRoutingTable;
import org.elasticsearch.cluster.routing.RoutingTable; import org.elasticsearch.cluster.routing.RoutingTable;
import org.elasticsearch.cluster.routing.ShardRouting; import org.elasticsearch.cluster.routing.ShardRouting;
import org.elasticsearch.cluster.routing.allocation.AllocationService; import org.elasticsearch.cluster.routing.allocation.AllocationService;
@ -126,19 +129,20 @@ public class AllocationBenchmark {
Settings.builder().put("cluster.routing.allocation.awareness.attributes", "tag").build() Settings.builder().put("cluster.routing.allocation.awareness.attributes", "tag").build()
); );
Metadata.Builder mb = Metadata.builder(); final ProjectId projectId = ProjectId.DEFAULT;
ProjectMetadata.Builder pmb = ProjectMetadata.builder(projectId);
for (int i = 1; i <= numIndices; i++) { for (int i = 1; i <= numIndices; i++) {
mb.put( pmb.put(
IndexMetadata.builder("test_" + i) IndexMetadata.builder("test_" + i)
.settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current())) .settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current()))
.numberOfShards(numShards) .numberOfShards(numShards)
.numberOfReplicas(numReplicas) .numberOfReplicas(numReplicas)
); );
} }
Metadata metadata = mb.build(); Metadata metadata = Metadata.builder().put(pmb).build();
RoutingTable.Builder rb = RoutingTable.builder(TestShardRoutingRoleStrategies.DEFAULT_ROLE_ONLY); RoutingTable.Builder rb = RoutingTable.builder(TestShardRoutingRoleStrategies.DEFAULT_ROLE_ONLY);
for (int i = 1; i <= numIndices; i++) { for (int i = 1; i <= numIndices; i++) {
rb.addAsNew(metadata.getProject().index("test_" + i)); rb.addAsNew(metadata.getProject(projectId).index("test_" + i));
} }
RoutingTable routingTable = rb.build(); RoutingTable routingTable = rb.build();
DiscoveryNodes.Builder nb = DiscoveryNodes.builder(); DiscoveryNodes.Builder nb = DiscoveryNodes.builder();
@ -151,7 +155,7 @@ public class AllocationBenchmark {
} }
initialClusterState = ClusterState.builder(ClusterName.DEFAULT) initialClusterState = ClusterState.builder(ClusterName.DEFAULT)
.metadata(metadata) .metadata(metadata)
.routingTable(routingTable) .routingTable(GlobalRoutingTable.builder().put(projectId, routingTable).build())
.nodes(nb) .nodes(nb)
.nodeIdsToCompatibilityVersions(compatibilityVersions) .nodeIdsToCompatibilityVersions(compatibilityVersions)
.build(); .build();

View file

@ -983,6 +983,10 @@ public class ClusterState implements ChunkedToXContent, Diffable<ClusterState> {
return copyAndUpdate(builder -> builder.metadata(metadata().copyAndUpdate(updater))); return copyAndUpdate(builder -> builder.metadata(metadata().copyAndUpdate(updater)));
} }
public ClusterState copyAndUpdateProject(ProjectId projectId, Consumer<ProjectMetadata.Builder> updater) {
return copyAndUpdate(builder -> builder.putProjectMetadata(metadata().getProject(projectId).copyAndUpdate(updater)));
}
@SuppressForbidden(reason = "directly reading ClusterState#clusterFeatures") @SuppressForbidden(reason = "directly reading ClusterState#clusterFeatures")
private static Map<String, Set<String>> getNodeFeatures(ClusterFeatures features) { private static Map<String, Set<String>> getNodeFeatures(ClusterFeatures features) {
return features.nodeFeatures(); return features.nodeFeatures();

View file

@ -16,7 +16,7 @@ import org.elasticsearch.cli.Terminal;
import org.elasticsearch.cli.UserException; import org.elasticsearch.cli.UserException;
import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.metadata.ProjectMetadata;
import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.core.Tuple; import org.elasticsearch.core.Tuple;
@ -58,9 +58,10 @@ public class RemoveIndexSettingsCommand extends ElasticsearchNodeCommand {
terminal.println(Terminal.Verbosity.VERBOSE, "Loading cluster state"); terminal.println(Terminal.Verbosity.VERBOSE, "Loading cluster state");
final Tuple<Long, ClusterState> termAndClusterState = loadTermAndClusterState(persistedClusterStateService, env); final Tuple<Long, ClusterState> termAndClusterState = loadTermAndClusterState(persistedClusterStateService, env);
final ClusterState oldClusterState = termAndClusterState.v2(); final ClusterState oldClusterState = termAndClusterState.v2();
final Metadata.Builder newMetadataBuilder = Metadata.builder(oldClusterState.metadata()); final ProjectMetadata oldProject = oldClusterState.metadata().getProject();
final ProjectMetadata.Builder newProjectBuilder = ProjectMetadata.builder(oldProject);
int changes = 0; int changes = 0;
for (IndexMetadata indexMetadata : oldClusterState.metadata().getProject()) { for (IndexMetadata indexMetadata : oldProject) {
Settings oldSettings = indexMetadata.getSettings(); Settings oldSettings = indexMetadata.getSettings();
Settings.Builder newSettings = Settings.builder().put(oldSettings); Settings.Builder newSettings = Settings.builder().put(oldSettings);
boolean removed = false; boolean removed = false;
@ -76,7 +77,7 @@ public class RemoveIndexSettingsCommand extends ElasticsearchNodeCommand {
} }
} }
if (removed) { if (removed) {
newMetadataBuilder.put(IndexMetadata.builder(indexMetadata).settings(newSettings)); newProjectBuilder.put(IndexMetadata.builder(indexMetadata).settings(newSettings));
changes++; changes++;
} }
} }
@ -84,7 +85,7 @@ public class RemoveIndexSettingsCommand extends ElasticsearchNodeCommand {
throw new UserException(ExitCodes.USAGE, "No index setting matching " + settingsToRemove + " were found on this node"); throw new UserException(ExitCodes.USAGE, "No index setting matching " + settingsToRemove + " were found on this node");
} }
final ClusterState newClusterState = ClusterState.builder(oldClusterState).metadata(newMetadataBuilder).build(); final ClusterState newClusterState = ClusterState.builder(oldClusterState).putProjectMetadata(newProjectBuilder).build();
terminal.println( terminal.println(
Terminal.Verbosity.VERBOSE, Terminal.Verbosity.VERBOSE,
"[old cluster state = " + oldClusterState + ", new cluster state = " + newClusterState + "]" "[old cluster state = " + oldClusterState + ", new cluster state = " + newClusterState + "]"

View file

@ -15,6 +15,7 @@ import org.elasticsearch.cli.Terminal;
import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.metadata.Metadata;
import org.elasticsearch.cluster.metadata.ProjectMetadata;
import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.UUIDs; import org.elasticsearch.common.UUIDs;
@ -104,8 +105,10 @@ public class UnsafeBootstrapMasterCommand extends ElasticsearchNodeCommand {
.clusterUUIDCommitted(true) .clusterUUIDCommitted(true)
.persistentSettings(persistentSettings) .persistentSettings(persistentSettings)
.coordinationMetadata(newCoordinationMetadata); .coordinationMetadata(newCoordinationMetadata);
final ProjectMetadata.Builder newProject = ProjectMetadata.builder(metadata.getProject());
for (IndexMetadata indexMetadata : metadata.getProject().indices().values()) { for (IndexMetadata indexMetadata : metadata.getProject().indices().values()) {
newMetadata.put( newProject.put(
IndexMetadata.builder(indexMetadata) IndexMetadata.builder(indexMetadata)
.settings( .settings(
Settings.builder() Settings.builder()
@ -114,6 +117,7 @@ public class UnsafeBootstrapMasterCommand extends ElasticsearchNodeCommand {
) )
); );
} }
newMetadata.put(newProject);
final ClusterState newClusterState = ClusterState.builder(oldClusterState).metadata(newMetadata).build(); final ClusterState newClusterState = ClusterState.builder(oldClusterState).metadata(newMetadata).build();

View file

@ -66,6 +66,7 @@ import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.BiPredicate; import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -1117,6 +1118,12 @@ public class ProjectMetadata implements Iterable<IndexMetadata>, Diffable<Projec
return new ProjectMetadata.Builder(projectMetadata); return new ProjectMetadata.Builder(projectMetadata);
} }
public ProjectMetadata copyAndUpdate(Consumer<Builder> updater) {
var builder = builder(this);
updater.accept(builder);
return builder.build();
}
public static class Builder { public static class Builder {
private final ImmutableOpenMap.Builder<String, IndexMetadata> indices; private final ImmutableOpenMap.Builder<String, IndexMetadata> indices;

View file

@ -29,6 +29,7 @@ import org.elasticsearch.cluster.metadata.ProjectMetadata;
import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodeUtils; import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
import org.elasticsearch.cluster.node.DiscoveryNodes; import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.cluster.routing.GlobalRoutingTable;
import org.elasticsearch.cluster.routing.GlobalRoutingTableTestHelper; import org.elasticsearch.cluster.routing.GlobalRoutingTableTestHelper;
import org.elasticsearch.cluster.routing.IndexRoutingTable; import org.elasticsearch.cluster.routing.IndexRoutingTable;
import org.elasticsearch.cluster.routing.IndexShardRoutingTable; import org.elasticsearch.cluster.routing.IndexShardRoutingTable;
@ -149,6 +150,24 @@ public class ClusterStateTests extends ESTestCase {
assertThat(copy.metadata().clusterUUID(), equalTo(newClusterUuid)); assertThat(copy.metadata().clusterUUID(), equalTo(newClusterUuid));
} }
public void testCopyAndUpdateProject() throws IOException {
var projectId = randomProjectIdOrDefault();
var state = buildClusterState(projectId);
var indexName = getTestName();
assertThat(state.metadata().getProject(projectId).hasIndex(indexName), equalTo(false));
var copy = state.copyAndUpdateProject(
projectId,
project -> project.put(IndexMetadata.builder(indexName).settings(indexSettings(IndexVersion.current(), randomUUID(), 1, 1)))
);
assertThat(copy, not(sameInstance(state)));
assertThat(copy.metadata(), not(sameInstance(state.metadata())));
assertThat(copy.metadata().getProject(projectId), not(sameInstance(state.metadata().getProject(projectId))));
assertThat(copy.metadata().getProject(projectId).hasIndex(indexName), equalTo(true));
}
public void testGetNonExistingProjectStateThrows() { public void testGetNonExistingProjectStateThrows() {
final List<ProjectMetadata> projects = IntStream.range(0, between(1, 3)) final List<ProjectMetadata> projects = IntStream.range(0, between(1, 3))
.mapToObj(i -> MetadataTests.randomProject(ProjectId.fromId("p_" + i), between(0, 5))) .mapToObj(i -> MetadataTests.randomProject(ProjectId.fromId("p_" + i), between(0, 5)))
@ -1862,6 +1881,10 @@ public class ClusterStateTests extends ESTestCase {
} }
private ClusterState buildClusterState() throws IOException { private ClusterState buildClusterState() throws IOException {
return buildClusterState(ProjectId.DEFAULT);
}
private static ClusterState buildClusterState(ProjectId projectId) throws IOException {
IndexMetadata indexMetadata = IndexMetadata.builder("index") IndexMetadata indexMetadata = IndexMetadata.builder("index")
.state(IndexMetadata.State.OPEN) .state(IndexMetadata.State.OPEN)
.settings(Settings.builder().put(SETTING_VERSION_CREATED, IndexVersion.current())) .settings(Settings.builder().put(SETTING_VERSION_CREATED, IndexVersion.current()))
@ -1925,29 +1948,38 @@ public class ClusterStateTests extends ESTestCase {
) )
.persistentSettings(Settings.builder().put(SETTING_VERSION_CREATED, IndexVersion.current()).build()) .persistentSettings(Settings.builder().put(SETTING_VERSION_CREATED, IndexVersion.current()).build())
.transientSettings(Settings.builder().put(SETTING_VERSION_CREATED, IndexVersion.current()).build()) .transientSettings(Settings.builder().put(SETTING_VERSION_CREATED, IndexVersion.current()).build())
.put(indexMetadata, false)
.put( .put(
IndexTemplateMetadata.builder("template") ProjectMetadata.builder(projectId)
.patterns(List.of("pattern1", "pattern2")) .put(indexMetadata, false)
.order(0) .put(
.settings(Settings.builder().put(SETTING_VERSION_CREATED, IndexVersion.current())) IndexTemplateMetadata.builder("template")
.putMapping("type", "{ \"key1\": {} }") .patterns(List.of("pattern1", "pattern2"))
.order(0)
.settings(Settings.builder().put(SETTING_VERSION_CREATED, IndexVersion.current()))
.putMapping("type", "{ \"key1\": {} }")
.build()
)
.build() .build()
) )
) )
.routingTable( .routingTable(
RoutingTable.builder() GlobalRoutingTable.builder()
.add( .put(
IndexRoutingTable.builder(new Index("index", "indexUUID")) projectId,
.addIndexShard( RoutingTable.builder()
new IndexShardRoutingTable.Builder(new ShardId("index", "indexUUID", 0)).addShard( .add(
TestShardRouting.newShardRouting( IndexRoutingTable.builder(new Index("index", "indexUUID"))
new ShardId("index", "indexUUID", 0), .addIndexShard(
"nodeId2", new IndexShardRoutingTable.Builder(new ShardId("index", "indexUUID", 0)).addShard(
true, TestShardRouting.newShardRouting(
ShardRoutingState.STARTED new ShardId("index", "indexUUID", 0),
"nodeId2",
true,
ShardRoutingState.STARTED
)
)
) )
) .build()
) )
.build() .build()
) )

View file

@ -29,6 +29,9 @@ import static org.elasticsearch.cluster.metadata.MetadataTests.checkChunkSize;
import static org.elasticsearch.cluster.metadata.MetadataTests.count; import static org.elasticsearch.cluster.metadata.MetadataTests.count;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent;
import static org.elasticsearch.xcontent.ToXContent.EMPTY_PARAMS; import static org.elasticsearch.xcontent.ToXContent.EMPTY_PARAMS;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.sameInstance;
public class ProjectMetadataTests extends ESTestCase { public class ProjectMetadataTests extends ESTestCase {
@ -384,4 +387,21 @@ public class ProjectMetadataTests extends ESTestCase {
return Math.toIntExact(chunkCount); return Math.toIntExact(chunkCount);
} }
public void testCopyAndUpdate() {
var initialIndexUUID = randomUUID();
final String indexName = randomAlphaOfLengthBetween(4, 12);
final ProjectMetadata before = ProjectMetadata.builder(randomProjectIdOrDefault())
.put(IndexMetadata.builder(indexName).settings(indexSettings(IndexVersion.current(), initialIndexUUID, 1, 1)))
.build();
var alteredIndexUUID = randomUUID();
assertThat(alteredIndexUUID, not(equalTo(initialIndexUUID)));
final ProjectMetadata after = before.copyAndUpdate(
builder -> builder.put(IndexMetadata.builder(indexName).settings(indexSettings(IndexVersion.current(), alteredIndexUUID, 1, 1)))
);
assertThat(after, not(sameInstance(before)));
assertThat(after.index(indexName).getIndexUUID(), equalTo(alteredIndexUUID));
}
} }

View file

@ -26,10 +26,12 @@ import org.elasticsearch.cluster.ClusterStateUpdateTask;
import org.elasticsearch.cluster.block.ClusterBlockException; import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.ProjectId;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.EsExecutors; import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.core.FixForMultiProject;
import org.elasticsearch.core.SuppressForbidden; import org.elasticsearch.core.SuppressForbidden;
import org.elasticsearch.index.Index; import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.index.IndexNotFoundException;
@ -287,6 +289,8 @@ public class TransportUnfollowAction extends AcknowledgedTransportMasterNodeActi
// Remove ccr custom metadata // Remove ccr custom metadata
newIndexMetadata.removeCustom(Ccr.CCR_CUSTOM_METADATA_KEY); newIndexMetadata.removeCustom(Ccr.CCR_CUSTOM_METADATA_KEY);
return current.copyAndUpdateMetadata(metadata -> metadata.put(newIndexMetadata)); @FixForMultiProject
final ProjectId projectId = current.metadata().getProject().id();
return current.copyAndUpdateProject(projectId, project -> project.put(newIndexMetadata));
} }
} }

View file

@ -20,6 +20,7 @@ import org.apache.lucene.store.NIOFSDirectory;
import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.MappingMetadata; import org.elasticsearch.cluster.metadata.MappingMetadata;
import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.metadata.Metadata;
import org.elasticsearch.cluster.metadata.ProjectMetadata;
import org.elasticsearch.cluster.metadata.RepositoryMetadata; import org.elasticsearch.cluster.metadata.RepositoryMetadata;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.lucene.Lucene;
@ -110,9 +111,13 @@ public final class SourceOnlySnapshotRepository extends FilterRepository {
} }
private static Metadata metadataToSnapshot(Collection<IndexId> indices, Metadata metadata) { private static Metadata metadataToSnapshot(Collection<IndexId> indices, Metadata metadata) {
Metadata.Builder builder = Metadata.builder(metadata); return Metadata.builder(metadata).put(projectMetadataToSnapshot(indices, metadata.getProject())).build();
}
private static ProjectMetadata projectMetadataToSnapshot(Collection<IndexId> indices, ProjectMetadata projectMetadata) {
ProjectMetadata.Builder builder = ProjectMetadata.builder(projectMetadata);
for (IndexId indexId : indices) { for (IndexId indexId : indices) {
IndexMetadata index = metadata.getProject().index(indexId.getName()); IndexMetadata index = projectMetadata.index(indexId.getName());
IndexMetadata.Builder indexMetadataBuilder = IndexMetadata.builder(index); IndexMetadata.Builder indexMetadataBuilder = IndexMetadata.builder(index);
// for a minimal restore we basically disable indexing on all fields and only create an index // for a minimal restore we basically disable indexing on all fields and only create an index
// that is valid from an operational perspective. ie. it will have all metadata fields like version/ // that is valid from an operational perspective. ie. it will have all metadata fields like version/

View file

@ -11,7 +11,7 @@ import org.apache.logging.log4j.Logger;
import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.LifecycleExecutionState; import org.elasticsearch.cluster.metadata.LifecycleExecutionState;
import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.metadata.ProjectMetadata;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.Index; import org.elasticsearch.index.Index;
@ -94,11 +94,11 @@ public class CopySettingsStep extends ClusterStateActionStep {
settings.put(key, value); settings.put(key, value);
} }
Metadata.Builder newMetaData = Metadata.builder(clusterState.getMetadata()) ProjectMetadata.Builder newProject = ProjectMetadata.builder(clusterState.getMetadata().getProject())
.put( .put(
IndexMetadata.builder(targetIndexMetadata).settingsVersion(targetIndexMetadata.getSettingsVersion() + 1).settings(settings) IndexMetadata.builder(targetIndexMetadata).settingsVersion(targetIndexMetadata.getSettingsVersion() + 1).settings(settings)
); );
return ClusterState.builder(clusterState).metadata(newMetaData).build(); return ClusterState.builder(clusterState).putProjectMetadata(newProject).build();
} }
@Override @Override

View file

@ -11,7 +11,7 @@ import org.apache.logging.log4j.Logger;
import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.LifecycleExecutionState; import org.elasticsearch.cluster.metadata.LifecycleExecutionState;
import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.metadata.ProjectMetadata;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.Index; import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.IndexSettings;
@ -79,7 +79,9 @@ public final class InitializePolicyContextStep extends ClusterStateActionStep {
.build() .build()
); );
builder.putCustom(ILM_CUSTOM_METADATA_KEY, newLifecycleState.asMap()); builder.putCustom(ILM_CUSTOM_METADATA_KEY, newLifecycleState.asMap());
return ClusterState.builder(clusterState).metadata(Metadata.builder(clusterState.metadata()).put(builder).build()).build(); return ClusterState.builder(clusterState)
.putProjectMetadata(ProjectMetadata.builder(clusterState.metadata().getProject()).put(builder).build())
.build();
} }
} }

View file

@ -15,9 +15,10 @@ import org.elasticsearch.client.internal.Client;
import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.LifecycleExecutionState; import org.elasticsearch.cluster.metadata.LifecycleExecutionState;
import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.metadata.ProjectMetadata;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.index.Index; import org.elasticsearch.index.Index;
import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.xcontent.ToXContentObject; import org.elasticsearch.xcontent.ToXContentObject;
@ -443,28 +444,44 @@ public final class IndexLifecycleTransition {
* any lifecycle execution state that may be present in the index metadata * any lifecycle execution state that may be present in the index metadata
*/ */
public static ClusterState removePolicyForIndexes(final Index[] indices, ClusterState currentState, List<String> failedIndexes) { public static ClusterState removePolicyForIndexes(final Index[] indices, ClusterState currentState, List<String> failedIndexes) {
Metadata.Builder newMetadata = Metadata.builder(currentState.getMetadata()); final ProjectMetadata currentProject = currentState.metadata().getProject();
boolean clusterStateChanged = false; final ProjectMetadata.Builder updatedProject = removePolicyForIndexes(indices, currentProject, failedIndexes);
if (updatedProject == null) {
return currentState;
} else {
return ClusterState.builder(currentState).putProjectMetadata(updatedProject).build();
}
}
/**
* @return If one or more policies were removed, then a new builder representing the changed project state.
* Otherwise {@code null} (if no changes were made)
*/
@Nullable
private static ProjectMetadata.Builder removePolicyForIndexes(
final Index[] indices,
ProjectMetadata currentProject,
List<String> failedIndexes
) {
ProjectMetadata.Builder newProject = null;
for (Index index : indices) { for (Index index : indices) {
IndexMetadata indexMetadata = currentState.getMetadata().getProject().index(index); IndexMetadata indexMetadata = currentProject.index(index);
if (indexMetadata == null) { if (indexMetadata == null) {
// Index doesn't exist so fail it // Index doesn't exist so fail it
failedIndexes.add(index.getName()); failedIndexes.add(index.getName());
} else { } else {
IndexMetadata.Builder newIdxMetadata = removePolicyForIndex(indexMetadata); IndexMetadata.Builder newIdxMetadata = removePolicyForIndex(indexMetadata);
if (newIdxMetadata != null) { if (newIdxMetadata != null) {
newMetadata.put(newIdxMetadata); if (newProject == null) {
clusterStateChanged = true; newProject = ProjectMetadata.builder(currentProject);
}
newProject.put(newIdxMetadata);
} }
} }
} }
if (clusterStateChanged) {
ClusterState.Builder newClusterState = ClusterState.builder(currentState); return newProject;
newClusterState.metadata(newMetadata);
return newClusterState.build();
} else {
return currentState;
}
} }
/** /**