Skip to content

Commit ace7752

Browse files
author
Shubh Sahu
committed
Added IT for ResizeIndex During migration
Signed-off-by: Shubh Sahu <shubhvs@amazon.com>
1 parent 6672cbe commit ace7752

File tree

3 files changed

+170
-41
lines changed

3 files changed

+170
-41
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
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.remotemigration;
10+
11+
import org.opensearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
12+
import org.opensearch.action.admin.indices.shrink.ResizeType;
13+
import org.opensearch.action.support.ActiveShardCount;
14+
import org.opensearch.client.Client;
15+
import org.opensearch.common.settings.Settings;
16+
import org.opensearch.indices.replication.common.ReplicationType;
17+
import org.opensearch.test.OpenSearchIntegTestCase;
18+
19+
import java.util.List;
20+
21+
import static org.opensearch.cluster.metadata.IndexMetadata.SETTING_REPLICATION_TYPE;
22+
import static org.opensearch.node.remotestore.RemoteStoreNodeService.MIGRATION_DIRECTION_SETTING;
23+
import static org.opensearch.node.remotestore.RemoteStoreNodeService.REMOTE_STORE_COMPATIBILITY_MODE_SETTING;
24+
import static org.opensearch.test.hamcrest.OpenSearchAssertions.assertAcked;
25+
26+
@OpenSearchIntegTestCase.ClusterScope(scope = OpenSearchIntegTestCase.Scope.TEST, numDataNodes = 0, autoManageMasterNodes = false)
27+
public class ResizeIndexMigrationTestCase extends MigrationBaseTestCase {
28+
private static final String TEST_INDEX = "test_index";
29+
private final static String REMOTE_STORE_DIRECTION = "remote_store";
30+
private final static String NONE_DIRECTION = "none";
31+
private final static String STRICT_MODE = "strict";
32+
private final static String MIXED_MODE = "mixed";
33+
34+
public void testFailResizeIndexWhileMigration() throws Exception {
35+
36+
internalCluster().setBootstrapClusterManagerNodeIndex(0);
37+
List<String> cmNodes = internalCluster().startNodes(1);
38+
Client client = internalCluster().client(cmNodes.get(0));
39+
ClusterUpdateSettingsRequest updateSettingsRequest = new ClusterUpdateSettingsRequest();
40+
updateSettingsRequest.persistentSettings(Settings.builder().put(REMOTE_STORE_COMPATIBILITY_MODE_SETTING.getKey(), MIXED_MODE));
41+
assertAcked(client().admin().cluster().updateSettings(updateSettingsRequest).actionGet());
42+
43+
// Adding a non remote and a remote node
44+
addRemote = false;
45+
String nonRemoteNodeName = internalCluster().startNode();
46+
47+
addRemote = true;
48+
String remoteNodeName = internalCluster().startNode();
49+
50+
logger.info("-->Create index on non-remote node and SETTING_REMOTE_STORE_ENABLED is false. Resize should not happen");
51+
Settings.Builder builder = Settings.builder().put(SETTING_REPLICATION_TYPE, ReplicationType.SEGMENT);
52+
client.admin()
53+
.indices()
54+
.prepareCreate(TEST_INDEX)
55+
.setSettings(
56+
builder.put("index.number_of_shards", 10)
57+
.put("index.number_of_replicas", 0)
58+
.put("index.routing.allocation.include._name", nonRemoteNodeName)
59+
.put("index.routing.allocation.exclude._name", remoteNodeName)
60+
)
61+
.setWaitForActiveShards(ActiveShardCount.ALL)
62+
.execute()
63+
.actionGet();
64+
65+
updateSettingsRequest.persistentSettings(Settings.builder().put(MIGRATION_DIRECTION_SETTING.getKey(), REMOTE_STORE_DIRECTION));
66+
assertAcked(client.admin().cluster().updateSettings(updateSettingsRequest).actionGet());
67+
68+
ResizeType resizeType;
69+
int resizeShardsNum;
70+
String cause;
71+
switch (randomIntBetween(0, 2)) {
72+
case 0:
73+
resizeType = ResizeType.SHRINK;
74+
resizeShardsNum = 5;
75+
cause = "shrink_index";
76+
break;
77+
case 1:
78+
resizeType = ResizeType.SPLIT;
79+
resizeShardsNum = 20;
80+
cause = "split_index";
81+
break;
82+
default:
83+
resizeType = ResizeType.CLONE;
84+
resizeShardsNum = 10;
85+
cause = "clone_index";
86+
}
87+
88+
client.admin()
89+
.indices()
90+
.prepareUpdateSettings(TEST_INDEX)
91+
.setSettings(Settings.builder().put("index.blocks.write", true))
92+
.execute()
93+
.actionGet();
94+
95+
ensureGreen(TEST_INDEX);
96+
97+
Settings.Builder resizeSettingsBuilder = Settings.builder()
98+
.put("index.number_of_replicas", 0)
99+
.put("index.number_of_shards", resizeShardsNum)
100+
.putNull("index.blocks.write");
101+
102+
IllegalStateException ex = expectThrows(
103+
IllegalStateException.class,
104+
() -> client().admin()
105+
.indices()
106+
.prepareResizeIndex(TEST_INDEX, "first_split")
107+
.setResizeType(resizeType)
108+
.setSettings(resizeSettingsBuilder.build())
109+
.get()
110+
);
111+
assertEquals(
112+
ex.getMessage(),
113+
"index Resizing for type ["
114+
+ resizeType
115+
+ "] is not allowed as Cluster mode is [Mixed]"
116+
+ " and migration direction is [Remote Store]"
117+
);
118+
}
119+
}

