Sfoglia il codice sorgente

Mark watcher NotMultiProjectCapable and replace deprecated multi-project methods (#131313)

Sam Xiao 2 mesi fa
parent
commit
38b7bfcaf3
14 ha cambiato i file con 206 aggiunte e 128 eliminazioni
  1. 4 1
      x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java
  2. 9 5
      x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherIndexingListener.java
  3. 10 3
      x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherLifeCycleService.java
  4. 7 2
      x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherService.java
  5. 4 1
      x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/execution/TriggeredWatchStore.java
  6. 4 1
      x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/history/HistoryStore.java
  7. 4 1
      x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistry.java
  8. 7 2
      x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/watch/WatchStoreUtils.java
  9. 32 22
      x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherIndexingListenerTests.java
  10. 60 50
      x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherLifeCycleServiceTests.java
  11. 13 9
      x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherServiceTests.java
  12. 21 17
      x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/execution/TriggeredWatchStoreTests.java
  13. 9 3
      x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistryTests.java
  14. 22 11
      x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/watch/WatchStoreUtilsTests.java

+ 4 - 1
x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java

@@ -21,6 +21,7 @@ import org.elasticsearch.cluster.metadata.DataStream;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
 import org.elasticsearch.cluster.metadata.IndexTemplateMetadata;
+import org.elasticsearch.cluster.metadata.ProjectId;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.node.DiscoveryNodes;
 import org.elasticsearch.cluster.service.ClusterService;
@@ -35,6 +36,7 @@ import org.elasticsearch.common.unit.ByteSizeUnit;
 import org.elasticsearch.common.unit.ByteSizeValue;
 import org.elasticsearch.common.util.concurrent.EsExecutors;
 import org.elasticsearch.core.IOUtils;
+import org.elasticsearch.core.NotMultiProjectCapable;
 import org.elasticsearch.core.TimeValue;
 import org.elasticsearch.core.UpdateForV10;
 import org.elasticsearch.env.Environment;
@@ -823,10 +825,11 @@ public class Watcher extends Plugin implements SystemIndexPlugin, ScriptPlugin,
     }
 
     @Override
