1212import org .opensearch .cluster .ClusterName ;
1313import org .opensearch .cluster .ClusterState ;
1414import org .opensearch .cluster .coordination .CoordinationMetadata ;
15+ import org .opensearch .cluster .metadata .IndexGraveyard ;
1516import org .opensearch .cluster .metadata .IndexMetadata ;
1617import org .opensearch .cluster .metadata .Metadata ;
1718import org .opensearch .cluster .node .DiscoveryNodes ;
2829import org .opensearch .common .lucene .store .ByteArrayIndexInput ;
2930import org .opensearch .common .settings .ClusterSettings ;
3031import org .opensearch .common .settings .Settings ;
32+ import org .opensearch .core .ParseField ;
3133import org .opensearch .core .action .ActionListener ;
3234import org .opensearch .core .common .bytes .BytesArray ;
3335import org .opensearch .core .common .bytes .BytesReference ;
@@ -634,7 +636,8 @@ public void testReadLatestMetadataManifestSuccessButNoIndexMetadata() throws IOE
634636
635637 remoteClusterStateService .start ();
636638 assertEquals (
637- remoteClusterStateService .getLatestIndexMetadata (clusterState .getClusterName ().value (), clusterState .metadata ().clusterUUID ())
639+ remoteClusterStateService .getLatestMetadata (clusterState .getClusterName ().value (), clusterState .metadata ().clusterUUID ())
640+ .getIndices ()
638641 .size (),
639642 0
640643 );
@@ -662,10 +665,8 @@ public void testReadLatestMetadataManifestSuccessButIndexMetadataFetchIOExceptio
662665 remoteClusterStateService .start ();
663666 Exception e = assertThrows (
664667 IllegalStateException .class ,
665- () -> remoteClusterStateService .getLatestIndexMetadata (
666- clusterState .getClusterName ().value (),
667- clusterState .metadata ().clusterUUID ()
668- )
668+ () -> remoteClusterStateService .getLatestMetadata (clusterState .getClusterName ().value (), clusterState .metadata ().clusterUUID ())
669+ .getIndices ()
669670 );
670671 assertEquals (e .getMessage (), "Error while downloading IndexMetadata - " + uploadedIndexMetadata .getUploadedFilename ());
671672 }
@@ -704,6 +705,70 @@ public void testReadLatestMetadataManifestSuccess() throws IOException {
704705 assertThat (manifest .getStateUUID (), is (expectedManifest .getStateUUID ()));
705706 }
706707
708+ public void testReadGlobalMetadata () throws IOException {
709+ when (blobStoreRepository .getNamedXContentRegistry ()).thenReturn (new NamedXContentRegistry (
710+ List .of (new NamedXContentRegistry .Entry (Metadata .Custom .class , new ParseField (IndexGraveyard .TYPE ), IndexGraveyard ::fromXContent ))));
711+ final ClusterState clusterState = generateClusterStateWithGlobalMetadata ().nodes (nodesWithLocalNodeClusterManager ()).build ();
712+ remoteClusterStateService .start ();
713+
714+ final ClusterMetadataManifest expectedManifest = ClusterMetadataManifest .builder ()
715+ .indices (List .of ())
716+ .clusterTerm (1L )
717+ .stateVersion (1L )
718+ .stateUUID ("state-uuid" )
719+ .clusterUUID ("cluster-uuid" )
720+ .codecVersion (MANIFEST_CURRENT_CODEC_VERSION )
721+ .globalMetadataFileName ("global-metadata-file" )
722+ .nodeId ("nodeA" )
723+ .opensearchVersion (VersionUtils .randomOpenSearchVersion (random ()))
724+ .previousClusterUUID ("prev-cluster-uuid" )
725+ .build ();
726+
727+ Metadata expactedMetadata = Metadata .builder ().persistentSettings (Settings .builder ().put ("readonly" , true ).build ()).build ();
728+ mockBlobContainerForGlobalMetadata (mockBlobStoreObjects (), expectedManifest , expactedMetadata );
729+
730+ Metadata metadata = remoteClusterStateService .getLatestMetadata (
731+ clusterState .getClusterName ().value (),
732+ clusterState .metadata ().clusterUUID ()
733+ );
734+
735+ assertTrue (Metadata .isGlobalStateEquals (metadata , expactedMetadata ));
736+ }
737+
738+ public void testReadGlobalMetadataIOException () throws IOException {
739+ final ClusterState clusterState = generateClusterStateWithGlobalMetadata ().nodes (nodesWithLocalNodeClusterManager ()).build ();
740+ remoteClusterStateService .start ();
741+ String globalIndexMetadataName = "global-metadata-file" ;
742+ final ClusterMetadataManifest expectedManifest = ClusterMetadataManifest .builder ()
743+ .indices (List .of ())
744+ .clusterTerm (1L )
745+ .stateVersion (1L )
746+ .stateUUID ("state-uuid" )
747+ .clusterUUID ("cluster-uuid" )
748+ .codecVersion (MANIFEST_CURRENT_CODEC_VERSION )
749+ .globalMetadataFileName (globalIndexMetadataName )
750+ .nodeId ("nodeA" )
751+ .opensearchVersion (VersionUtils .randomOpenSearchVersion (random ()))
752+ .previousClusterUUID ("prev-cluster-uuid" )
753+ .build ();
754+
755+ Metadata expactedMetadata = Metadata .builder ().persistentSettings (Settings .builder ().put ("readonly" , true ).build ()).build ();
756+
757+ BlobContainer blobContainer = mockBlobStoreObjects ();
758+ mockBlobContainerForGlobalMetadata (blobContainer , expectedManifest , expactedMetadata );
759+
760+ when (blobContainer .readBlob (RemoteClusterStateService .GLOBAL_METADATA_FORMAT .blobName (globalIndexMetadataName ))).thenThrow (
761+ FileNotFoundException .class
762+ );
763+
764+ remoteClusterStateService .start ();
765+ Exception e = assertThrows (
766+ IllegalStateException .class ,
767+ () -> remoteClusterStateService .getLatestMetadata (clusterState .getClusterName ().value (), clusterState .metadata ().clusterUUID ())
768+ );
769+ assertEquals (e .getMessage (), "Error while downloading Global Metadata - " + globalIndexMetadataName );
770+ }
771+
707772 public void testReadLatestIndexMetadataSuccess () throws IOException {
708773 final ClusterState clusterState = generateClusterStateWithOneIndex ().nodes (nodesWithLocalNodeClusterManager ()).build ();
709774 remoteClusterStateService .start ();
@@ -730,15 +795,16 @@ public void testReadLatestIndexMetadataSuccess() throws IOException {
730795 .nodeId ("nodeA" )
731796 .opensearchVersion (VersionUtils .randomOpenSearchVersion (random ()))
732797 .previousClusterUUID ("prev-cluster-uuid" )
798+ .globalMetadataFileName ("global-metadata-file" )
733799 .codecVersion (ClusterMetadataManifest .CODEC_V0 )
734800 .build ();
735801
736802 mockBlobContainer (mockBlobStoreObjects (), expectedManifest , Map .of (index .getUUID (), indexMetadata ));
737803
738- Map <String , IndexMetadata > indexMetadataMap = remoteClusterStateService .getLatestIndexMetadata (
804+ Map <String , IndexMetadata > indexMetadataMap = remoteClusterStateService .getLatestMetadata (
739805 clusterState .getClusterName ().value (),
740806 clusterState .metadata ().clusterUUID ()
741- );
807+ ). getIndices () ;
742808
743809 assertEquals (indexMetadataMap .size (), 1 );
744810 assertEquals (indexMetadataMap .get (index .getUUID ()).getIndex ().getName (), index .getName ());
@@ -1114,6 +1180,41 @@ private void mockBlobContainer(
11141180 });
11151181 }
11161182
1183+ private void mockBlobContainerForGlobalMetadata (
1184+ BlobContainer blobContainer ,
1185+ ClusterMetadataManifest clusterMetadataManifest ,
1186+ Metadata metadata
1187+ ) throws IOException {
1188+ String mockManifestFileName = "manifest__1__2__C__456__1" ;
1189+ BlobMetadata blobMetadata = new PlainBlobMetadata (mockManifestFileName , 1 );
1190+ when (
1191+ blobContainer .listBlobsByPrefixInSortedOrder (
1192+ "manifest" + RemoteClusterStateService .DELIMITER ,
1193+ 1 ,
1194+ BlobContainer .BlobNameSortOrder .LEXICOGRAPHIC
1195+ )
1196+ ).thenReturn (Arrays .asList (blobMetadata ));
1197+
1198+ BytesReference bytes = RemoteClusterStateService .CLUSTER_METADATA_MANIFEST_FORMAT .serialize (
1199+ clusterMetadataManifest ,
1200+ mockManifestFileName ,
1201+ blobStoreRepository .getCompressor (),
1202+ FORMAT_PARAMS
1203+ );
1204+ when (blobContainer .readBlob (mockManifestFileName )).thenReturn (new ByteArrayInputStream (bytes .streamInput ().readAllBytes ()));
1205+
1206+ BytesReference bytesGlobalMetadata = RemoteClusterStateService .GLOBAL_METADATA_FORMAT .serialize (
1207+ metadata ,
1208+ "global-metadata-file" ,
1209+ blobStoreRepository .getCompressor (),
1210+ FORMAT_PARAMS
1211+ );
1212+ String [] splitPath = clusterMetadataManifest .getGlobalMetadataFileName ().split ("/" );
1213+ when (blobContainer .readBlob (RemoteClusterStateService .GLOBAL_METADATA_FORMAT .blobName (splitPath [splitPath .length - 1 ]))).thenReturn (
1214+ new ByteArrayInputStream (bytesGlobalMetadata .streamInput ().readAllBytes ())
1215+ );
1216+ }
1217+
11171218 private static ClusterState .Builder generateClusterStateWithGlobalMetadata () {
11181219 final Settings clusterSettings = Settings .builder ().put ("cluster.blocks.read_only" , true ).build ();
11191220 final CoordinationMetadata coordinationMetadata = CoordinationMetadata .builder ().term (1L ).build ();
0 commit comments