server/src/main/java/org/opensearch/action/admin/indices/shrink/TransportResizeAction.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@
5858
import org.opensearch.index.IndexSettings;
5959
import org.opensearch.index.shard.DocsStats;
6060
import org.opensearch.index.store.StoreStats;
61+
import org.opensearch.node.remotestore.RemoteStoreNodeService;
6162
import org.opensearch.threadpool.ThreadPool;
6263
import org.opensearch.transport.TransportService;
63-
import org.opensearch.node.remotestore.RemoteStoreNodeService;
6464

6565
import java.io.IOException;
6666
import java.util.Locale;
@@ -164,7 +164,7 @@ protected void clusterManagerOperation(
164164
CreateIndexClusterStateUpdateRequest updateRequest = prepareCreateIndexRequest(resizeRequest, state, i -> {
165165
IndexShardStats shard = indicesStatsResponse.getIndex(sourceIndex).getIndexShards().get(i);
166166
return shard == null ? null : shard.getPrimary().getDocs();
167-
}, indicesStatsResponse.getPrimaries().store, clusterSettings,sourceIndex, targetIndex);
167+
}, indicesStatsResponse.getPrimaries().store, clusterSettings, sourceIndex, targetIndex);
168168

169169
if (indicesStatsResponse.getIndex(sourceIndex)
170170
.getTotal()
@@ -235,7 +235,7 @@ static CreateIndexClusterStateUpdateRequest prepareCreateIndexRequest(
235235
if (metadata == null) {
236236
throw new IndexNotFoundException(sourceIndexName);
237237
}
238-
validateClusterModeSettings(resizeRequest.getResizeType(),metadata,clusterSettings);
238+
validateClusterModeSettings(resizeRequest.getResizeType(), metadata, clusterSettings);
239239
final Settings.Builder targetIndexSettingsBuilder = Settings.builder()
240240
.put(targetIndex.settings())
241241
.normalizePrefix(IndexMetadata.INDEX_SETTING_PREFIX);
@@ -374,15 +374,23 @@ protected String getClusterManagerActionName(DiscoveryNode node) {
374374
return super.getClusterManagerActionName(node);
375375
}
376376

377-
private static void validateClusterModeSettings(final ResizeType type,IndexMetadata sourceIndexMetadata,ClusterSettings clusterSettings) {
378-
boolean isMixed = clusterSettings.get(RemoteStoreNodeService.REMOTE_STORE_COMPATIBILITY_MODE_SETTING)
377+
private static void validateClusterModeSettings(
378+
final ResizeType type,
379+
IndexMetadata sourceIndexMetadata,
380+
ClusterSettings clusterSettings
381+
) {
382+
boolean isMixed = clusterSettings.get(RemoteStoreNodeService.REMOTE_STORE_COMPATIBILITY_MODE_SETTING)
379383
.equals(RemoteStoreNodeService.CompatibilityMode.MIXED);
380384
boolean isRemoteStoreMigrationDirection = clusterSettings.get(RemoteStoreNodeService.MIGRATION_DIRECTION_SETTING)
381385
.equals(RemoteStoreNodeService.Direction.REMOTE_STORE);
382-
boolean isRemoteStoreEnabled = sourceIndexMetadata.getSettings().getAsBoolean(SETTING_REMOTE_STORE_ENABLED, false);
386+
boolean isRemoteStoreEnabled = sourceIndexMetadata.getSettings().getAsBoolean(SETTING_REMOTE_STORE_ENABLED, false);
383387
if (isMixed && isRemoteStoreMigrationDirection && !isRemoteStoreEnabled) {
384-
throw new IllegalStateException("index Resizing for type [" + type + "] is not allowed as Cluster mode is [Mixed]"
385-
+ " and migration direction is [Remote Store]");
388+
throw new IllegalStateException(
389+
"index Resizing for type ["
390+
+ type
391+
+ "] is not allowed as Cluster mode is [Mixed]"
392+
+ " and migration direction is [Remote Store]"
393+
);
386394
}
387395
}
388396
}

server/src/test/java/org/opensearch/action/admin/indices/shrink/TransportResizeActionTests.java

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -55,30 +55,25 @@
5555
import org.opensearch.common.settings.Settings;
5656
import org.opensearch.common.util.FeatureFlags;
5757
import org.opensearch.core.common.unit.ByteSizeValue;
58-
import org.opensearch.index.query.Rewriteable;
59-
import org.opensearch.index.query.RewriteableTests;
6058
import org.opensearch.index.shard.DocsStats;
6159
import org.opensearch.index.store.StoreStats;
6260
import org.opensearch.node.remotestore.RemoteStoreNodeService;
6361
import org.opensearch.snapshots.EmptySnapshotsInfoService;
6462
import org.opensearch.test.OpenSearchTestCase;
6563
import org.opensearch.test.gateway.TestGatewayAllocator;
6664

67-
import static org.hamcrest.CoreMatchers.startsWith;
68-
import static org.hamcrest.Matchers.*;
69-
import static org.opensearch.cluster.metadata.IndexMetadata.SETTING_REMOTE_STORE_ENABLED;
70-
import static org.opensearch.node.remotestore.RemoteStoreNodeService.CompatibilityMode;
71-
72-
7365
import java.util.Arrays;
7466
import java.util.Collections;
7567
import java.util.HashSet;
7668
import java.util.Set;
7769

7870
import static java.util.Collections.emptyMap;
71+
import static org.opensearch.cluster.metadata.IndexMetadata.SETTING_REMOTE_STORE_ENABLED;
72+
import static org.opensearch.common.util.FeatureFlags.REMOTE_STORE_MIGRATION_EXPERIMENTAL;
73+
import static org.opensearch.node.remotestore.RemoteStoreNodeService.CompatibilityMode;
7974
import static org.opensearch.node.remotestore.RemoteStoreNodeService.MIGRATION_DIRECTION_SETTING;
8075
import static org.opensearch.node.remotestore.RemoteStoreNodeService.REMOTE_STORE_COMPATIBILITY_MODE_SETTING;
81-
import static org.opensearch.common.util.FeatureFlags.REMOTE_STORE_MIGRATION_EXPERIMENTAL;
76+
import static org.hamcrest.CoreMatchers.equalTo;
8277

8378
public class TransportResizeActionTests extends OpenSearchTestCase {
8479

@@ -108,10 +103,14 @@ private ClusterState createClusterState(String name, int numShards, int numRepli
108103
return clusterState;
109104
}
110105

111-
private ClusterSettings createClusterSettings(CompatibilityMode compatibilityMode, RemoteStoreNodeService.Direction migrationDirection) {
106+
private ClusterSettings createClusterSettings(
107+
CompatibilityMode compatibilityMode,
108+
RemoteStoreNodeService.Direction migrationDirection
109+
) {
112110
ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
113111
clusterSettings.applySettings(
114-
(Settings.builder().put(REMOTE_STORE_COMPATIBILITY_MODE_SETTING.getKey(), compatibilityMode)
112+
(Settings.builder()
113+
.put(REMOTE_STORE_COMPATIBILITY_MODE_SETTING.getKey(), compatibilityMode)
115114
.put(MIGRATION_DIRECTION_SETTING.getKey(), migrationDirection)).build()
116115
);
117116
return clusterSettings;
@@ -124,7 +123,7 @@ public void testErrorCondition() {
124123
randomIntBetween(0, 10),
125124
Settings.builder().put("index.blocks.write", true).build()
126125
);
127-
ClusterSettings clusterSettings = createClusterSettings(CompatibilityMode.STRICT,RemoteStoreNodeService.Direction.NONE);
126+
ClusterSettings clusterSettings = createClusterSettings(CompatibilityMode.STRICT, RemoteStoreNodeService.Direction.NONE);
128127
assertTrue(
129128
expectThrows(
130129
IllegalStateException.class,
@@ -216,7 +215,7 @@ public void testPassNumRoutingShards() {
216215
EmptyClusterInfoService.INSTANCE,
217216
EmptySnapshotsInfoService.INSTANCE
218217
);
219-
ClusterSettings clusterSettings = createClusterSettings(CompatibilityMode.STRICT,RemoteStoreNodeService.Direction.NONE);
218+
ClusterSettings clusterSettings = createClusterSettings(CompatibilityMode.STRICT, RemoteStoreNodeService.Direction.NONE);
220219
RoutingTable routingTable = service.reroute(clusterState, "reroute").routingTable();
221220
clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build();
222221
// now we start the shard
@@ -264,7 +263,7 @@ public void testPassNumRoutingShardsAndFail() {
264263
EmptySnapshotsInfoService.INSTANCE
265264
);
266265

267-
ClusterSettings clusterSettings = createClusterSettings(CompatibilityMode.STRICT,RemoteStoreNodeService.Direction.NONE);
266+
ClusterSettings clusterSettings = createClusterSettings(CompatibilityMode.STRICT, RemoteStoreNodeService.Direction.NONE);
268267
RoutingTable routingTable = service.reroute(clusterState, "reroute").routingTable();
269268
clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build();
270269
// now we start the shard
@@ -318,7 +317,7 @@ public void testShrinkIndexSettings() {
318317
EmptySnapshotsInfoService.INSTANCE
319318
);
320319

321-
ClusterSettings clusterSettings = createClusterSettings(CompatibilityMode.STRICT,RemoteStoreNodeService.Direction.NONE);
320+
ClusterSettings clusterSettings = createClusterSettings(CompatibilityMode.STRICT, RemoteStoreNodeService.Direction.NONE);
322321
RoutingTable routingTable = service.reroute(clusterState, "reroute").routingTable();
323322
clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build();
324323
// now we start the shard
@@ -360,7 +359,7 @@ public void testShrinkWithMaxShardSize() {
360359
EmptySnapshotsInfoService.INSTANCE
361360
);
362361

363-
ClusterSettings clusterSettings = createClusterSettings(CompatibilityMode.STRICT,RemoteStoreNodeService.Direction.NONE);
362+
ClusterSettings clusterSettings = createClusterSettings(CompatibilityMode.STRICT, RemoteStoreNodeService.Direction.NONE);
364363
RoutingTable routingTable = service.reroute(clusterState, "reroute").routingTable();
365364
clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build();
366365
// now we start the shard
@@ -516,7 +515,7 @@ public void testIndexBlocks() {
516515
createClusterState(indexName, 10, 0, 40, Settings.builder().put("index.blocks.read_only", true).build())
517516
).nodes(DiscoveryNodes.builder().add(newNode("node1"))).build();
518517

519-
ClusterSettings clusterSettings = createClusterSettings(CompatibilityMode.STRICT,RemoteStoreNodeService.Direction.NONE);
518+
ClusterSettings clusterSettings = createClusterSettings(CompatibilityMode.STRICT, RemoteStoreNodeService.Direction.NONE);
520519
// Target index will be blocked by [index.blocks.read_only=true] copied from the source index
521520
ResizeRequest resizeRequest = new ResizeRequest("target", indexName);
522521
ResizeType resizeType;
@@ -604,24 +603,27 @@ public void testIndexBlocks() {
604603
}
605604

606605
public void testResizeFailuresDuringMigration() {
607-
//We will keep all other settings correct for resize request,
608-
//So we only need to test for the failures due to cluster setting validation while migration
606+
// We will keep all other settings correct for resize request,
607+
// So we only need to test for the failures due to cluster setting validation while migration
609608
final Settings directionEnabledNodeSettings = Settings.builder().put(REMOTE_STORE_MIGRATION_EXPERIMENTAL, "true").build();
610609
FeatureFlags.initializeFeatureFlags(directionEnabledNodeSettings);
611610
boolean isRemoteStoreEnabled = randomBoolean();
612611
CompatibilityMode compatibilityMode = randomFrom(CompatibilityMode.values());
613612
RemoteStoreNodeService.Direction migrationDirection = randomFrom(RemoteStoreNodeService.Direction.values());
614-
//If not mixed mode, then migration direction is NONE.
615-
if(!compatibilityMode.equals(CompatibilityMode.MIXED)){
613+
// If not mixed mode, then migration direction is NONE.
614+
if (!compatibilityMode.equals(CompatibilityMode.MIXED)) {
616615
migrationDirection = RemoteStoreNodeService.Direction.NONE;
617616
}
618-
ClusterSettings clusterSettings = createClusterSettings(compatibilityMode,migrationDirection);
617+
ClusterSettings clusterSettings = createClusterSettings(compatibilityMode, migrationDirection);
619618

620619
ClusterState clusterState = ClusterState.builder(
621-
createClusterState("source", 10, 0,40,
622-
Settings.builder().put("index.blocks.write", true)
623-
.put(SETTING_REMOTE_STORE_ENABLED, isRemoteStoreEnabled)
624-
.build())
620+
createClusterState(
621+
"source",
622+
10,
623+
0,
624+
40,
625+
Settings.builder().put("index.blocks.write", true).put(SETTING_REMOTE_STORE_ENABLED, isRemoteStoreEnabled).build()
626+
)
625627
).nodes(DiscoveryNodes.builder().add(newNode("node1"))).build();
626628
AllocationService service = new AllocationService(
627629
new AllocationDeciders(Collections.singleton(new MaxRetryAllocationDecider())),
@@ -662,14 +664,14 @@ public void testResizeFailuresDuringMigration() {
662664
.settings(Settings.builder().put("index.number_of_shards", expectedShardsNum).put("index.blocks.read_only", false).build());
663665
final ActiveShardCount activeShardCount = randomBoolean() ? ActiveShardCount.ALL : ActiveShardCount.ONE;
664666
resizeRequest.setWaitForActiveShards(activeShardCount);
665-
//startsWith("index Resizing for type [")
667+
// startsWith("index Resizing for type [")
666668
if (compatibilityMode == CompatibilityMode.MIXED
667669
&& migrationDirection == RemoteStoreNodeService.Direction.REMOTE_STORE
668670
&& !isRemoteStoreEnabled) {
669671
ClusterState finalState = clusterState;
670672
IllegalStateException ise = expectThrows(
671673
IllegalStateException.class,
672-
() ->TransportResizeAction.prepareCreateIndexRequest(
674+
() -> TransportResizeAction.prepareCreateIndexRequest(
673675
new ResizeRequest("target", "source"),
674676
finalState,
675677
(i) -> stats,
@@ -679,12 +681,12 @@ public void testResizeFailuresDuringMigration() {
679681
"target"
680682
)
681683
);
682-
assertThat(
684+
assertEquals(
683685
ise.getMessage(),
684-
allOf(
685-
startsWith("index Resizing for type"),
686-
endsWith("Cluster mode is [Mixed] and migration direction is [Remote Store]")
687-
)
686+
"index Resizing for type ["
687+
+ resizeType
688+
+ "] is not allowed as Cluster mode is [Mixed]"
689+
+ " and migration direction is [Remote Store]"
688690
);
689691
} else {
690692
CreateIndexClusterStateUpdateRequest request = TransportResizeAction.prepareCreateIndexRequest(

0 commit comments

Comments
 (0)