8
8
9
9
package org .opensearch .remotestore ;
10
10
11
+ import org .opensearch .action .admin .cluster .configuration .AddVotingConfigExclusionsAction ;
12
+ import org .opensearch .action .admin .cluster .configuration .AddVotingConfigExclusionsRequest ;
11
13
import org .opensearch .action .admin .cluster .settings .ClusterUpdateSettingsRequest ;
14
+ import org .opensearch .action .admin .cluster .settings .ClusterUpdateSettingsResponse ;
15
+ import org .opensearch .action .admin .indices .alias .Alias ;
12
16
import org .opensearch .action .admin .indices .datastream .DataStreamRolloverIT ;
13
17
import org .opensearch .action .admin .indices .settings .put .UpdateSettingsRequest ;
18
+ import org .opensearch .action .admin .indices .template .put .PutComponentTemplateAction ;
19
+ import org .opensearch .action .admin .indices .template .put .PutComposableIndexTemplateAction ;
14
20
import org .opensearch .action .admin .indices .template .put .PutIndexTemplateRequest ;
21
+ import org .opensearch .action .support .master .AcknowledgedResponse ;
15
22
import org .opensearch .cluster .ClusterState ;
16
23
import org .opensearch .cluster .block .ClusterBlockException ;
24
+ import org .opensearch .cluster .metadata .ComponentTemplate ;
25
+ import org .opensearch .cluster .metadata .ComponentTemplateMetadata ;
26
+ import org .opensearch .cluster .metadata .ComposableIndexTemplate ;
27
+ import org .opensearch .cluster .metadata .ComposableIndexTemplateMetadata ;
17
28
import org .opensearch .cluster .metadata .IndexMetadata ;
18
29
import org .opensearch .cluster .metadata .IndexTemplateMetadata ;
19
30
import org .opensearch .cluster .metadata .Metadata ;
20
31
import org .opensearch .cluster .metadata .RepositoriesMetadata ;
32
+ import org .opensearch .cluster .metadata .Template ;
33
+ import org .opensearch .common .action .ActionFuture ;
34
+ import org .opensearch .common .settings .Setting ;
21
35
import org .opensearch .common .settings .Settings ;
22
36
import org .opensearch .gateway .remote .ClusterMetadataManifest ;
23
37
import org .opensearch .gateway .remote .ClusterMetadataManifest .UploadedIndexMetadata ;
30
44
import java .nio .file .Files ;
31
45
import java .nio .file .Path ;
32
46
import java .util .Arrays ;
47
+ import java .util .Collections ;
33
48
import java .util .List ;
34
49
import java .util .Locale ;
35
50
import java .util .Map ;
36
51
import java .util .Objects ;
37
52
import java .util .concurrent .ExecutionException ;
53
+ import java .util .stream .Collectors ;
38
54
39
55
import static org .opensearch .cluster .coordination .ClusterBootstrapService .INITIAL_CLUSTER_MANAGER_NODES_SETTING ;
40
56
import static org .opensearch .cluster .metadata .IndexMetadata .INDEX_READ_ONLY_SETTING ;
47
63
48
64
@ OpenSearchIntegTestCase .ClusterScope (scope = OpenSearchIntegTestCase .Scope .TEST , numDataNodes = 0 )
49
65
public class RemoteStoreClusterStateRestoreIT extends BaseRemoteStoreRestoreIT {
66
+ static final String TEMPLATE_NAME = "remote-store-test-template" ;
67
+ static final String COMPONENT_TEMPLATE_NAME = "remote-component-template1" ;
68
+ static final String COMPOSABLE_TEMPLATE_NAME = "remote-composable-template1" ;
69
+ static final Setting <String > MOCK_SETTING = Setting .simpleString ("mock-setting" );
70
+ static final String [] EXCLUDED_NODES = { "ex-1" , "ex-2" };
50
71
51
72
@ Before
52
73
public void setup () {
@@ -93,6 +114,45 @@ public void testFullClusterRestore() throws Exception {
93
114
Map <String , Long > indexStats = initialTestSetup (shardCount , replicaCount , dataNodeCount , 1 );
94
115
String prevClusterUUID = clusterService ().state ().metadata ().clusterUUID ();
95
116
long prevClusterStateVersion = clusterService ().state ().version ();
117
+ // Step - 1.1 Add some cluster state elements
118
+ ActionFuture <AcknowledgedResponse > response = client ().admin ()
119
+ .indices ()
120
+ .preparePutTemplate (TEMPLATE_NAME )
121
+ .addAlias (new Alias (INDEX_NAME ))
122
+ .setPatterns (Arrays .stream (INDEX_NAMES_WILDCARD .split ("," )).collect (Collectors .toList ()))
123
+ .execute ();
124
+ assertTrue (response .get ().isAcknowledged ());
125
+ ActionFuture <ClusterUpdateSettingsResponse > clusterUpdateSettingsResponse = client ().admin ()
126
+ .cluster ()
127
+ .prepareUpdateSettings ()
128
+ .setPersistentSettings (Settings .builder ().put (SETTING_READ_ONLY_SETTING .getKey (), false ).build ())
129
+ .execute ();
130
+ assertTrue (clusterUpdateSettingsResponse .get ().isAcknowledged ());
131
+ // update coordination metadata
132
+ client ().execute (AddVotingConfigExclusionsAction .INSTANCE , new AddVotingConfigExclusionsRequest (EXCLUDED_NODES ));
133
+ // Add a custom metadata as component index template
134
+ ActionFuture <AcknowledgedResponse > componentTemplateResponse = client ().execute (
135
+ PutComponentTemplateAction .INSTANCE ,
136
+ new PutComponentTemplateAction .Request (COMPONENT_TEMPLATE_NAME ).componentTemplate (
137
+ new ComponentTemplate (new Template (Settings .EMPTY , null , Collections .emptyMap ()), 1L , Collections .emptyMap ())
138
+ )
139
+ );
140
+ assertTrue (componentTemplateResponse .get ().isAcknowledged ());
141
+ ActionFuture <AcknowledgedResponse > composableTemplateResponse = client ().execute (
142
+ PutComposableIndexTemplateAction .INSTANCE ,
143
+ new PutComposableIndexTemplateAction .Request (COMPOSABLE_TEMPLATE_NAME ).indexTemplate (
144
+ new ComposableIndexTemplate (
145
+ Arrays .stream (INDEX_NAMES_WILDCARD .split ("," )).collect (Collectors .toList ()),
146
+ new Template (Settings .EMPTY , null , Collections .emptyMap ()),
147
+ Collections .singletonList (COMPONENT_TEMPLATE_NAME ),
148
+ 1L ,
149
+ 1L ,
150
+ Collections .emptyMap (),
151
+ null
152
+ )
153
+ )
154
+ );
155
+ assertTrue (composableTemplateResponse .get ().isAcknowledged ());
96
156
97
157
// Step - 2 Replace all nodes in the cluster with new nodes. This ensures new cluster state doesn't have previous index metadata
98
158
resetCluster (dataNodeCount , clusterManagerNodeCount );
@@ -110,7 +170,24 @@ public void testFullClusterRestore() throws Exception {
110
170
);
111
171
validateMetadata (List .of (INDEX_NAME ));
112
172
verifyRedIndicesAndTriggerRestore (indexStats , INDEX_NAME , true );
113
-
173
+ clusterService ().state ()
174
+ .metadata ()
175
+ .coordinationMetadata ()
176
+ .getVotingConfigExclusions ()
177
+ .stream ()
178
+ .forEach (config -> assertTrue (Arrays .stream (EXCLUDED_NODES ).anyMatch (node -> node .equals (config .getNodeId ()))));
179
+ assertFalse (clusterService ().state ().metadata ().templates ().isEmpty ());
180
+ assertTrue (clusterService ().state ().metadata ().templates ().containsKey (TEMPLATE_NAME ));
181
+ assertFalse (clusterService ().state ().metadata ().settings ().isEmpty ());
182
+ assertFalse (clusterService ().state ().metadata ().settings ().getAsBoolean (SETTING_READ_ONLY_SETTING .getKey (), true ));
183
+ assertNotNull (clusterService ().state ().metadata ().custom ("component_template" ));
184
+ ComponentTemplateMetadata componentTemplateMetadata = clusterService ().state ().metadata ().custom ("component_template" );
185
+ assertFalse (componentTemplateMetadata .componentTemplates ().isEmpty ());
186
+ assertTrue (componentTemplateMetadata .componentTemplates ().containsKey (COMPONENT_TEMPLATE_NAME ));
187
+ assertNotNull (clusterService ().state ().metadata ().custom ("index_template" ));
188
+ ComposableIndexTemplateMetadata composableIndexTemplate = clusterService ().state ().metadata ().custom ("index_template" );
189
+ assertFalse (composableIndexTemplate .indexTemplates ().isEmpty ());
190
+ assertTrue (composableIndexTemplate .indexTemplates ().containsKey (COMPOSABLE_TEMPLATE_NAME ));
114
191
}
115
192
116
193
/**
0 commit comments