2424import org .elasticsearch .index .Index ;
2525import org .elasticsearch .index .IndexSettings ;
2626import org .elasticsearch .test .ESTestCase ;
27+ import org .elasticsearch .xpack .ccr .Ccr ;
2728import org .elasticsearch .xpack .ccr .CcrLicenseChecker ;
2829import org .elasticsearch .xpack .ccr .CcrSettings ;
2930import org .elasticsearch .xpack .ccr .action .AutoFollowCoordinator .AutoFollower ;
@@ -345,8 +346,7 @@ public void testGetLeaderIndicesToFollow() {
345346 .routingTable (routingTableBuilder .build ())
346347 .build ();
347348
348- List <Index > result = AutoFollower .getLeaderIndicesToFollow (autoFollowPattern , remoteState , clusterState ,
349- Collections .emptyList ());
349+ List <Index > result = AutoFollower .getLeaderIndicesToFollow (autoFollowPattern , remoteState , Collections .emptyList ());
350350 result .sort (Comparator .comparing (Index ::getName ));
351351 assertThat (result .size (), equalTo (5 ));
352352 assertThat (result .get (0 ).getName (), equalTo ("metrics-0" ));
@@ -356,7 +356,7 @@ public void testGetLeaderIndicesToFollow() {
356356 assertThat (result .get (4 ).getName (), equalTo ("metrics-4" ));
357357
358358 List <String > followedIndexUUIDs = Collections .singletonList (remoteState .metaData ().index ("metrics-2" ).getIndexUUID ());
359- result = AutoFollower .getLeaderIndicesToFollow (autoFollowPattern , remoteState , clusterState , followedIndexUUIDs );
359+ result = AutoFollower .getLeaderIndicesToFollow (autoFollowPattern , remoteState , followedIndexUUIDs );
360360 result .sort (Comparator .comparing (Index ::getName ));
361361 assertThat (result .size (), equalTo (4 ));
362362 assertThat (result .get (0 ).getName (), equalTo ("metrics-0" ));
@@ -390,8 +390,7 @@ public void testGetLeaderIndicesToFollow_shardsNotStarted() {
390390 .routingTable (RoutingTable .builder (remoteState .routingTable ()).add (indexRoutingTable ).build ())
391391 .build ();
392392
393- List <Index > result = AutoFollower .getLeaderIndicesToFollow (autoFollowPattern , remoteState , clusterState ,
394- Collections .emptyList ());
393+ List <Index > result = AutoFollower .getLeaderIndicesToFollow (autoFollowPattern , remoteState , Collections .emptyList ());
395394 assertThat (result .size (), equalTo (1 ));
396395 assertThat (result .get (0 ).getName (), equalTo ("index1" ));
397396
@@ -404,7 +403,7 @@ public void testGetLeaderIndicesToFollow_shardsNotStarted() {
404403 .routingTable (RoutingTable .builder (remoteState .routingTable ()).add (indexRoutingTable ).build ())
405404 .build ();
406405
407- result = AutoFollower .getLeaderIndicesToFollow (autoFollowPattern , remoteState , clusterState , Collections .emptyList ());
406+ result = AutoFollower .getLeaderIndicesToFollow (autoFollowPattern , remoteState , Collections .emptyList ());
408407 assertThat (result .size (), equalTo (2 ));
409408 result .sort (Comparator .comparing (Index ::getName ));
410409 assertThat (result .get (0 ).getName (), equalTo ("index1" ));
@@ -864,6 +863,83 @@ void cleanFollowedRemoteIndices(ClusterState remoteClusterState, List<String> pa
864863 "because soft deletes are not enabled" ));
865864 }
866865
866+ public void testAutoFollowerFollowerIndexAlreadyExists () {
867+ Client client = mock (Client .class );
868+ when (client .getRemoteClusterClient (anyString ())).thenReturn (client );
869+
870+ ClusterState remoteState = createRemoteClusterState ("logs-20190101" , true );
871+
872+ AutoFollowPattern autoFollowPattern = new AutoFollowPattern ("remote" , Collections .singletonList ("logs-*" ),
873+ null , null , null , null , null , null , null , null , null , null , null );
874+ Map <String , AutoFollowPattern > patterns = new HashMap <>();
875+ patterns .put ("remote" , autoFollowPattern );
876+ Map <String , List <String >> followedLeaderIndexUUIDS = new HashMap <>();
877+ followedLeaderIndexUUIDS .put ("remote" , new ArrayList <>());
878+ Map <String , Map <String , String >> autoFollowHeaders = new HashMap <>();
879+ autoFollowHeaders .put ("remote" , Collections .singletonMap ("key" , "val" ));
880+ AutoFollowMetadata autoFollowMetadata = new AutoFollowMetadata (patterns , followedLeaderIndexUUIDS , autoFollowHeaders );
881+
882+ ClusterState currentState = ClusterState .builder (new ClusterName ("name" ))
883+ .metaData (MetaData .builder ()
884+ .put (IndexMetaData .builder ("logs-20190101" )
885+ .settings (settings (Version .CURRENT ).put (IndexSettings .INDEX_SOFT_DELETES_SETTING .getKey (), true ))
886+ .putCustom (Ccr .CCR_CUSTOM_METADATA_KEY , Collections .singletonMap (Ccr .CCR_CUSTOM_METADATA_LEADER_INDEX_UUID_KEY ,
887+ remoteState .metaData ().index ("logs-20190101" ).getIndexUUID ()))
888+ .numberOfShards (1 )
889+ .numberOfReplicas (0 ))
890+ .putCustom (AutoFollowMetadata .TYPE , autoFollowMetadata ))
891+ .build ();
892+
893+
894+ final Object [] resultHolder = new Object [1 ];
895+ Consumer <List <AutoFollowCoordinator .AutoFollowResult >> handler = results -> {
896+ resultHolder [0 ] = results ;
897+ };
898+ AutoFollower autoFollower = new AutoFollower ("remote" , handler , localClusterStateSupplier (currentState ), () -> 1L ) {
899+ @ Override
900+ void getRemoteClusterState (String remoteCluster ,
901+ long metadataVersion ,
902+ BiConsumer <ClusterStateResponse , Exception > handler ) {
903+ assertThat (remoteCluster , equalTo ("remote" ));
904+ handler .accept (new ClusterStateResponse (new ClusterName ("name" ), remoteState , 1L , false ), null );
905+ }
906+
907+ @ Override
908+ void createAndFollow (Map <String , String > headers ,
909+ PutFollowAction .Request followRequest ,
910+ Runnable successHandler ,
911+ Consumer <Exception > failureHandler ) {
912+ fail ("this should not be invoked" );
913+ }
914+
915+ @ Override
916+ void updateAutoFollowMetadata (Function <ClusterState , ClusterState > updateFunction ,
917+ Consumer <Exception > handler ) {
918+ ClusterState resultCs = updateFunction .apply (currentState );
919+ AutoFollowMetadata result = resultCs .metaData ().custom (AutoFollowMetadata .TYPE );
920+ assertThat (result .getFollowedLeaderIndexUUIDs ().size (), equalTo (1 ));
921+ assertThat (result .getFollowedLeaderIndexUUIDs ().get ("remote" ).size (), equalTo (1 ));
922+ handler .accept (null );
923+ }
924+
925+ @ Override
926+ void cleanFollowedRemoteIndices (ClusterState remoteClusterState , List <String > patterns ) {
927+ // Ignore, to avoid invoking updateAutoFollowMetadata(...) twice
928+ }
929+ };
930+ autoFollower .start ();
931+
932+ @ SuppressWarnings ("unchecked" )
933+ List <AutoFollowCoordinator .AutoFollowResult > results = (List <AutoFollowCoordinator .AutoFollowResult >) resultHolder [0 ];
934+ assertThat (results , notNullValue ());
935+ assertThat (results .size (), equalTo (1 ));
936+ assertThat (results .get (0 ).clusterStateFetchException , nullValue ());
937+ List <Map .Entry <Index , Exception >> entries = new ArrayList <>(results .get (0 ).autoFollowExecutionResults .entrySet ());
938+ assertThat (entries .size (), equalTo (1 ));
939+ assertThat (entries .get (0 ).getKey ().getName (), equalTo ("logs-20190101" ));
940+ assertThat (entries .get (0 ).getValue (), nullValue ());
941+ }
942+
867943 private static ClusterState createRemoteClusterState (String indexName , Boolean enableSoftDeletes ) {
868944 Settings .Builder indexSettings ;
869945 if (enableSoftDeletes != null ) {
0 commit comments