+    @NotMultiProjectCapable(description = "Watcher is not available in serverless")
     public void prepareForIndicesMigration(ClusterService clusterService, Client client, ActionListener<Map<String, Object>> listener) {
         Client originClient = new OriginSettingClient(client, WATCHER_ORIGIN);
         boolean manuallyStopped = Optional.ofNullable(
-            clusterService.state().metadata().getProject().<WatcherMetadata>custom(WatcherMetadata.TYPE)
+            clusterService.state().metadata().getProject(ProjectId.DEFAULT).<WatcherMetadata>custom(WatcherMetadata.TYPE)
         ).map(WatcherMetadata::manuallyStopped).orElse(false);
 
         if (manuallyStopped == false) {

+ 9 - 5
x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherIndexingListener.java

@@ -14,6 +14,7 @@ import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.ClusterStateListener;
 import org.elasticsearch.cluster.block.ClusterBlockLevel;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
+import org.elasticsearch.cluster.metadata.ProjectId;
 import org.elasticsearch.cluster.routing.AllocationId;
 import org.elasticsearch.cluster.routing.IndexRoutingTable;
 import org.elasticsearch.cluster.routing.Murmur3HashFunction;
@@ -22,6 +23,7 @@ import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.util.Maps;
 import org.elasticsearch.common.util.set.Sets;
+import org.elasticsearch.core.NotMultiProjectCapable;
 import org.elasticsearch.index.engine.Engine;
 import org.elasticsearch.index.shard.IndexingOperationListener;
 import org.elasticsearch.index.shard.ShardId;
@@ -251,10 +253,12 @@ final class WatcherIndexingListener implements IndexingOperationListener, Cluste
      * @param event             The cluster changed event containing the new cluster state
      */
     private void reloadConfiguration(String watchIndex, List<ShardRouting> localShardRouting, ClusterChangedEvent event) {
+        @NotMultiProjectCapable(description = "Watcher is not available in serverless")
+        ProjectId projectId = ProjectId.DEFAULT;
         // changed alias means to always read a new configuration
         boolean isAliasChanged = watchIndex.equals(configuration.index) == false;
-        if (isAliasChanged || hasShardAllocationIdChanged(watchIndex, event.state())) {
-            IndexRoutingTable watchIndexRoutingTable = event.state().routingTable().index(watchIndex);
+        if (isAliasChanged || hasShardAllocationIdChanged(projectId, watchIndex, event.state())) {
+            IndexRoutingTable watchIndexRoutingTable = event.state().routingTable(projectId).index(watchIndex);
             Map<ShardId, ShardAllocationConfiguration> ids = getLocalShardAllocationIds(localShardRouting, watchIndexRoutingTable);
             configuration = new Configuration(watchIndex, ids);
         }
@@ -267,9 +271,9 @@ final class WatcherIndexingListener implements IndexingOperationListener, Cluste
      * @param state      The new cluster state
      * @return           true if the routing tables has changed and local shards are affected
      */
-    private boolean hasShardAllocationIdChanged(String watchIndex, ClusterState state) {
-        List<ShardRouting> allStartedRelocatedShards = state.getRoutingTable().index(watchIndex).shardsWithState(STARTED);
-        allStartedRelocatedShards.addAll(state.getRoutingTable().index(watchIndex).shardsWithState(RELOCATING));
+    private boolean hasShardAllocationIdChanged(ProjectId projectId, String watchIndex, ClusterState state) {
+        List<ShardRouting> allStartedRelocatedShards = state.routingTable(projectId).index(watchIndex).shardsWithState(STARTED);
+        allStartedRelocatedShards.addAll(state.routingTable(projectId).index(watchIndex).shardsWithState(RELOCATING));
 
         // exit early, when there are shards, but the current configuration is inactive
         if (allStartedRelocatedShards.isEmpty() == false && configuration == INACTIVE) {

+ 10 - 3
x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherLifeCycleService.java

@@ -13,12 +13,15 @@ import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.ClusterStateListener;
 import org.elasticsearch.cluster.block.ClusterBlockLevel;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
+import org.elasticsearch.cluster.metadata.ProjectId;
 import org.elasticsearch.cluster.node.DiscoveryNode;
+import org.elasticsearch.cluster.routing.IndexRoutingTable;
 import org.elasticsearch.cluster.routing.RoutingNode;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.service.ClusterService;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.component.LifecycleListener;
+import org.elasticsearch.core.NotMultiProjectCapable;
 import org.elasticsearch.gateway.GatewayService;
 import org.elasticsearch.index.shard.ShardId;
 import org.elasticsearch.xpack.core.watcher.WatcherMetadata;
@@ -153,8 +156,11 @@ public class WatcherLifeCycleService implements ClusterStateListener {
         // also check if non local shards have changed, as loosing a shard on a
         // remote node or adding a replica on a remote node needs to trigger a reload too
         Set<ShardId> localShardIds = localShards.stream().map(ShardRouting::shardId).collect(Collectors.toSet());
-        List<ShardRouting> allShards = event.state().routingTable().index(watchIndex).shardsWithState(STARTED);
-        allShards.addAll(event.state().routingTable().index(watchIndex).shardsWithState(RELOCATING));
+
+        @NotMultiProjectCapable(description = "Watcher is not available in serverless")
+        IndexRoutingTable routingTable = event.state().routingTable(ProjectId.DEFAULT).index(watchIndex);
+        List<ShardRouting> allShards = routingTable.shardsWithState(STARTED);
+        allShards.addAll(routingTable.shardsWithState(RELOCATING));
         List<ShardRouting> localAffectedShardRoutings = allShards.stream()
             .filter(shardRouting -> localShardIds.contains(shardRouting.shardId()))
             // shardrouting is not comparable, so we need some order mechanism
@@ -192,8 +198,9 @@ public class WatcherLifeCycleService implements ClusterStateListener {
     /**
      * check if watcher has been stopped manually via the stop API
      */
+    @NotMultiProjectCapable(description = "Watcher is not available in serverless")
     private static boolean isWatcherStoppedManually(ClusterState state) {
-        WatcherMetadata watcherMetadata = state.getMetadata().getProject().custom(WatcherMetadata.TYPE);
+        WatcherMetadata watcherMetadata = state.getMetadata().getProject(ProjectId.DEFAULT).custom(WatcherMetadata.TYPE);
         return watcherMetadata != null && watcherMetadata.manuallyStopped();
     }
 

+ 7 - 2
x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherService.java

@@ -18,6 +18,7 @@ import org.elasticsearch.action.support.broadcast.BroadcastResponse;
 import org.elasticsearch.client.internal.Client;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
+import org.elasticsearch.cluster.metadata.ProjectId;
 import org.elasticsearch.cluster.routing.AllocationId;
 import org.elasticsearch.cluster.routing.Murmur3HashFunction;
 import org.elasticsearch.cluster.routing.Preference;
@@ -27,6 +28,7 @@ import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.util.Maps;
 import org.elasticsearch.common.util.concurrent.AbstractRunnable;
 import org.elasticsearch.common.util.concurrent.EsExecutors;
+import org.elasticsearch.core.NotMultiProjectCapable;
 import org.elasticsearch.core.TimeValue;
 import org.elasticsearch.search.SearchHit;
 import org.elasticsearch.search.builder.SearchSourceBuilder;
@@ -134,6 +136,8 @@ public class WatcherService {
      * @return true if everything is good to go, so that the service can be started
      */
     public boolean validate(ClusterState state) {
+        @NotMultiProjectCapable(description = "Watcher is not available in serverless")
+        ProjectId projectId = ProjectId.DEFAULT;
         IndexMetadata watcherIndexMetadata = WatchStoreUtils.getConcreteIndex(Watch.INDEX, state.metadata());
         IndexMetadata triggeredWatchesIndexMetadata = WatchStoreUtils.getConcreteIndex(
             TriggeredWatchStoreField.INDEX_NAME,
@@ -160,7 +164,7 @@ public class WatcherService {
 
             return watcherIndexMetadata == null
                 || (watcherIndexMetadata.getState() == IndexMetadata.State.OPEN
-                    && state.routingTable().index(watcherIndexMetadata.getIndex()).allPrimaryShardsActive());
+                    && state.routingTable(projectId).index(watcherIndexMetadata.getIndex()).allPrimaryShardsActive());
         } catch (IllegalStateException e) {
             logger.warn("Validation error: cannot start watcher", e);
             return false;
@@ -329,7 +333,8 @@ public class WatcherService {
             List<ShardRouting> localShards = routingNode.shardsWithState(watchIndexName, RELOCATING, STARTED).toList();
 
             // find out all allocation ids
-            List<ShardRouting> watchIndexShardRoutings = clusterState.getRoutingTable().allShards(watchIndexName);
+            @NotMultiProjectCapable(description = "Watcher is not available in serverless")
+            List<ShardRouting> watchIndexShardRoutings = clusterState.routingTable(ProjectId.DEFAULT).allShards(watchIndexName);
 
             SearchRequest searchRequest = new SearchRequest(INDEX).scroll(scrollTimeout)
                 .preference(Preference.ONLY_LOCAL.toString())

+ 4 - 1
x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/execution/TriggeredWatchStore.java

@@ -24,8 +24,10 @@ import org.elasticsearch.action.support.PlainActionFuture;
 import org.elasticsearch.client.internal.Client;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
+import org.elasticsearch.cluster.metadata.ProjectId;
 import org.elasticsearch.cluster.routing.Preference;
 import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.core.NotMultiProjectCapable;
 import org.elasticsearch.core.TimeValue;
 import org.elasticsearch.index.IndexNotFoundException;
 import org.elasticsearch.search.SearchHit;
@@ -183,10 +185,11 @@ public class TriggeredWatchStore {
         return triggeredWatches;
     }
 
+    @NotMultiProjectCapable(description = "Watcher is not available in serverless")
     public static boolean validate(ClusterState state) {
         IndexMetadata indexMetadata = WatchStoreUtils.getConcreteIndex(TriggeredWatchStoreField.INDEX_NAME, state.metadata());
         return indexMetadata == null
             || (indexMetadata.getState() == IndexMetadata.State.OPEN
-                && state.routingTable().index(indexMetadata.getIndex()).allPrimaryShardsActive());
+                && state.routingTable(ProjectId.DEFAULT).index(indexMetadata.getIndex()).allPrimaryShardsActive());
     }
 }

+ 4 - 1
x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/history/HistoryStore.java

@@ -13,9 +13,11 @@ import org.elasticsearch.action.bulk.BulkProcessor2;
 import org.elasticsearch.action.index.IndexRequest;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
+import org.elasticsearch.cluster.metadata.ProjectId;
 import org.elasticsearch.common.settings.Setting;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.unit.ByteSizeValue;
+import org.elasticsearch.core.NotMultiProjectCapable;
 import org.elasticsearch.xcontent.XContentBuilder;
 import org.elasticsearch.xcontent.XContentFactory;
 import org.elasticsearch.xpack.core.watcher.history.HistoryStoreField;
@@ -91,10 +93,11 @@ public class HistoryStore {
      * @param state The current cluster state
      * @return true, if history store is ready to be started
      */
+    @NotMultiProjectCapable(description = "Watcher is not available in serverless")
     public static boolean validate(ClusterState state) {
         IndexMetadata indexMetadata = WatchStoreUtils.getConcreteIndex(HistoryStoreField.DATA_STREAM, state.metadata());
         return indexMetadata == null
             || (indexMetadata.getState() == IndexMetadata.State.OPEN
-                && state.routingTable().index(indexMetadata.getIndex()).allPrimaryShardsActive());
+                && state.routingTable(ProjectId.DEFAULT).index(indexMetadata.getIndex()).allPrimaryShardsActive());
     }
 }

+ 4 - 1
x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistry.java

@@ -9,8 +9,10 @@ package org.elasticsearch.xpack.watcher.support;
 import org.elasticsearch.client.internal.Client;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.metadata.ComposableIndexTemplate;
+import org.elasticsearch.cluster.metadata.ProjectId;
 import org.elasticsearch.cluster.service.ClusterService;
 import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.core.NotMultiProjectCapable;
 import org.elasticsearch.threadpool.ThreadPool;
 import org.elasticsearch.xcontent.NamedXContentRegistry;
 import org.elasticsearch.xpack.core.ilm.LifecyclePolicy;
@@ -89,9 +91,10 @@ public class WatcherIndexTemplateRegistry extends IndexTemplateRegistry {
         return WATCHER_ORIGIN;
     }
 
+    @NotMultiProjectCapable(description = "Watcher is not available in serverless")
     public static boolean validate(ClusterState state) {
         return state.getMetadata()
-            .getProject()
+            .getProject(ProjectId.DEFAULT)
             .templatesV2()
             .keySet()
             .stream()

+ 7 - 2
x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/watch/WatchStoreUtils.java

@@ -9,6 +9,9 @@ package org.elasticsearch.xpack.watcher.watch;
 import org.elasticsearch.cluster.metadata.IndexAbstraction;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.metadata.Metadata;
+import org.elasticsearch.cluster.metadata.ProjectId;
+import org.elasticsearch.cluster.metadata.ProjectMetadata;
+import org.elasticsearch.core.NotMultiProjectCapable;
 import org.elasticsearch.index.Index;
 import org.elasticsearch.index.IndexNotFoundException;
 
@@ -26,7 +29,9 @@ public class WatchStoreUtils {
      * @throws IndexNotFoundException If no index exists
      */
     public static IndexMetadata getConcreteIndex(String name, Metadata metadata) {
-        IndexAbstraction indexAbstraction = metadata.getProject().getIndicesLookup().get(name);
+        @NotMultiProjectCapable(description = "Watcher is not available in serverless")
+        ProjectMetadata projectMetadata = metadata.getProject(ProjectId.DEFAULT);
+        IndexAbstraction indexAbstraction = projectMetadata.getIndicesLookup().get(name);
         if (indexAbstraction == null) {
             return null;
         }
@@ -48,7 +53,7 @@ public class WatchStoreUtils {
         if (concreteIndex == null) {
             concreteIndex = indexAbstraction.getIndices().get(indexAbstraction.getIndices().size() - 1);
         }
-        return metadata.getProject().index(concreteIndex);
+        return projectMetadata.index(concreteIndex);
     }
 
 }

+ 32 - 22
x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherIndexingListenerTests.java

@@ -16,6 +16,7 @@ import org.elasticsearch.cluster.metadata.AliasMetadata;
 import org.elasticsearch.cluster.metadata.IndexAbstraction;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.metadata.Metadata;
+import org.elasticsearch.cluster.metadata.ProjectId;
 import org.elasticsearch.cluster.metadata.ProjectMetadata;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.node.DiscoveryNodeRole;
@@ -30,6 +31,7 @@ import org.elasticsearch.cluster.routing.ShardRoutingState;
 import org.elasticsearch.cluster.routing.TestShardRouting;
 import org.elasticsearch.common.bytes.BytesArray;
 import org.elasticsearch.common.time.DateUtils;
+import org.elasticsearch.core.NotMultiProjectCapable;
 import org.elasticsearch.core.Strings;
 import org.elasticsearch.index.Index;
 import org.elasticsearch.index.IndexVersion;
@@ -87,6 +89,8 @@ public class WatcherIndexingListenerTests extends ESTestCase {
     private Engine.IndexResult result = mock(Engine.IndexResult.class);
     private Engine.Index operation = mock(Engine.Index.class);
     private Engine.Delete delete = mock(Engine.Delete.class);
+    @NotMultiProjectCapable(description = "Watcher is not available in serverless")
+    private final ProjectId projectId = ProjectId.DEFAULT;
 
     @Before
     public void setup() throws Exception {
@@ -324,7 +328,7 @@ public class WatcherIndexingListenerTests extends ESTestCase {
         when(routingTable.hasIndex(eq(newActiveWatchIndex))).thenReturn(true);
 
         ClusterState currentClusterState = mockClusterState(newActiveWatchIndex);
-        when(currentClusterState.routingTable()).thenReturn(routingTable);
+        when(currentClusterState.routingTable(projectId)).thenReturn(routingTable);
         DiscoveryNodes nodes = DiscoveryNodes.builder().add(newNode("node_1")).localNodeId("node_1").build();
         when(currentClusterState.getNodes()).thenReturn(nodes);
         RoutingNodes routingNodes = mock(RoutingNodes.class);
@@ -347,7 +351,7 @@ public class WatcherIndexingListenerTests extends ESTestCase {
         when(currentClusterState.getRoutingNodes()).thenReturn(routingNodes);
 
         ClusterState previousClusterState = mockClusterState(randomAlphaOfLength(8));
-        when(previousClusterState.routingTable()).thenReturn(routingTable);
+        when(previousClusterState.routingTable(projectId)).thenReturn(routingTable);
 
         ClusterChangedEvent event = new ClusterChangedEvent("something", currentClusterState, previousClusterState);
         listener.clusterChanged(event);
@@ -364,12 +368,12 @@ public class WatcherIndexingListenerTests extends ESTestCase {
         IndexRoutingTable watchRoutingTable = IndexRoutingTable.builder(index).build();
         ClusterState previousState = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(newNode("node_1")))
-            .routingTable(RoutingTable.builder().add(watchRoutingTable).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(watchRoutingTable).build())
             .build();
 
         ClusterState currentState = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(newNode("node_1")).add(newNode("node_2")))
-            .routingTable(RoutingTable.builder().add(watchRoutingTable).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(watchRoutingTable).build())
             .build();
 
         Configuration configuration = listener.getConfiguration();
@@ -492,9 +496,9 @@ public class WatcherIndexingListenerTests extends ESTestCase {
         IndexMetadata.Builder indexMetadataBuilder = createIndexBuilder(Watch.INDEX, 1, 0);
 
         ClusterState previousState = ClusterState.builder(new ClusterName("my-cluster"))
-            .metadata(Metadata.builder().put(indexMetadataBuilder))
+            .putProjectMetadata(ProjectMetadata.builder(projectId).put(indexMetadataBuilder))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(node1).add(node2).add(node3))
-            .routingTable(RoutingTable.builder().add(indexRoutingTable).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(indexRoutingTable).build())
             .build();
 
         IndexMetadata.Builder newIndexMetadataBuilder = createIndexBuilder(Watch.INDEX, 1, 1);
@@ -502,9 +506,9 @@ public class WatcherIndexingListenerTests extends ESTestCase {
         ShardRouting replicaShardRouting = TestShardRouting.newShardRouting(shardId, "node3", false, STARTED);
         IndexRoutingTable.Builder newRoutingTable = IndexRoutingTable.builder(index).addShard(shardRouting).addShard(replicaShardRouting);
         ClusterState currentState = ClusterState.builder(new ClusterName("my-cluster"))
-            .metadata(Metadata.builder().put(newIndexMetadataBuilder))
+            .putProjectMetadata(ProjectMetadata.builder(projectId).put(newIndexMetadataBuilder))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(node1).add(node2).add(node3))
-            .routingTable(RoutingTable.builder().add(newRoutingTable).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(newRoutingTable).build())
             .build();
 
         ClusterChangedEvent event = new ClusterChangedEvent("something", currentState, previousState);
@@ -526,9 +530,9 @@ public class WatcherIndexingListenerTests extends ESTestCase {
             .addShard(TestShardRouting.newShardRouting(firstShardId, "node_2", false, STARTED));
 
         ClusterState previousState = ClusterState.builder(new ClusterName("my-cluster"))
-            .metadata(Metadata.builder().put(indexMetadataBuilder))
+            .putProjectMetadata(ProjectMetadata.builder(projectId).put(indexMetadataBuilder))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(node1).add(node2))
-            .routingTable(RoutingTable.builder().add(indexRoutingTable).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(indexRoutingTable).build())
             .build();
 
         IndexMetadata.Builder currentMetadataBuilder = createIndexBuilder(Watch.INDEX, 2, 1);
@@ -543,9 +547,9 @@ public class WatcherIndexingListenerTests extends ESTestCase {
             .addShard(TestShardRouting.newShardRouting(watchShardId, "node_2", false, STARTED));
 
         ClusterState currentState = ClusterState.builder(new ClusterName("my-cluster"))
-            .metadata(Metadata.builder().put(currentMetadataBuilder))
+            .putProjectMetadata(ProjectMetadata.builder(projectId).put(currentMetadataBuilder))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(node1).add(node2))
-            .routingTable(RoutingTable.builder().add(currentRoutingTable).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(currentRoutingTable).build())
             .build();
 
         listener.setConfiguration(INACTIVE);
@@ -588,9 +592,9 @@ public class WatcherIndexingListenerTests extends ESTestCase {
             .addShard(secondShardRoutingReplica);
 
         ClusterState previousState = ClusterState.builder(new ClusterName("my-cluster"))
-            .metadata(Metadata.builder().put(indexMetadataBuilder))
+            .putProjectMetadata(ProjectMetadata.builder(projectId).put(indexMetadataBuilder))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId(localNode).add(node1).add(node2).add(node3).add(node4))
-            .routingTable(RoutingTable.builder().add(indexRoutingTable).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(indexRoutingTable).build())
             .build();
 
         ClusterState emptyState = ClusterState.builder(new ClusterName("my-cluster"))
@@ -611,9 +615,9 @@ public class WatcherIndexingListenerTests extends ESTestCase {
             .addShard(secondShardRoutingPrimary);
 
         ClusterState currentState = ClusterState.builder(new ClusterName("my-cluster"))
-            .metadata(Metadata.builder().put(newIndexMetadataBuilder))
+            .putProjectMetadata(ProjectMetadata.builder(projectId).put(newIndexMetadataBuilder))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId(localNode).add(node1).add(node2).add(node3).add(node4))
-            .routingTable(RoutingTable.builder().add(newRoutingTable).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(newRoutingTable).build())
             .build();
 
         ClusterChangedEvent nodeGoneEvent = new ClusterChangedEvent("something", currentState, previousState);
@@ -636,9 +640,11 @@ public class WatcherIndexingListenerTests extends ESTestCase {
 
         // regular cluster state with correct single alias pointing to watches index
         ClusterState previousState = ClusterState.builder(new ClusterName("my-cluster"))
-            .metadata(Metadata.builder().put(createIndexBuilder("foo", 1, 0).putAlias(AliasMetadata.builder(Watch.INDEX))))
+            .putProjectMetadata(
+                ProjectMetadata.builder(projectId).put(createIndexBuilder("foo", 1, 0).putAlias(AliasMetadata.builder(Watch.INDEX)))
+            )
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(node1))
-            .routingTable(RoutingTable.builder().add(fooIndexRoutingTable).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(fooIndexRoutingTable).build())
             .build();
 
         // index bar pointing to .watches
@@ -650,11 +656,15 @@ public class WatcherIndexingListenerTests extends ESTestCase {
 
         // cluster state with two indices pointing to the .watches index
         ClusterState currentState = ClusterState.builder(new ClusterName("my-cluster"))
-            .metadata(
-                Metadata.builder().put(createIndexBuilder("foo", 1, 0).putAlias(AliasMetadata.builder(Watch.INDEX))).put(barIndexMetadata)
+            .putProjectMetadata(
+                ProjectMetadata.builder(projectId)
+                    .put(createIndexBuilder("foo", 1, 0).putAlias(AliasMetadata.builder(Watch.INDEX)))
+                    .put(barIndexMetadata)
+                    .build()
             )
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(node1))
-            .routingTable(
+            .putRoutingTable(
+                projectId,
                 RoutingTable.builder().add(IndexRoutingTable.builder(fooIndex).addShard(fooShardRouting)).add(barIndexRoutingTable).build()
             )
             .build();
@@ -699,7 +709,7 @@ public class WatcherIndexingListenerTests extends ESTestCase {
     private ClusterState mockClusterState(String watchIndex) {
         Metadata metadata = mock(Metadata.class);
         ProjectMetadata projectMetadata = mock(ProjectMetadata.class);
-        when(metadata.getProject()).thenReturn(projectMetadata);
+        when(metadata.getProject(projectId)).thenReturn(projectMetadata);
         if (watchIndex == null) {
             when(projectMetadata.getIndicesLookup()).thenReturn(Collections.emptySortedMap());
         } else {

+ 60 - 50
x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherLifeCycleServiceTests.java

@@ -16,7 +16,7 @@ import org.elasticsearch.cluster.block.ClusterBlocks;
 import org.elasticsearch.cluster.coordination.NoMasterBlockService;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.metadata.IndexTemplateMetadata;
-import org.elasticsearch.cluster.metadata.Metadata;
+import org.elasticsearch.cluster.metadata.ProjectId;
 import org.elasticsearch.cluster.metadata.ProjectMetadata;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.node.DiscoveryNodeRole;
@@ -29,6 +29,7 @@ import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.routing.ShardRoutingState;
 import org.elasticsearch.cluster.routing.TestShardRouting;
 import org.elasticsearch.cluster.service.ClusterService;
+import org.elasticsearch.core.NotMultiProjectCapable;
 import org.elasticsearch.gateway.GatewayService;
 import org.elasticsearch.index.Index;
 import org.elasticsearch.index.IndexVersion;
@@ -73,6 +74,8 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
 
     private WatcherService watcherService;
     private WatcherLifeCycleService lifeCycleService;
+    @NotMultiProjectCapable(description = "Watcher is not available in serverless")
+    private ProjectId projectId = ProjectId.DEFAULT;
 
     @Before
     public void prepareServices() {
@@ -91,14 +94,18 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
         IndexRoutingTable indexRoutingTable = IndexRoutingTable.builder(new Index("anything", "foo")).build();
         ClusterState previousClusterState = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(newNode("node_1")))
-            .routingTable(RoutingTable.builder().add(indexRoutingTable).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(indexRoutingTable).build())
             .build();
 
         IndexRoutingTable watchRoutingTable = IndexRoutingTable.builder(new Index(Watch.INDEX, "foo")).build();
         ClusterState clusterState = ClusterState.builder(new ClusterName("my-cluster"))
-            .metadata(Metadata.builder().put(IndexTemplateMetadata.builder(HISTORY_TEMPLATE_NAME).patterns(randomIndexPatterns())).build())
+            .putProjectMetadata(
+                ProjectMetadata.builder(projectId)
+                    .put(IndexTemplateMetadata.builder(HISTORY_TEMPLATE_NAME).patterns(randomIndexPatterns()))
+                    .build()
+            )
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(newNode("node_1")))
-            .routingTable(RoutingTable.builder().add(watchRoutingTable).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(watchRoutingTable).build())
             .build();
 
         when(watcherService.validate(clusterState)).thenReturn(true);
@@ -126,8 +133,12 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
         IndexRoutingTable watchRoutingTable = IndexRoutingTable.builder(new Index(Watch.INDEX, "foo")).build();
         ClusterState clusterState = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(newNode("node_1")))
-            .routingTable(RoutingTable.builder().add(watchRoutingTable).build())
-            .metadata(Metadata.builder().put(IndexTemplateMetadata.builder(HISTORY_TEMPLATE_NAME).patterns(randomIndexPatterns())).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(watchRoutingTable).build())
+            .putProjectMetadata(
+                ProjectMetadata.builder(projectId)
+                    .put(IndexTemplateMetadata.builder(HISTORY_TEMPLATE_NAME).patterns(randomIndexPatterns()))
+                    .build()
+            )
             .build();
 
         when(watcherService.validate(clusterState)).thenReturn(true);
@@ -152,18 +163,18 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
                                                                                                             // required
             .numberOfShards(1)
             .numberOfReplicas(0);
-        Metadata.Builder metadataBuilder = Metadata.builder()
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId)
             .put(indexMetadataBuilder)
             .put(IndexTemplateMetadata.builder(HISTORY_TEMPLATE_NAME).patterns(randomIndexPatterns()));
         if (randomBoolean()) {
             metadataBuilder.putCustom(WatcherMetadata.TYPE, new WatcherMetadata(false));
         }
-        Metadata metadata = metadataBuilder.build();
+        ProjectMetadata metadata = metadataBuilder.build();
         IndexRoutingTable indexRoutingTable = indexRoutingTableBuilder.build();
         ClusterState clusterState = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(newNode("node_1")))
-            .routingTable(RoutingTable.builder().add(indexRoutingTable).build())
-            .metadata(metadata)
+            .putRoutingTable(projectId, RoutingTable.builder().add(indexRoutingTable).build())
+            .putProjectMetadata(metadata)
             .build();
 
         when(watcherService.validate(clusterState)).thenReturn(true);
@@ -171,8 +182,8 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
         // mark watcher manually as stopped
         ClusterState stoppedClusterState = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(newNode("node_1")))
-            .routingTable(RoutingTable.builder().add(indexRoutingTable).build())
-            .metadata(Metadata.builder(metadata).putCustom(WatcherMetadata.TYPE, new WatcherMetadata(true)).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(indexRoutingTable).build())
+            .putProjectMetadata(ProjectMetadata.builder(metadata).putCustom(WatcherMetadata.TYPE, new WatcherMetadata(true)).build())
             .build();
 
         lifeCycleService.clusterChanged(new ClusterChangedEvent("foo", stoppedClusterState, clusterState));
@@ -210,25 +221,25 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
                                                                                                             // required
             .numberOfShards(1)
             .numberOfReplicas(0);
-        Metadata.Builder metadataBuilder = Metadata.builder()
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId)
             .put(indexMetadataBuilder)
             .put(IndexTemplateMetadata.builder(HISTORY_TEMPLATE_NAME).patterns(randomIndexPatterns()));
         if (randomBoolean()) {
             metadataBuilder.putCustom(WatcherMetadata.TYPE, new WatcherMetadata(false));
         }
-        Metadata metadata = metadataBuilder.build();
+        ProjectMetadata metadata = metadataBuilder.build();
         IndexRoutingTable indexRoutingTable = indexRoutingTableBuilder.build();
         ClusterState clusterState = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(newNode("node_1")))
-            .routingTable(RoutingTable.builder().add(indexRoutingTable).build())
-            .metadata(metadata)
+            .putRoutingTable(projectId, RoutingTable.builder().add(indexRoutingTable).build())
+            .putProjectMetadata(metadata)
             .build();
 
         // mark watcher manually as stopped
         ClusterState stoppedClusterState = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(newNode("node_1")))
-            .routingTable(RoutingTable.builder().add(indexRoutingTable).build())
-            .metadata(Metadata.builder(metadata).putCustom(WatcherMetadata.TYPE, new WatcherMetadata(true)).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(indexRoutingTable).build())
+            .putProjectMetadata(ProjectMetadata.builder(metadata).putCustom(WatcherMetadata.TYPE, new WatcherMetadata(true)).build())
             .build();
 
         lifeCycleService.clusterChanged(new ClusterChangedEvent("foo", stoppedClusterState, clusterState));
@@ -323,23 +334,22 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
             // required
             .numberOfShards(1)
             .numberOfReplicas(0);
-        Metadata metadata = Metadata.builder()
+        ProjectMetadata metadata = ProjectMetadata.builder(projectId)
             .put(IndexTemplateMetadata.builder(HISTORY_TEMPLATE_NAME).patterns(randomIndexPatterns()))
             .put(indexMetadataBuilder)
             .build();
-        ProjectMetadata project = metadata.projects().values().iterator().next();
 
-        GlobalRoutingTable globalRoutingTable = GlobalRoutingTable.builder().put(project.id(), routingTable).build();
+        GlobalRoutingTable globalRoutingTable = GlobalRoutingTable.builder().put(metadata.id(), routingTable).build();
 
-        ClusterState emptyState = ClusterState.builder(new ClusterName("my-cluster")).nodes(nodes).metadata(metadata).build();
+        ClusterState emptyState = ClusterState.builder(new ClusterName("my-cluster")).nodes(nodes).putProjectMetadata(metadata).build();
         ClusterState stateWithMasterNode1 = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(nodes.withMasterNodeId("node_1"))
-            .metadata(metadata)
+            .putProjectMetadata(metadata)
             .routingTable(globalRoutingTable)
             .build();
         ClusterState stateWithMasterNode2 = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(nodes.withMasterNodeId("node_2"))
-            .metadata(metadata)
+            .putProjectMetadata(metadata)
             .routingTable(globalRoutingTable)
             .build();
 
@@ -369,8 +379,8 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
             .build();
         ClusterState clusterStateWithLocalShards = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(nodes)
-            .routingTable(RoutingTable.builder().add(watchRoutingTable).build())
-            .metadata(Metadata.builder().put(indexMetadata, false))
+            .putRoutingTable(projectId, RoutingTable.builder().add(watchRoutingTable).build())
+            .putProjectMetadata(ProjectMetadata.builder(projectId).put(indexMetadata, false))
             .build();
 
         // shard moved over to node 2
@@ -383,8 +393,8 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
             .build();
         ClusterState clusterStateWithoutLocalShards = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(nodes)
-            .routingTable(RoutingTable.builder().add(watchRoutingTableNode2).build())
-            .metadata(Metadata.builder().put(indexMetadata, false))
+            .putRoutingTable(projectId, RoutingTable.builder().add(watchRoutingTableNode2).build())
+            .putProjectMetadata(ProjectMetadata.builder(projectId).put(indexMetadata, false))
             .build();
 
         // set current allocation ids
@@ -431,8 +441,8 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
 
         ClusterState stateWithPrimaryShard = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(discoveryNodes)
-            .routingTable(RoutingTable.builder().add(previousWatchRoutingTable).build())
-            .metadata(Metadata.builder().put(indexMetadata, false))
+            .putRoutingTable(projectId, RoutingTable.builder().add(previousWatchRoutingTable).build())
+            .putProjectMetadata(ProjectMetadata.builder(projectId).put(indexMetadata, false))
             .build();
 
         // add a replica in the local node
@@ -452,8 +462,8 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
 
         ClusterState stateWithReplicaAdded = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(discoveryNodes)
-            .routingTable(RoutingTable.builder().add(currentWatchRoutingTable).build())
-            .metadata(Metadata.builder().put(indexMetadata, false))
+            .putRoutingTable(projectId, RoutingTable.builder().add(currentWatchRoutingTable).build())
+            .putProjectMetadata(ProjectMetadata.builder(projectId).put(indexMetadata, false))
             .build();
 
         // randomize between addition or removal of a replica
@@ -497,9 +507,9 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
             .settings(indexSettings(IndexVersion.current(), 1, 0));
 
         ClusterState previousState = ClusterState.builder(new ClusterName("my-cluster"))
-            .metadata(Metadata.builder().put(indexMetadataBuilder))
+            .putProjectMetadata(ProjectMetadata.builder(projectId).put(indexMetadataBuilder))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(node1).add(node2).add(node3))
-            .routingTable(RoutingTable.builder().add(indexRoutingTable).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(indexRoutingTable).build())
             .build();
 
         IndexMetadata.Builder newIndexMetadataBuilder = IndexMetadata.builder(Watch.INDEX)
@@ -508,9 +518,9 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
         ShardRouting replicaShardRouting = TestShardRouting.newShardRouting(shardId, "node3", false, STARTED);
         IndexRoutingTable.Builder newRoutingTable = IndexRoutingTable.builder(index).addShard(shardRouting).addShard(replicaShardRouting);
         ClusterState currentState = ClusterState.builder(new ClusterName("my-cluster"))
-            .metadata(Metadata.builder().put(newIndexMetadataBuilder))
+            .putProjectMetadata(ProjectMetadata.builder(projectId).put(newIndexMetadataBuilder))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(node1).add(node2).add(node3))
-            .routingTable(RoutingTable.builder().add(newRoutingTable).build())
+            .putRoutingTable(projectId, RoutingTable.builder().add(newRoutingTable).build())
             .build();
 
         lifeCycleService.clusterChanged(new ClusterChangedEvent("any", currentState, previousState));
@@ -531,8 +541,8 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
 
         ClusterState clusterStateWithWatcherIndex = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(nodes)
-            .routingTable(RoutingTable.builder().add(watchRoutingTable).build())
-            .metadata(Metadata.builder().put(newIndexMetadataBuilder))
+            .putRoutingTable(projectId, RoutingTable.builder().add(watchRoutingTable).build())
+            .putProjectMetadata(ProjectMetadata.builder(projectId).put(newIndexMetadataBuilder))
             .build();
 
         ClusterState clusterStateWithoutWatcherIndex = ClusterState.builder(new ClusterName("my-cluster")).nodes(nodes).build();
@@ -556,12 +566,12 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
     public void testWatcherServiceDoesNotStartIfIndexTemplatesAreMissing() throws Exception {
         DiscoveryNodes nodes = new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(newNode("node_1")).build();
 
-        Metadata.Builder metadataBuilder = Metadata.builder();
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId);
         boolean isHistoryTemplateAdded = randomBoolean();
         if (isHistoryTemplateAdded) {
             metadataBuilder.put(IndexTemplateMetadata.builder(HISTORY_TEMPLATE_NAME).patterns(randomIndexPatterns()));
         }
-        ClusterState state = ClusterState.builder(new ClusterName("my-cluster")).nodes(nodes).metadata(metadataBuilder).build();
+        ClusterState state = ClusterState.builder(new ClusterName("my-cluster")).nodes(nodes).putProjectMetadata(metadataBuilder).build();
         when(watcherService.validate(eq(state))).thenReturn(true);
 
         lifeCycleService.clusterChanged(new ClusterChangedEvent("any", state, state));
@@ -602,12 +612,12 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
     }
 
     public void testDataNodeWithoutDataCanStart() {
-        Metadata metadata = Metadata.builder()
+        ProjectMetadata metadata = ProjectMetadata.builder(projectId)
             .put(IndexTemplateMetadata.builder(HISTORY_TEMPLATE_NAME).patterns(randomIndexPatterns()))
             .build();
         ClusterState state = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(newNode("node_1")))
-            .metadata(metadata)
+            .putProjectMetadata(metadata)
             .build();
 
         lifeCycleService.clusterChanged(new ClusterChangedEvent("test", state, state));
@@ -641,8 +651,8 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
 
         ClusterState previousState = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(previousDiscoveryNodes)
-            .routingTable(RoutingTable.builder().add(previousWatchRoutingTable).build())
-            .metadata(Metadata.builder().put(indexMetadata, false))
+            .putRoutingTable(projectId, RoutingTable.builder().add(previousWatchRoutingTable).build())
+            .putProjectMetadata(ProjectMetadata.builder(projectId).put(indexMetadata, false))
             .build();
 
         ShardRouting nowPrimaryShardRouting = replicaShardRouting.moveActiveReplicaToPrimary();
@@ -655,8 +665,8 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
 
         ClusterState currentState = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(currentDiscoveryNodes)
-            .routingTable(RoutingTable.builder().add(currentWatchRoutingTable).build())
-            .metadata(Metadata.builder().put(indexMetadata, false))
+            .putRoutingTable(projectId, RoutingTable.builder().add(currentWatchRoutingTable).build())
+            .putProjectMetadata(ProjectMetadata.builder(projectId).put(indexMetadata, false))
             .build();
 
         // initialize the previous state, so all the allocation ids are loaded
@@ -681,18 +691,18 @@ public class WatcherLifeCycleServiceTests extends ESTestCase {
                                                                                                             // required
             .numberOfShards(1)
             .numberOfReplicas(0);
-        Metadata metadata = Metadata.builder()
+        ProjectMetadata metadata = ProjectMetadata.builder(projectId)
             .put(IndexTemplateMetadata.builder(HISTORY_TEMPLATE_NAME).patterns(randomIndexPatterns()))
             .put(indexMetadataBuilder)
             .build();
         ClusterState state = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(newNode("node_1")))
-            .routingTable(RoutingTable.builder().add(indexRoutingTableBuilder.build()).build())
-            .metadata(metadata)
+            .putRoutingTable(projectId, RoutingTable.builder().add(indexRoutingTableBuilder.build()).build())
+            .putProjectMetadata(metadata)
             .build();
         ClusterState emptyState = ClusterState.builder(new ClusterName("my-cluster"))
             .nodes(new DiscoveryNodes.Builder().masterNodeId("node_1").localNodeId("node_1").add(newNode("node_1")))
-            .metadata(metadata)
+            .putProjectMetadata(metadata)
             .build();
 
         when(watcherService.validate(state)).thenReturn(true);

+ 13 - 9
x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherServiceTests.java

@@ -26,6 +26,7 @@ import org.elasticsearch.cluster.ClusterName;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.metadata.Metadata;
+import org.elasticsearch.cluster.metadata.ProjectId;
 import org.elasticsearch.cluster.metadata.ProjectMetadata;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
@@ -38,6 +39,7 @@ import org.elasticsearch.cluster.routing.TestShardRouting;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.util.concurrent.EsExecutors;
 import org.elasticsearch.common.util.concurrent.ThreadContext;
+import org.elasticsearch.core.NotMultiProjectCapable;
 import org.elasticsearch.index.Index;
 import org.elasticsearch.index.IndexVersion;
 import org.elasticsearch.index.shard.ShardId;
@@ -84,6 +86,8 @@ import static org.mockito.Mockito.when;
 public class WatcherServiceTests extends ESTestCase {
 
     private final Client client = mock(Client.class);
+    @NotMultiProjectCapable(description = "Watcher is not available in serverless")
+    private final ProjectId projectId = ProjectId.DEFAULT;
 
     @Before
     public void configureMockClient() {
@@ -113,10 +117,10 @@ public class WatcherServiceTests extends ESTestCase {
         };
 
         ClusterState.Builder csBuilder = new ClusterState.Builder(new ClusterName("_name"));
-        Metadata.Builder metadataBuilder = Metadata.builder();
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId);
         Settings indexSettings = indexSettings(IndexVersion.current(), 1, 1).build();
         metadataBuilder.put(IndexMetadata.builder(Watch.INDEX).state(IndexMetadata.State.CLOSE).settings(indexSettings));
-        csBuilder.metadata(metadataBuilder);
+        csBuilder.putProjectMetadata(metadataBuilder);
 
         assertThat(service.validate(csBuilder.build()), is(false));
     }
@@ -142,10 +146,10 @@ public class WatcherServiceTests extends ESTestCase {
 
         // cluster state setup, with one node, one shard
         ClusterState.Builder csBuilder = new ClusterState.Builder(new ClusterName("_name"));
-        Metadata.Builder metadataBuilder = Metadata.builder();
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId);
         Settings indexSettings = indexSettings(IndexVersion.current(), 1, 1).build();
         metadataBuilder.put(IndexMetadata.builder(Watch.INDEX).settings(indexSettings));
-        csBuilder.metadata(metadataBuilder);
+        csBuilder.putProjectMetadata(metadataBuilder);
 
         Index watchIndex = new Index(Watch.INDEX, "uuid");
         ShardId shardId = new ShardId(watchIndex, 0);
@@ -157,7 +161,7 @@ public class WatcherServiceTests extends ESTestCase {
             )
             .build();
         RoutingTable routingTable = RoutingTable.builder().add(indexRoutingTable).build();
-        csBuilder.routingTable(routingTable);
+        csBuilder.putRoutingTable(projectId, routingTable);
 
         csBuilder.nodes(new DiscoveryNodes.Builder().masterNodeId("node").localNodeId("node").add(newNode()));
         ClusterState clusterState = csBuilder.build();
@@ -165,7 +169,7 @@ public class WatcherServiceTests extends ESTestCase {
         // response setup, successful refresh response
         BroadcastResponse refreshResponse = mock(BroadcastResponse.class);
         when(refreshResponse.getSuccessfulShards()).thenReturn(
-            clusterState.getMetadata().getProject().indices().get(Watch.INDEX).getNumberOfShards()
+            clusterState.getMetadata().getProject(ProjectId.DEFAULT).indices().get(Watch.INDEX).getNumberOfShards()
         );
         doAnswer(invocation -> {
             ActionListener<BroadcastResponse> listener = (ActionListener<BroadcastResponse>) invocation.getArguments()[2];
@@ -261,10 +265,10 @@ public class WatcherServiceTests extends ESTestCase {
         };
 
         ClusterState.Builder csBuilder = new ClusterState.Builder(new ClusterName("_name"));
-        Metadata.Builder metadataBuilder = Metadata.builder();
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId);
         Settings indexSettings = indexSettings(IndexVersion.current(), 1, 1).build();
         metadataBuilder.put(IndexMetadata.builder(Watch.INDEX).settings(indexSettings));
-        csBuilder.metadata(metadataBuilder);
+        csBuilder.putProjectMetadata(metadataBuilder);
         ClusterState clusterState = csBuilder.build();
 
         AtomicReference<Exception> exceptionReference = new AtomicReference<>();
@@ -358,7 +362,7 @@ public class WatcherServiceTests extends ESTestCase {
         ClusterState.Builder csBuilder = new ClusterState.Builder(new ClusterName("_name"));
         Metadata metadata = mock(Metadata.class);
         ProjectMetadata project = mock(ProjectMetadata.class);
-        when(metadata.getProject()).thenReturn(project);
+        when(metadata.getProject(projectId)).thenReturn(project);
         // simulate exception in WatcherService's private loadWatches()
         when(project.getIndicesLookup()).thenThrow(RuntimeException.class);
 

+ 21 - 17
x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/execution/TriggeredWatchStoreTests.java

@@ -29,7 +29,8 @@ import org.elasticsearch.cluster.ClusterName;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.metadata.AliasMetadata;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
-import org.elasticsearch.cluster.metadata.Metadata;
+import org.elasticsearch.cluster.metadata.ProjectId;
+import org.elasticsearch.cluster.metadata.ProjectMetadata;
 import org.elasticsearch.cluster.routing.IndexRoutingTable;
 import org.elasticsearch.cluster.routing.IndexShardRoutingTable;
 import org.elasticsearch.cluster.routing.RoutingTable;
@@ -40,6 +41,7 @@ import org.elasticsearch.common.bytes.BytesArray;
 import org.elasticsearch.common.bytes.BytesReference;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.util.concurrent.ThreadContext;
+import org.elasticsearch.core.NotMultiProjectCapable;
 import org.elasticsearch.index.Index;
 import org.elasticsearch.index.IndexNotFoundException;
 import org.elasticsearch.index.IndexVersion;
@@ -114,6 +116,8 @@ public class TriggeredWatchStoreTests extends ESTestCase {
             throw new ElasticsearchException(failure);
         }
     };
+    @NotMultiProjectCapable(description = "Watcher is not available in serverless")
+    private final ProjectId projectId = ProjectId.DEFAULT;
 
     @Before
     public void init() {
@@ -143,7 +147,7 @@ public class TriggeredWatchStoreTests extends ESTestCase {
         ClusterState.Builder csBuilder = new ClusterState.Builder(new ClusterName("name"));
 
         RoutingTable.Builder routingTableBuilder = RoutingTable.builder();
-        Metadata.Builder metadataBuilder = Metadata.builder();
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId);
 
         int numShards = 2 + randomInt(2);
         int numStartedShards = 1;
@@ -173,8 +177,8 @@ public class TriggeredWatchStoreTests extends ESTestCase {
         }
         routingTableBuilder.add(indexRoutingTableBuilder.build());
 
-        csBuilder.metadata(metadataBuilder);
-        csBuilder.routingTable(routingTableBuilder.build());
+        csBuilder.putProjectMetadata(metadataBuilder);
+        csBuilder.putRoutingTable(projectId, routingTableBuilder.build());
         ClusterState cs = csBuilder.build();
 
         assertThat(TriggeredWatchStore.validate(cs), is(false));
@@ -184,7 +188,7 @@ public class TriggeredWatchStoreTests extends ESTestCase {
         ClusterState.Builder csBuilder = new ClusterState.Builder(new ClusterName("_name"));
 
         RoutingTable.Builder routingTableBuilder = RoutingTable.builder();
-        Metadata.Builder metadataBuilder = Metadata.builder();
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId);
         metadataBuilder.put(IndexMetadata.builder(TriggeredWatchStoreField.INDEX_NAME).settings(indexSettings));
         final Index index = metadataBuilder.get(TriggeredWatchStoreField.INDEX_NAME).getIndex();
         IndexRoutingTable.Builder indexRoutingTableBuilder = IndexRoutingTable.builder(index);
@@ -196,8 +200,8 @@ public class TriggeredWatchStoreTests extends ESTestCase {
         );
         indexRoutingTableBuilder.addReplica(ShardRouting.Role.DEFAULT);
         routingTableBuilder.add(indexRoutingTableBuilder.build());
-        csBuilder.metadata(metadataBuilder);
-        csBuilder.routingTable(routingTableBuilder.build());
+        csBuilder.putProjectMetadata(metadataBuilder);
+        csBuilder.putRoutingTable(projectId, routingTableBuilder.build());
         ClusterState cs = csBuilder.build();
 
         doAnswer(invocation -> {
@@ -298,7 +302,7 @@ public class TriggeredWatchStoreTests extends ESTestCase {
         ClusterState.Builder csBuilder = new ClusterState.Builder(new ClusterName("_name"));
 
         RoutingTable.Builder routingTableBuilder = RoutingTable.builder();
-        Metadata.Builder metadataBuilder = Metadata.builder();
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId);
         metadataBuilder.put(
             IndexMetadata.builder("triggered-watches-alias")
                 .settings(indexSettings)
@@ -314,8 +318,8 @@ public class TriggeredWatchStoreTests extends ESTestCase {
         );
         indexRoutingTableBuilder.addReplica(ShardRouting.Role.DEFAULT);
         routingTableBuilder.add(indexRoutingTableBuilder.build());
-        csBuilder.metadata(metadataBuilder);
-        csBuilder.routingTable(routingTableBuilder.build());
+        csBuilder.putProjectMetadata(metadataBuilder);
+        csBuilder.putRoutingTable(projectId, routingTableBuilder.build());
         ClusterState cs = csBuilder.build();
 
         assertThat(TriggeredWatchStore.validate(cs), is(true));
@@ -326,7 +330,7 @@ public class TriggeredWatchStoreTests extends ESTestCase {
     public void testLoadingFailsWithTwoAliases() {
         ClusterState.Builder csBuilder = new ClusterState.Builder(new ClusterName("_name"));
 
-        Metadata.Builder metadataBuilder = Metadata.builder();
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId);
         RoutingTable.Builder routingTableBuilder = RoutingTable.builder();
         metadataBuilder.put(
             IndexMetadata.builder("triggered-watches-alias")
@@ -355,8 +359,8 @@ public class TriggeredWatchStoreTests extends ESTestCase {
             )
         );
 
-        csBuilder.metadata(metadataBuilder);
-        csBuilder.routingTable(routingTableBuilder.build());
+        csBuilder.putProjectMetadata(metadataBuilder);
+        csBuilder.putRoutingTable(projectId, routingTableBuilder.build());
         ClusterState cs = csBuilder.build();
 
         IllegalStateException e = expectThrows(IllegalStateException.class, () -> TriggeredWatchStore.validate(cs));
@@ -367,11 +371,11 @@ public class TriggeredWatchStoreTests extends ESTestCase {
     public void testTriggeredWatchesIndexIsClosed() {
         ClusterState.Builder csBuilder = new ClusterState.Builder(new ClusterName("_name"));
 
-        Metadata.Builder metadataBuilder = Metadata.builder();
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId);
         metadataBuilder.put(
             IndexMetadata.builder(TriggeredWatchStoreField.INDEX_NAME).settings(indexSettings).state(IndexMetadata.State.CLOSE)
         );
-        csBuilder.metadata(metadataBuilder);
+        csBuilder.putProjectMetadata(metadataBuilder);
 
         assertThat(TriggeredWatchStore.validate(csBuilder.build()), is(false));
     }
@@ -387,9 +391,9 @@ public class TriggeredWatchStoreTests extends ESTestCase {
 
     public void testIndexNotFoundButInMetadata() {
         ClusterState.Builder csBuilder = new ClusterState.Builder(new ClusterName("_name"));
-        Metadata.Builder metadataBuilder = Metadata.builder()
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId)
             .put(IndexMetadata.builder(TriggeredWatchStoreField.INDEX_NAME).settings(indexSettings));
-        csBuilder.metadata(metadataBuilder);
+        csBuilder.putProjectMetadata(metadataBuilder);
 
         ClusterState cs = csBuilder.build();
         Watch watch = mock(Watch.class);

+ 9 - 3
x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistryTests.java

@@ -21,6 +21,8 @@ import org.elasticsearch.cluster.block.ClusterBlocks;
 import org.elasticsearch.cluster.metadata.ComposableIndexTemplate;
 import org.elasticsearch.cluster.metadata.IndexTemplateMetadata;
 import org.elasticsearch.cluster.metadata.Metadata;
+import org.elasticsearch.cluster.metadata.ProjectId;
+import org.elasticsearch.cluster.metadata.ProjectMetadata;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
 import org.elasticsearch.cluster.node.DiscoveryNodes;
@@ -28,6 +30,7 @@ import org.elasticsearch.cluster.service.ClusterService;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.util.concurrent.EsExecutors;
 import org.elasticsearch.common.util.concurrent.ThreadContext;
+import org.elasticsearch.core.NotMultiProjectCapable;
 import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.threadpool.ThreadPool;
 import org.elasticsearch.xcontent.NamedXContentRegistry;
@@ -80,6 +83,8 @@ public class WatcherIndexTemplateRegistryTests extends ESTestCase {
     private ClusterService clusterService;
     private ThreadPool threadPool;
     private Client client;
+    @NotMultiProjectCapable(description = "Watcher is not available in serverless")
+    private final ProjectId projectId = ProjectId.DEFAULT;
 
     @SuppressWarnings("unchecked")
     @Before
@@ -335,9 +340,10 @@ public class WatcherIndexTemplateRegistryTests extends ESTestCase {
         return ClusterState.builder(new ClusterName("test"))
             .metadata(
                 Metadata.builder()
-                    .templates(indexTemplates)
                     .transientSettings(nodeSettings)
-                    .putCustom(IndexLifecycleMetadata.TYPE, ilmMeta)
+                    .put(
+                        ProjectMetadata.builder(projectId).templates(indexTemplates).putCustom(IndexLifecycleMetadata.TYPE, ilmMeta).build()
+                    )
                     .build()
             )
             .blocks(new ClusterBlocks.Builder().build())
@@ -380,7 +386,7 @@ public class WatcherIndexTemplateRegistryTests extends ESTestCase {
             when(indexTemplate.indexPatterns()).thenReturn(Arrays.asList(generateRandomStringArray(10, 100, false, false)));
             templates.put(template.getKey(), indexTemplate);
         }
-        metadataBuilder.indexTemplates(templates);
+        metadataBuilder.put(ProjectMetadata.builder(projectId).indexTemplates(templates));
 
         return ClusterState.builder(new ClusterName("foo")).metadata(metadataBuilder.build()).build();
     }

+ 22 - 11
x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/watch/WatchStoreUtilsTests.java

@@ -14,8 +14,11 @@ import org.elasticsearch.cluster.metadata.DataStreamMetadata;
 import org.elasticsearch.cluster.metadata.DataStreamTestHelper;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.metadata.Metadata;
+import org.elasticsearch.cluster.metadata.ProjectId;
+import org.elasticsearch.cluster.metadata.ProjectMetadata;
 import org.elasticsearch.common.collect.ImmutableOpenMap;
 import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.core.NotMultiProjectCapable;
 import org.elasticsearch.index.Index;
 import org.elasticsearch.index.IndexVersion;
 import org.elasticsearch.test.ESTestCase;
@@ -27,10 +30,12 @@ import java.util.Map;
 import java.util.stream.Collectors;
 
 public class WatchStoreUtilsTests extends ESTestCase {
+    @NotMultiProjectCapable(description = "Watcher is not available in serverless")
+    private final ProjectId projectId = ProjectId.DEFAULT;
 
     public void testGetConcreteIndexForDataStream() {
         String dataStreamName = randomAlphaOfLength(20);
-        Metadata.Builder metadataBuilder = Metadata.builder();
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId);
         Map<String, Metadata.ProjectCustom> customsBuilder = new HashMap<>();
         Map<String, DataStream> dataStreams = new HashMap<>();
         Map<String, IndexMetadata> indexMetadataMapBuilder = new HashMap<>();
@@ -54,15 +59,18 @@ public class WatchStoreUtilsTests extends ESTestCase {
             dataStreamAliases
         );
         customsBuilder.put(DataStreamMetadata.TYPE, dataStreamMetadata);
-        metadataBuilder.projectCustoms(customsBuilder);
-        IndexMetadata concreteIndex = WatchStoreUtils.getConcreteIndex(dataStreamName, metadataBuilder.build());
+        metadataBuilder.customs(customsBuilder);
+        IndexMetadata concreteIndex = WatchStoreUtils.getConcreteIndex(
+            dataStreamName,
+            Metadata.builder().put(metadataBuilder.build()).build()
+        );
         assertNotNull(concreteIndex);
         assertEquals(indexNames.get(indexNames.size() - 1), concreteIndex.getIndex().getName());
     }
 
     public void testGetConcreteIndexForAliasWithMultipleNonWritableIndices() {
         String aliasName = randomAlphaOfLength(20);
-        Metadata.Builder metadataBuilder = Metadata.builder();
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId);
         AliasMetadata.Builder aliasMetadataBuilder = new AliasMetadata.Builder(aliasName);
         aliasMetadataBuilder.writeIndex(false);
         AliasMetadata aliasMetadata = aliasMetadataBuilder.build();
@@ -72,12 +80,15 @@ public class WatchStoreUtilsTests extends ESTestCase {
             indexMetadataMapBuilder.put(indexName, createIndexMetaData(indexName, aliasMetadata));
         }
         metadataBuilder.indices(indexMetadataMapBuilder);
-        expectThrows(IllegalStateException.class, () -> WatchStoreUtils.getConcreteIndex(aliasName, metadataBuilder.build()));
+        expectThrows(
+            IllegalStateException.class,
+            () -> WatchStoreUtils.getConcreteIndex(aliasName, Metadata.builder().put(metadataBuilder.build()).build())
+        );
     }
 
     public void testGetConcreteIndexForAliasWithMultipleIndicesWithWritable() {
         String aliasName = randomAlphaOfLength(20);
-        Metadata.Builder metadataBuilder = Metadata.builder();
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId);
         AliasMetadata.Builder aliasMetadataBuilder = new AliasMetadata.Builder(aliasName);
         aliasMetadataBuilder.writeIndex(false);
         AliasMetadata nonWritableAliasMetadata = aliasMetadataBuilder.build();
@@ -100,14 +111,14 @@ public class WatchStoreUtilsTests extends ESTestCase {
             indexMetadataMapBuilder.put(indexName, createIndexMetaData(indexName, aliasMetadata));
         }
         metadataBuilder.indices(indexMetadataMapBuilder);
-        IndexMetadata concreteIndex = WatchStoreUtils.getConcreteIndex(aliasName, metadataBuilder.build());
+        IndexMetadata concreteIndex = WatchStoreUtils.getConcreteIndex(aliasName, Metadata.builder().put(metadataBuilder.build()).build());
         assertNotNull(concreteIndex);
         assertEquals(indexNames.get(writableIndexIndex), concreteIndex.getIndex().getName());
     }
 
     public void testGetConcreteIndexForAliasWithOneNonWritableIndex() {
         String aliasName = randomAlphaOfLength(20);
-        Metadata.Builder metadataBuilder = Metadata.builder();
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId);
         AliasMetadata.Builder aliasMetadataBuilder = new AliasMetadata.Builder(aliasName);
         aliasMetadataBuilder.writeIndex(false);
         AliasMetadata aliasMetadata = aliasMetadataBuilder.build();
@@ -115,18 +126,18 @@ public class WatchStoreUtilsTests extends ESTestCase {
         String indexName = aliasName + "_" + 0;
         indexMetadataMapBuilder.put(indexName, createIndexMetaData(indexName, aliasMetadata));
         metadataBuilder.indices(indexMetadataMapBuilder);
-        IndexMetadata concreteIndex = WatchStoreUtils.getConcreteIndex(aliasName, metadataBuilder.build());
+        IndexMetadata concreteIndex = WatchStoreUtils.getConcreteIndex(aliasName, Metadata.builder().put(metadataBuilder.build()).build());
         assertNotNull(concreteIndex);
         assertEquals(indexName, concreteIndex.getIndex().getName());
     }
 
     public void testGetConcreteIndexForConcreteIndex() {
         String indexName = randomAlphaOfLength(20);
-        Metadata.Builder metadataBuilder = Metadata.builder();
+        ProjectMetadata.Builder metadataBuilder = ProjectMetadata.builder(projectId);
         Map<String, IndexMetadata> indexMetadataMapBuilder = new HashMap<>();
         indexMetadataMapBuilder.put(indexName, createIndexMetaData(indexName, null));
         metadataBuilder.indices(indexMetadataMapBuilder);
-        IndexMetadata concreteIndex = WatchStoreUtils.getConcreteIndex(indexName, metadataBuilder.build());
+        IndexMetadata concreteIndex = WatchStoreUtils.getConcreteIndex(indexName, Metadata.builder().put(metadataBuilder.build()).build());
         assertNotNull(concreteIndex);
         assertEquals(indexName, concreteIndex.getIndex().getName());
     }