Skip to content

Commit dc4d16c

Browse files
committed
Merge branch 'main-integ-publication' of github.com:rajiv-kv/OpenSearch into rajiv-kv-main-integ-publication
2 parents 0e2f404 + c7efb89 commit dc4d16c

File tree

3 files changed

+291
-8
lines changed

3 files changed

+291
-8
lines changed
Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*/
8+
9+
package org.opensearch.gateway.remote;
10+
11+
import org.opensearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
12+
import org.opensearch.common.settings.Settings;
13+
import org.opensearch.plugins.Plugin;
14+
import org.opensearch.remotemigration.MigrationBaseTestCase;
15+
import org.opensearch.remotestore.multipart.mocks.MockFsRepositoryPlugin;
16+
import org.opensearch.repositories.blobstore.BlobStoreRepository;
17+
import org.opensearch.repositories.fs.ReloadableFsRepository;
18+
import org.opensearch.test.InternalSettingsPlugin;
19+
import org.opensearch.test.OpenSearchIntegTestCase;
20+
import org.opensearch.test.transport.MockTransportService;
21+
import org.junit.Before;
22+
23+
import java.util.Collection;
24+
import java.util.Locale;
25+
import java.util.stream.Collectors;
26+
import java.util.stream.Stream;
27+
28+
import static org.opensearch.gateway.remote.RemoteClusterStateService.REMOTE_CLUSTER_STATE_ENABLED_SETTING;
29+
import static org.opensearch.node.remotestore.RemoteStoreNodeAttribute.REMOTE_STORE_CLUSTER_STATE_REPOSITORY_NAME_ATTRIBUTE_KEY;
30+
import static org.opensearch.node.remotestore.RemoteStoreNodeAttribute.REMOTE_STORE_REPOSITORY_SETTINGS_ATTRIBUTE_KEY_PREFIX;
31+
import static org.opensearch.node.remotestore.RemoteStoreNodeAttribute.REMOTE_STORE_REPOSITORY_TYPE_ATTRIBUTE_KEY_FORMAT;
32+
import static org.opensearch.node.remotestore.RemoteStoreNodeAttribute.REMOTE_STORE_ROUTING_TABLE_REPOSITORY_NAME_ATTRIBUTE_KEY;
33+
import static org.opensearch.node.remotestore.RemoteStoreNodeService.MIGRATION_DIRECTION_SETTING;
34+
import static org.opensearch.node.remotestore.RemoteStoreNodeService.REMOTE_STORE_COMPATIBILITY_MODE_SETTING;
35+
import static org.opensearch.test.hamcrest.OpenSearchAssertions.assertAcked;
36+
37+
/**
38+
* Tests the compatibility between types of nodes based on the configured repositories
39+
* Non Remote node [No Repositories configured]
40+
* Remote Publish Configured Node [Cluster State + Routing Table]
41+
* Remote Node [Cluster State + Segment + Translog]
42+
* Remote Node With Routing Table [Cluster State + Segment + Translog + Routing Table]
43+
*/
44+
@OpenSearchIntegTestCase.ClusterScope(scope = OpenSearchIntegTestCase.Scope.TEST, numDataNodes = 0)
45+
public class RemotePublicationConfigurationIT extends MigrationBaseTestCase {
46+
private final String REMOTE_PRI_DOCREP_REP = "remote-primary-docrep-replica";
47+
48+
@Override
49+
protected Collection<Class<? extends Plugin>> nodePlugins() {
50+
/* Adding the following mock plugins:
51+
- InternalSettingsPlugin : To override default intervals of retention lease and global ckp sync
52+
- MockFsRepositoryPlugin and MockTransportService.TestPlugin: To ensure remote interactions are not no-op and retention leases are properly propagated
53+
*/
54+
return Stream.concat(
55+
super.nodePlugins().stream(),
56+
Stream.of(InternalSettingsPlugin.class, MockFsRepositoryPlugin.class, MockTransportService.TestPlugin.class)
57+
).collect(Collectors.toList());
58+
}
59+
60+
@Before
61+
public void setUp() throws Exception {
62+
if (segmentRepoPath == null || translogRepoPath == null) {
63+
segmentRepoPath = randomRepoPath().toAbsolutePath();
64+
translogRepoPath = randomRepoPath().toAbsolutePath();
65+
}
66+
super.setUp();
67+
}
68+
69+
public Settings.Builder remotePublishConfiguredNodeSetting() {
70+
String stateRepoSettingsAttributeKeyPrefix = String.format(
71+
Locale.getDefault(),
72+
"node.attr." + REMOTE_STORE_REPOSITORY_SETTINGS_ATTRIBUTE_KEY_PREFIX,
73+
REPOSITORY_NAME
74+
);
75+
String prefixModeVerificationSuffix = BlobStoreRepository.PREFIX_MODE_VERIFICATION_SETTING.getKey();
76+
String stateRepoTypeAttributeKey = String.format(
77+
Locale.getDefault(),
78+
"node.attr." + REMOTE_STORE_REPOSITORY_TYPE_ATTRIBUTE_KEY_FORMAT,
79+
REPOSITORY_NAME
80+
);
81+
String routingTableRepoTypeAttributeKey = String.format(
82+
Locale.getDefault(),
83+
"node.attr." + REMOTE_STORE_REPOSITORY_TYPE_ATTRIBUTE_KEY_FORMAT,
84+
ROUTING_TABLE_REPO_NAME
85+
);
86+
String routingTableRepoSettingsAttributeKeyPrefix = String.format(
87+
Locale.getDefault(),
88+
"node.attr." + REMOTE_STORE_REPOSITORY_SETTINGS_ATTRIBUTE_KEY_PREFIX,
89+
ROUTING_TABLE_REPO_NAME
90+
);
91+
92+
Settings.Builder builder = Settings.builder()
93+
.put("node.attr." + REMOTE_STORE_CLUSTER_STATE_REPOSITORY_NAME_ATTRIBUTE_KEY, REPOSITORY_NAME)
94+
.put(stateRepoTypeAttributeKey, ReloadableFsRepository.TYPE)
95+
.put(stateRepoSettingsAttributeKeyPrefix + "location", segmentRepoPath)
96+
.put(stateRepoSettingsAttributeKeyPrefix + prefixModeVerificationSuffix, true)
97+
.put(REMOTE_CLUSTER_STATE_ENABLED_SETTING.getKey(), true)
98+
.put("node.attr." + REMOTE_STORE_ROUTING_TABLE_REPOSITORY_NAME_ATTRIBUTE_KEY, ROUTING_TABLE_REPO_NAME)
99+
.put(routingTableRepoTypeAttributeKey, ReloadableFsRepository.TYPE)
100+
.put(routingTableRepoSettingsAttributeKeyPrefix + "location", segmentRepoPath);
101+
return builder;
102+
}
103+
104+
public Settings.Builder remoteWithRoutingTableNodeSetting() {
105+
// Remote Cluster with Routing table
106+
return Settings.builder()
107+
.put(
108+
buildRemoteStoreNodeAttributes(
109+
REPOSITORY_NAME,
110+
segmentRepoPath,
111+
REPOSITORY_2_NAME,
112+
translogRepoPath,
113+
REPOSITORY_NAME,
114+
segmentRepoPath,
115+
false
116+
)
117+
)
118+
.put(REMOTE_CLUSTER_STATE_ENABLED_SETTING.getKey(), true);
119+
}
120+
121+
public void testRemotePublishConfigNodeJoinNonRemoteCluster() throws Exception {
122+
internalCluster().startClusterManagerOnlyNode();
123+
internalCluster().startDataOnlyNodes(2);
124+
125+
Settings.Builder build = remotePublishConfiguredNodeSetting();
126+
internalCluster().startClusterManagerOnlyNode(build.build());
127+
internalCluster().startDataOnlyNodes(2, build.build());
128+
129+
ensureStableCluster(6);
130+
ensureGreen();
131+
}
132+
133+
public void testRemotePublishConfigNodeJoinRemoteCluster() throws Exception {
134+
// Remote Cluster without Routing table
135+
setAddRemote(true);
136+
internalCluster().startClusterManagerOnlyNode();
137+
internalCluster().startDataOnlyNodes(2);
138+
setAddRemote(false);
139+
140+
ClusterUpdateSettingsRequest updateSettingsRequest = new ClusterUpdateSettingsRequest();
141+
updateSettingsRequest.persistentSettings(
142+
Settings.builder()
143+
.put(MIGRATION_DIRECTION_SETTING.getKey(), "remote_store")
144+
.put(REMOTE_STORE_COMPATIBILITY_MODE_SETTING.getKey(), "mixed")
145+
);
146+
assertAcked(client().admin().cluster().updateSettings(updateSettingsRequest).actionGet());
147+
Settings.Builder build = remotePublishConfiguredNodeSetting();
148+
internalCluster().startClusterManagerOnlyNode(build.build());
149+
ensureStableCluster(4);
150+
ensureGreen();
151+
}
152+
153+
public void testRemoteNodeWithRoutingTableJoinRemoteCluster() throws Exception {
154+
setAddRemote(true);
155+
internalCluster().startClusterManagerOnlyNode();
156+
internalCluster().startDataOnlyNodes(2);
157+
setAddRemote(false);
158+
159+
ClusterUpdateSettingsRequest updateSettingsRequest = new ClusterUpdateSettingsRequest();
160+
updateSettingsRequest.persistentSettings(
161+
Settings.builder()
162+
.put(MIGRATION_DIRECTION_SETTING.getKey(), "remote_store")
163+
.put(REMOTE_STORE_COMPATIBILITY_MODE_SETTING.getKey(), "mixed")
164+
);
165+
assertAcked(client().admin().cluster().updateSettings(updateSettingsRequest).actionGet());
166+
167+
// Remote Repo with Routing table
168+
Settings settings = remoteWithRoutingTableNodeSetting().build();
169+
internalCluster().startClusterManagerOnlyNode(settings);
170+
ensureStableCluster(4);
171+
ensureGreen();
172+
}
173+
174+
public void testNonRemoteNodeJoinRemoteWithRoutingCluster() throws Exception {
175+
Settings settings = remoteWithRoutingTableNodeSetting().build();
176+
internalCluster().startClusterManagerOnlyNode(settings);
177+
internalCluster().startDataOnlyNodes(2, settings);
178+
179+
ClusterUpdateSettingsRequest updateSettingsRequest = new ClusterUpdateSettingsRequest();
180+
updateSettingsRequest.persistentSettings(
181+
Settings.builder()
182+
.put(MIGRATION_DIRECTION_SETTING.getKey(), "remote_store")
183+
.put(REMOTE_STORE_COMPATIBILITY_MODE_SETTING.getKey(), "mixed")
184+
);
185+
assertAcked(client().admin().cluster().updateSettings(updateSettingsRequest).actionGet());
186+
187+
internalCluster().startClusterManagerOnlyNode();
188+
ensureStableCluster(4);
189+
ensureGreen();
190+
}
191+
192+
public void testRemotePublishConfigNodeJoinRemoteWithRoutingCluster() throws Exception {
193+
Settings settings = remoteWithRoutingTableNodeSetting().build();
194+
internalCluster().startClusterManagerOnlyNode(settings);
195+
internalCluster().startDataOnlyNodes(2, settings);
196+
197+
ClusterUpdateSettingsRequest updateSettingsRequest = new ClusterUpdateSettingsRequest();
198+
updateSettingsRequest.persistentSettings(
199+
Settings.builder()
200+
.put(MIGRATION_DIRECTION_SETTING.getKey(), "remote_store")
201+
.put(REMOTE_STORE_COMPATIBILITY_MODE_SETTING.getKey(), "mixed")
202+
);
203+
assertAcked(client().admin().cluster().updateSettings(updateSettingsRequest).actionGet());
204+
205+
internalCluster().startClusterManagerOnlyNode(remotePublishConfiguredNodeSetting().build());
206+
207+
ensureStableCluster(4);
208+
ensureGreen();
209+
}
210+
211+
public void testNonRemoteNodeJoiningPublishConfigCluster() throws Exception {
212+
Settings.Builder build = remotePublishConfiguredNodeSetting();
213+
internalCluster().startClusterManagerOnlyNode(build.build());
214+
internalCluster().startDataOnlyNodes(2, build.build());
215+
216+
internalCluster().startClusterManagerOnlyNode();
217+
218+
ensureStableCluster(4);
219+
ensureGreen();
220+
}
221+
222+
public void testRemoteNodeJoiningPublishConfigCluster() throws Exception {
223+
Settings.Builder build = remotePublishConfiguredNodeSetting();
224+
internalCluster().startClusterManagerOnlyNode(build.build());
225+
internalCluster().startDataOnlyNodes(2, build.build());
226+
227+
ClusterUpdateSettingsRequest updateSettingsRequest = new ClusterUpdateSettingsRequest();
228+
updateSettingsRequest.persistentSettings(
229+
Settings.builder()
230+
.put(MIGRATION_DIRECTION_SETTING.getKey(), "remote_store")
231+
.put(REMOTE_STORE_COMPATIBILITY_MODE_SETTING.getKey(), "mixed")
232+
);
233+
assertAcked(client().admin().cluster().updateSettings(updateSettingsRequest).actionGet());
234+
235+
setAddRemote(true);
236+
internalCluster().startClusterManagerOnlyNode();
237+
ensureStableCluster(4);
238+
ensureGreen();
239+
}
240+
241+
public void testRemoteNodeWithRoutingTableJoiningPublishConfigCluster() throws Exception {
242+
Settings.Builder build = remotePublishConfiguredNodeSetting();
243+
internalCluster().startClusterManagerOnlyNode(build.build());
244+
internalCluster().startDataOnlyNodes(2, build.build());
245+
246+
ClusterUpdateSettingsRequest updateSettingsRequest = new ClusterUpdateSettingsRequest();
247+
updateSettingsRequest.persistentSettings(
248+
Settings.builder()
249+
.put(MIGRATION_DIRECTION_SETTING.getKey(), "remote_store")
250+
.put(REMOTE_STORE_COMPATIBILITY_MODE_SETTING.getKey(), "mixed")
251+
);
252+
253+
Settings settings = Settings.builder()
254+
.put(
255+
buildRemoteStoreNodeAttributes(
256+
REPOSITORY_NAME,
257+
segmentRepoPath,
258+
REPOSITORY_2_NAME,
259+
translogRepoPath,
260+
ROUTING_TABLE_REPO_NAME,
261+
segmentRepoPath,
262+
false
263+
)
264+
)
265+
.put(REMOTE_CLUSTER_STATE_ENABLED_SETTING.getKey(), true)
266+
.build();
267+
assertAcked(client().admin().cluster().updateSettings(updateSettingsRequest).actionGet());
268+
internalCluster().startClusterManagerOnlyNode(settings);
269+
270+
ensureStableCluster(4);
271+
ensureGreen();
272+
}
273+
}

