11
11
import org .elasticsearch .action .admin .indices .create .CreateIndexRequest ;
12
12
import org .elasticsearch .action .admin .indices .delete .DeleteIndexRequest ;
13
13
import org .elasticsearch .action .admin .indices .exists .indices .IndicesExistsRequest ;
14
+ import org .elasticsearch .action .get .GetResponse ;
15
+ import org .elasticsearch .action .index .IndexRequest ;
16
+ import org .elasticsearch .action .support .PlainActionFuture ;
14
17
import org .elasticsearch .client .Client ;
15
18
import org .elasticsearch .cluster .metadata .IndexMetadata ;
16
19
import org .elasticsearch .cluster .metadata .Metadata ;
17
- import org .elasticsearch .core . CheckedRunnable ;
20
+ import org .elasticsearch .cluster . service . ClusterService ;
18
21
import org .elasticsearch .common .Strings ;
19
22
import org .elasticsearch .common .regex .Regex ;
20
23
import org .elasticsearch .common .settings .Settings ;
21
24
import org .elasticsearch .common .unit .ByteSizeUnit ;
22
25
import org .elasticsearch .common .unit .ByteSizeValue ;
26
+ import org .elasticsearch .core .CheckedRunnable ;
23
27
import org .elasticsearch .core .TimeValue ;
24
28
import org .elasticsearch .index .IndexNotFoundException ;
25
29
import org .elasticsearch .index .IndexSettings ;
30
+ import org .elasticsearch .indices .SystemIndexDescriptor ;
31
+ import org .elasticsearch .plugins .Plugin ;
32
+ import org .elasticsearch .plugins .SystemIndexPlugin ;
26
33
import org .elasticsearch .xpack .CcrIntegTestCase ;
27
34
import org .elasticsearch .xpack .core .ccr .AutoFollowMetadata ;
28
35
import org .elasticsearch .xpack .core .ccr .AutoFollowStats ;
36
+ import org .elasticsearch .xpack .core .ccr .CcrAutoFollowInfoFetcher ;
37
+ import org .elasticsearch .xpack .core .ccr .CcrConstants ;
29
38
import org .elasticsearch .xpack .core .ccr .action .ActivateAutoFollowPatternAction ;
30
39
import org .elasticsearch .xpack .core .ccr .action .CcrStatsAction ;
31
40
import org .elasticsearch .xpack .core .ccr .action .DeleteAutoFollowPatternAction ;
32
41
import org .elasticsearch .xpack .core .ccr .action .FollowInfoAction ;
33
42
import org .elasticsearch .xpack .core .ccr .action .FollowInfoAction .Response .FollowerInfo ;
34
43
import org .elasticsearch .xpack .core .ccr .action .FollowParameters ;
35
44
import org .elasticsearch .xpack .core .ccr .action .GetAutoFollowPatternAction ;
45
+ import org .elasticsearch .xpack .core .ccr .action .PauseFollowAction ;
36
46
import org .elasticsearch .xpack .core .ccr .action .PutAutoFollowPatternAction ;
37
47
38
48
import java .util .Arrays ;
49
+ import java .util .Collection ;
39
50
import java .util .Collections ;
40
51
import java .util .List ;
41
52
import java .util .Locale ;
46
57
import java .util .stream .Collectors ;
47
58
48
59
import static org .elasticsearch .test .hamcrest .ElasticsearchAssertions .assertAcked ;
60
+ import static org .hamcrest .Matchers .empty ;
49
61
import static org .hamcrest .Matchers .equalTo ;
50
62
import static org .hamcrest .Matchers .greaterThanOrEqualTo ;
51
63
import static org .hamcrest .Matchers .hasSize ;
@@ -60,6 +72,49 @@ protected boolean reuseClusters() {
60
72
return false ;
61
73
}
62
74
75
+ @ Override
76
+ protected Collection <Class <? extends Plugin >> nodePlugins () {
77
+ return org .elasticsearch .core .List .of (FakeSystemIndexPlugin .class , SecondFakeSystemIndexPlugin .class );
78
+ }
79
+
80
+ public static class FakeSystemIndexPlugin extends Plugin implements SystemIndexPlugin {
81
+ public static final String SYSTEM_INDEX_NAME = ".test-system-idx" ;
82
+
83
+ @ Override
84
+ public Collection <SystemIndexDescriptor > getSystemIndexDescriptors (Settings settings ) {
85
+ return Collections .singletonList (new SystemIndexDescriptor (SYSTEM_INDEX_NAME , "test" ));
86
+ }
87
+
88
+ @ Override
89
+ public String getFeatureName () {
90
+ return "FakeSystemIndexPlugin" ;
91
+ }
92
+
93
+ @ Override
94
+ public String getFeatureDescription () {
95
+ return "FakeSystemIndexPlugin" ;
96
+ }
97
+ }
98
+
99
+ public static class SecondFakeSystemIndexPlugin extends Plugin implements SystemIndexPlugin {
100
+ public static final String SYSTEM_INDEX_NAME = ".another-test-system-idx" ;
101
+
102
+ @ Override
103
+ public Collection <SystemIndexDescriptor > getSystemIndexDescriptors (Settings settings ) {
104
+ return Collections .singletonList (new SystemIndexDescriptor (SYSTEM_INDEX_NAME , "test" ));
105
+ }
106
+
107
+ @ Override
108
+ public String getFeatureName () {
109
+ return "SecondFakeSystemIndexPlugin" ;
110
+ }
111
+
112
+ @ Override
113
+ public String getFeatureDescription () {
114
+ return "Fake system index" ;
115
+ }
116
+ }
117
+
63
118
public void testAutoFollow () throws Exception {
64
119
Settings leaderIndexSettings = Settings .builder ()
65
120
.put (IndexSettings .INDEX_SOFT_DELETES_SETTING .getKey (), true )
@@ -117,8 +172,8 @@ public void testCleanFollowedLeaderIndexUUIDs() throws Exception {
117
172
118
173
Metadata metadata = getFollowerCluster ().clusterService ().state ().metadata ();
119
174
String leaderIndexUUID = metadata .index ("copy-logs-201901" )
120
- .getCustomData (Ccr .CCR_CUSTOM_METADATA_KEY )
121
- .get (Ccr .CCR_CUSTOM_METADATA_LEADER_INDEX_UUID_KEY );
175
+ .getCustomData (CcrConstants .CCR_CUSTOM_METADATA_KEY )
176
+ .get (CcrConstants .CCR_CUSTOM_METADATA_LEADER_INDEX_UUID_KEY );
122
177
AutoFollowMetadata autoFollowMetadata = metadata .custom (AutoFollowMetadata .TYPE );
123
178
assertThat (autoFollowMetadata , notNullValue ());
124
179
List <String > followedLeaderIndixUUIDs = autoFollowMetadata .getFollowedLeaderIndexUUIDs ().get ("my-pattern" );
@@ -573,7 +628,6 @@ public void testAutoFollowExclusion() throws Exception {
573
628
.put (IndexMetadata .INDEX_NUMBER_OF_SHARDS_SETTING .getKey (), 1 )
574
629
.put (IndexMetadata .INDEX_NUMBER_OF_REPLICAS_SETTING .getKey (), 0 )
575
630
.build ();
576
-
577
631
putAutoFollowPatterns ("my-pattern1" , new String [] {"logs-*" }, Collections .singletonList ("logs-2018*" ));
578
632
579
633
createLeaderIndex ("logs-201801" , leaderIndexSettings );
@@ -594,6 +648,69 @@ public void testAutoFollowExclusion() throws Exception {
594
648
assertFalse (indexExists ("copy-logs-201801" , followerClient ()));
595
649
}
596
650
651
+ public void testGetAutoFollowedSystemIndices () throws Exception {
652
+ assertThat (getFollowerAutoFollowedSystemIndices (), is (empty ()));
653
+
654
+ // This index is created before the auto-follow pattern therefore it won't be auto-followed
655
+ // but it's in the followedLeaderIndexUUIDs list anyway.
656
+ createLeaderSystemIndex (FakeSystemIndexPlugin .SYSTEM_INDEX_NAME );
657
+
658
+ putAutoFollowPatterns ("my-pattern" , new String []{".*" , "logs-*" });
659
+
660
+ assertLongBusy (() -> {
661
+ final AutoFollowStats autoFollowStats = getAutoFollowStats ();
662
+ assertThat (autoFollowStats .getAutoFollowedClusters ().size (), equalTo (1 ));
663
+ assertThat (autoFollowStats .getNumberOfSuccessfulFollowIndices (), equalTo (0L ));
664
+ });
665
+
666
+ assertThat (getFollowerAutoFollowedSystemIndices (), is (empty ()));
667
+
668
+ Settings leaderIndexSettings = Settings .builder ()
669
+ .put (IndexSettings .INDEX_SOFT_DELETES_SETTING .getKey (), true )
670
+ .put (IndexMetadata .INDEX_NUMBER_OF_SHARDS_SETTING .getKey (), 1 )
671
+ .put (IndexMetadata .INDEX_NUMBER_OF_REPLICAS_SETTING .getKey (), 0 )
672
+ .build ();
673
+ createLeaderIndex ("logs-202101" , leaderIndexSettings );
674
+ createLeaderSystemIndex (SecondFakeSystemIndexPlugin .SYSTEM_INDEX_NAME );
675
+
676
+ final String followerSystemIndexName = "copy-" + SecondFakeSystemIndexPlugin .SYSTEM_INDEX_NAME ;
677
+
678
+ ensureFollowerGreen (followerSystemIndexName );
679
+ ensureFollowerGreen ("copy-logs-202101" );
680
+
681
+ assertLongBusy (() -> {
682
+ final AutoFollowStats autoFollowStats = getAutoFollowStats ();
683
+ assertThat (autoFollowStats .getNumberOfSuccessfulFollowIndices (), equalTo (2L ));
684
+
685
+ // Ensure that the operations have been replicated
686
+ final GetResponse response = followerClient ().prepareGet (followerSystemIndexName , "_doc" , "1" ).execute ().actionGet ();
687
+ assertThat (response .isExists (), equalTo (true ));
688
+ });
689
+
690
+ final List <String > autoFollowedIndices = getFollowerAutoFollowedSystemIndices ();
691
+ assertThat (autoFollowedIndices .size (), is (equalTo (1 )));
692
+ assertThat (autoFollowedIndices .get (0 ), is (equalTo (followerSystemIndexName )));
693
+
694
+ followerClient ().execute (PauseFollowAction .INSTANCE , new PauseFollowAction .Request (followerSystemIndexName )).actionGet ();
695
+
696
+ assertLongBusy (() -> {
697
+ assertThat (getFollowerAutoFollowedSystemIndices (), is (empty ()));
698
+ });
699
+ }
700
+
701
+ private void createLeaderSystemIndex (String indexName ) {
702
+ leaderClient ().index (new IndexRequest (indexName ).id ("1" ).source ("completed" , true )).actionGet ();
703
+ final GetResponse getResponse = leaderClient ().prepareGet (indexName , "_doc" , "1" ).execute ().actionGet ();
704
+ assertThat (getResponse .isExists (), equalTo (true ));
705
+ }
706
+
707
+ private List <String > getFollowerAutoFollowedSystemIndices () {
708
+ final ClusterService followerClusterService = getFollowerCluster ().getMasterNodeInstance (ClusterService .class );
709
+ PlainActionFuture <List <String >> future = PlainActionFuture .newFuture ();
710
+ CcrAutoFollowInfoFetcher .getAutoFollowedSystemIndices (followerClient (), followerClusterService .state (), future );
711
+ return future .actionGet ();
712
+ }
713
+
597
714
private boolean indexExists (String index , Client client ) {
598
715
return client .admin ().indices ().exists (new IndicesExistsRequest (index )).actionGet ().isExists ();
599
716
}
0 commit comments