|
7 | 7 | import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters;
|
8 | 8 | import com.carrotsearch.randomizedtesting.generators.RandomPicks;
|
9 | 9 |
|
| 10 | +import org.opensearch.action.admin.cluster.health.ClusterHealthResponse; |
10 | 11 | import org.opensearch.action.admin.cluster.node.stats.NodeStats;
|
11 | 12 | import org.opensearch.action.admin.cluster.node.stats.NodesStatsRequest;
|
12 | 13 | import org.opensearch.action.admin.cluster.node.stats.NodesStatsResponse;
|
|
25 | 26 | import org.opensearch.cluster.ClusterState;
|
26 | 27 | import org.opensearch.cluster.block.ClusterBlockException;
|
27 | 28 | import org.opensearch.cluster.metadata.IndexMetadata;
|
| 29 | +import org.opensearch.cluster.node.DiscoveryNode; |
28 | 30 | import org.opensearch.cluster.routing.GroupShardsIterator;
|
29 | 31 | import org.opensearch.cluster.routing.ShardIterator;
|
30 | 32 | import org.opensearch.cluster.routing.ShardRouting;
|
| 33 | +import org.opensearch.common.Priority; |
31 | 34 | import org.opensearch.common.io.PathUtils;
|
32 | 35 | import org.opensearch.common.settings.Settings;
|
| 36 | +import org.opensearch.common.unit.TimeValue; |
33 | 37 | import org.opensearch.core.common.unit.ByteSizeUnit;
|
34 | 38 | import org.opensearch.core.index.Index;
|
35 | 39 | import org.opensearch.index.IndexModule;
|
|
47 | 51 | import java.util.Arrays;
|
48 | 52 | import java.util.List;
|
49 | 53 | import java.util.Map;
|
| 54 | +import java.util.Set; |
| 55 | +import java.util.concurrent.TimeUnit; |
50 | 56 | import java.util.stream.Collectors;
|
51 | 57 | import java.util.stream.Stream;
|
52 | 58 | import java.util.stream.StreamSupport;
|
@@ -235,6 +241,62 @@ public void testSearchableSnapshotAllocationForLocalAndRemoteShardsOnSameNode()
|
235 | 241 | assertDocCount(indexName, 100L);
|
236 | 242 | }
|
237 | 243 |
|
| 244 | + public void testSearchableSnapshotAllocationFilterSettings() throws Exception { |
| 245 | + final int numShardsIndex = randomIntBetween(3, 6); |
| 246 | + final String indexName = "test-idx"; |
| 247 | + final String restoredIndexName = indexName + "-copy"; |
| 248 | + final String repoName = "test-repo"; |
| 249 | + final String snapshotName = "test-snap"; |
| 250 | + final Client client = client(); |
| 251 | + |
| 252 | + internalCluster().ensureAtLeastNumSearchAndDataNodes(numShardsIndex); |
| 253 | + createIndexWithDocsAndEnsureGreen(numShardsIndex, 1, 100, indexName); |
| 254 | + createRepositoryWithSettings(null, repoName); |
| 255 | + takeSnapshot(client, snapshotName, repoName, indexName); |
| 256 | + |
| 257 | + restoreSnapshotAndEnsureGreen(client, snapshotName, repoName); |
| 258 | + assertRemoteSnapshotIndexSettings(client, restoredIndexName); |
| 259 | + final Set<String> searchNodes = StreamSupport.stream(clusterService().state().getNodes().spliterator(), false) |
| 260 | + .filter(DiscoveryNode::isSearchNode) |
| 261 | + .map(DiscoveryNode::getId) |
| 262 | + .collect(Collectors.toSet()); |
| 263 | + |
| 264 | + for (int i = searchNodes.size(); i > 2; --i) { |
| 265 | + String pickedNode = randomFrom(searchNodes); |
| 266 | + searchNodes.remove(pickedNode); |
| 267 | + assertIndexAssignedToNodeOrNot(restoredIndexName, pickedNode, true); |
| 268 | + assertTrue( |
| 269 | + client.admin() |
| 270 | + .indices() |
| 271 | + .prepareUpdateSettings(restoredIndexName) |
| 272 | + .setSettings(Settings.builder().put("index.routing.allocation.exclude._id", pickedNode)) |
| 273 | + .execute() |
| 274 | + .actionGet() |
| 275 | + .isAcknowledged() |
| 276 | + ); |
| 277 | + ClusterHealthResponse clusterHealthResponse = client.admin() |
| 278 | + .cluster() |
| 279 | + .prepareHealth() |
| 280 | + .setWaitForEvents(Priority.LANGUID) |
| 281 | + .setWaitForNoRelocatingShards(true) |
| 282 | + .setTimeout(new TimeValue(5, TimeUnit.MINUTES)) |
| 283 | + .execute() |
| 284 | + .actionGet(); |
| 285 | + assertThat(clusterHealthResponse.isTimedOut(), equalTo(false)); |
| 286 | + assertIndexAssignedToNodeOrNot(restoredIndexName, pickedNode, false); |
| 287 | + assertIndexAssignedToNodeOrNot(indexName, pickedNode, true); |
| 288 | + } |
| 289 | + } |
| 290 | + |
| 291 | + private void assertIndexAssignedToNodeOrNot(String index, String node, boolean assigned) { |
| 292 | + final ClusterState state = clusterService().state(); |
| 293 | + if (assigned) { |
| 294 | + assertTrue(state.getRoutingTable().allShards(index).stream().anyMatch(shard -> shard.currentNodeId().equals(node))); |
| 295 | + } else { |
| 296 | + assertTrue(state.getRoutingTable().allShards(index).stream().noneMatch(shard -> shard.currentNodeId().equals(node))); |
| 297 | + } |
| 298 | + } |
| 299 | + |
238 | 300 | /**
|
239 | 301 | * Tests the functionality of remote shard allocation to
|
240 | 302 | * ensure it can handle node drops for failover scenarios and the cluster gets back to a healthy state when
|
@@ -342,11 +404,16 @@ public void testDeleteSearchableSnapshotBackingIndex() throws Exception {
|
342 | 404 | }
|
343 | 405 |
|
344 | 406 | private void createIndexWithDocsAndEnsureGreen(int numReplicasIndex, int numOfDocs, String indexName) throws InterruptedException {
|
| 407 | + createIndexWithDocsAndEnsureGreen(1, numReplicasIndex, numOfDocs, indexName); |
| 408 | + } |
| 409 | + |
| 410 | + private void createIndexWithDocsAndEnsureGreen(int numShardsIndex, int numReplicasIndex, int numOfDocs, String indexName) |
| 411 | + throws InterruptedException { |
345 | 412 | createIndex(
|
346 | 413 | indexName,
|
347 | 414 | Settings.builder()
|
348 |
| - .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, Integer.toString(numReplicasIndex)) |
349 |
| - .put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, "1") |
| 415 | + .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, numReplicasIndex) |
| 416 | + .put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, numShardsIndex) |
350 | 417 | .put(IndexModule.INDEX_STORE_TYPE_SETTING.getKey(), IndexModule.Type.FS.getSettingsKey())
|
351 | 418 | .build()
|
352 | 419 | );
|
|
0 commit comments