server/src/internalClusterTest/java/org/opensearch/remotemigration/MigrationBaseTestCase.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import org.opensearch.test.OpenSearchIntegTestCase;
3939
import org.junit.Before;
4040

41-
import java.nio.file.Path;
4241
import java.util.HashMap;
4342
import java.util.List;
4443
import java.util.Map;
@@ -57,10 +56,10 @@
5756

5857
public class MigrationBaseTestCase extends OpenSearchIntegTestCase {
5958
protected static final String REPOSITORY_NAME = "test-remote-store-repo";
59+
protected static final String ROUTING_TABLE_REPO_NAME = "remote-routing-repo";
60+
6061
protected static final String REPOSITORY_2_NAME = "test-remote-store-repo-2";
6162

62-
protected Path segmentRepoPath;
63-
protected Path translogRepoPath;
6463
boolean addRemote = false;
6564
Settings extraSettings = Settings.EMPTY;
6665

@@ -72,7 +71,7 @@ public class MigrationBaseTestCase extends OpenSearchIntegTestCase {
7271
randomAlphaOfLength(5)
7372
);
7473

75-
void setAddRemote(boolean addRemote) {
74+
public void setAddRemote(boolean addRemote) {
7675
this.addRemote = addRemote;
7776
}
7877

@@ -97,7 +96,11 @@ protected Settings nodeSettings(int nodeOrdinal) {
9796
.build();
9897
} else {
9998
logger.info("Adding docrep node");
100-
return Settings.builder().put(super.nodeSettings(nodeOrdinal)).put(REMOTE_CLUSTER_STATE_ENABLED_SETTING.getKey(), true).build();
99+
return Settings.builder()
100+
.put(super.nodeSettings(nodeOrdinal))
101+
// .put(remoteStoreClusterSettings(REPOSITORY_NAME, segmentRepoPath, REPOSITORY_2_NAME, translogRepoPath))
102+
.put(REMOTE_CLUSTER_STATE_ENABLED_SETTING.getKey(), true)
103+
.build();
101104
}
102105
}
103106

server/src/main/java/org/opensearch/cluster/coordination/JoinTaskExecutor.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,9 +420,14 @@ public static void ensureIndexCompatibility(final Version nodeVersion, Metadata
420420
* ensures that the joining node has a version that's compatible with all current nodes
421421
*/
422422
public static void ensureNodesCompatibility(final DiscoveryNode joiningNode, DiscoveryNodes currentNodes, Metadata metadata) {
423-
final Version minNodeVersion = currentNodes.getMinNodeVersion();
424-
final Version maxNodeVersion = currentNodes.getMaxNodeVersion();
425-
ensureNodesCompatibility(joiningNode, currentNodes, metadata, minNodeVersion, maxNodeVersion);
423+
try {
424+
final Version minNodeVersion = currentNodes.getMinNodeVersion();
425+
final Version maxNodeVersion = currentNodes.getMaxNodeVersion();
426+
ensureNodesCompatibility(joiningNode, currentNodes, metadata, minNodeVersion, maxNodeVersion);
427+
} catch (Exception e) {
428+
logger.error("Exception in NodesCompatibility validation", e);
429+
throw e;
430+
}
426431
}
427432

428433
/**
@@ -539,9 +544,11 @@ private static void ensureRemoteStoreNodesCompatibility(DiscoveryNode joiningNod
539544
CompatibilityMode remoteStoreCompatibilityMode = REMOTE_STORE_COMPATIBILITY_MODE_SETTING.get(metadata.settings());
540545

541546
List<String> reposToSkip = new ArrayList<>(1);
547+
// find a remote node which has routing table configured
542548
Optional<DiscoveryNode> remoteRoutingTableNode = existingNodes.stream()
543549
.filter(
544550
node -> node.getAttributes().get(RemoteStoreNodeAttribute.REMOTE_STORE_ROUTING_TABLE_REPOSITORY_NAME_ATTRIBUTE_KEY) != null
551+
&& node.getAttributes().get(RemoteStoreNodeAttribute.REMOTE_STORE_SEGMENT_REPOSITORY_NAME_ATTRIBUTE_KEY) != null
545552
)
546553
.findFirst();
547554
// If none of the existing nodes have routing table repo, then we skip this repo check if present in joining node.

0 commit comments

Comments
 (0)