|
16 | 16 | import org.opensearch.action.admin.indices.stats.IndexStats; |
17 | 17 | import org.opensearch.action.admin.indices.stats.ShardStats; |
18 | 18 | import org.opensearch.action.admin.indices.streamingingestion.pause.PauseIngestionResponse; |
| 19 | +import org.opensearch.action.admin.indices.streamingingestion.resume.ResumeIngestionRequest; |
19 | 20 | import org.opensearch.action.admin.indices.streamingingestion.resume.ResumeIngestionResponse; |
20 | 21 | import org.opensearch.action.admin.indices.streamingingestion.state.GetIngestionStateResponse; |
21 | 22 | import org.opensearch.action.search.SearchResponse; |
@@ -254,8 +255,7 @@ public void testMultiThreadedWrites() throws Exception { |
254 | 255 | } |
255 | 256 |
|
256 | 257 | public void testAllActiveIngestion() throws Exception { |
257 | | - // Create pull-based index in default replication mode (docrep) and publish some messages |
258 | | - |
| 258 | + // Create all-active pull-based index |
259 | 259 | internalCluster().startClusterManagerOnlyNode(); |
260 | 260 | final String nodeA = internalCluster().startDataOnlyNode(); |
261 | 261 | for (int i = 0; i < 10; i++) { |
@@ -374,7 +374,7 @@ public void testAllActiveIngestion() throws Exception { |
374 | 374 | } |
375 | 375 |
|
376 | 376 | public void testReplicaPromotionOnAllActiveIngestion() throws Exception { |
377 | | - // Create pull-based index in default replication mode (docrep) and publish some messages |
| 377 | + // Create all-active pull-based index |
378 | 378 | internalCluster().startClusterManagerOnlyNode(); |
379 | 379 | final String nodeA = internalCluster().startDataOnlyNode(); |
380 | 380 | for (int i = 0; i < 10; i++) { |
@@ -425,7 +425,7 @@ public void testReplicaPromotionOnAllActiveIngestion() throws Exception { |
425 | 425 | } |
426 | 426 |
|
427 | 427 | public void testSnapshotRestoreOnAllActiveIngestion() throws Exception { |
428 | | - // Create pull-based index in default replication mode (docrep) and publish some messages |
| 428 | + // Create all-active pull-based index |
429 | 429 | internalCluster().startClusterManagerOnlyNode(); |
430 | 430 | final String nodeA = internalCluster().startDataOnlyNode(); |
431 | 431 | final String nodeB = internalCluster().startDataOnlyNode(); |
@@ -505,6 +505,68 @@ public void testSnapshotRestoreOnAllActiveIngestion() throws Exception { |
505 | 505 | assertThat(shardTypeToStats.get("replica").getConsumerStats().totalPollerMessageFailureCount(), is(0L)); |
506 | 506 | } |
507 | 507 |
|
| 508 | + public void testResetPollerInAllActiveIngestion() throws Exception { |
| 509 | + // Create all-active pull-based index |
| 510 | + internalCluster().startClusterManagerOnlyNode(); |
| 511 | + final String nodeA = internalCluster().startDataOnlyNode(); |
| 512 | + final String nodeB = internalCluster().startDataOnlyNode(); |
| 513 | + for (int i = 0; i < 10; i++) { |
| 514 | + produceData(Integer.toString(i), "name" + i, "30"); |
| 515 | + } |
| 516 | + |
| 517 | + createIndex( |
| 518 | + indexName, |
| 519 | + Settings.builder() |
| 520 | + .put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1) |
| 521 | + .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 1) |
| 522 | + .put("ingestion_source.type", "kafka") |
| 523 | + .put("ingestion_source.param.topic", topicName) |
| 524 | + .put("ingestion_source.param.bootstrap_servers", kafka.getBootstrapServers()) |
| 525 | + .put("ingestion_source.pointer.init.reset", "earliest") |
| 526 | + .put("ingestion_source.all_active", true) |
| 527 | + .build(), |
| 528 | + "{\"properties\":{\"name\":{\"type\": \"text\"},\"age\":{\"type\": \"integer\"}}}}" |
| 529 | + ); |
| 530 | + |
| 531 | + ensureGreen(indexName); |
| 532 | + waitForSearchableDocs(10, List.of(nodeA, nodeB)); |
| 533 | + |
| 534 | + // pause ingestion |
| 535 | + PauseIngestionResponse pauseResponse = pauseIngestion(indexName); |
| 536 | + assertTrue(pauseResponse.isAcknowledged()); |
| 537 | + assertTrue(pauseResponse.isShardsAcknowledged()); |
| 538 | + waitForState(() -> { |
| 539 | + GetIngestionStateResponse ingestionState = getIngestionState(indexName); |
| 540 | + return ingestionState.getShardStates().length == 2 |
| 541 | + && ingestionState.getFailedShards() == 0 |
| 542 | + && Arrays.stream(ingestionState.getShardStates()) |
| 543 | + .allMatch(state -> state.isPollerPaused() && state.getPollerState().equalsIgnoreCase("paused")); |
| 544 | + }); |
| 545 | + |
| 546 | + // reset to offset=2 and resume ingestion |
| 547 | + ResumeIngestionResponse resumeResponse = resumeIngestion(indexName, 0, ResumeIngestionRequest.ResetSettings.ResetMode.OFFSET, "2"); |
| 548 | + assertTrue(resumeResponse.isAcknowledged()); |
| 549 | + assertTrue(resumeResponse.isShardsAcknowledged()); |
| 550 | + waitForState(() -> { |
| 551 | + GetIngestionStateResponse ingestionState = getIngestionState(indexName); |
| 552 | + return ingestionState.getShardStates().length == 2 |
| 553 | + && Arrays.stream(ingestionState.getShardStates()) |
| 554 | + .allMatch( |
| 555 | + state -> state.isPollerPaused() == false |
| 556 | + && (state.getPollerState().equalsIgnoreCase("polling") || state.getPollerState().equalsIgnoreCase("processing")) |
| 557 | + ); |
| 558 | + }); |
| 559 | + |
| 560 | + // validate there are 8 duplicate messages encountered after reset |
| 561 | + waitForState(() -> { |
| 562 | + Map<String, PollingIngestStats> shardTypeToStats = getPollingIngestStatsForPrimaryAndReplica(indexName); |
| 563 | + assertNotNull(shardTypeToStats.get("primary")); |
| 564 | + assertNotNull(shardTypeToStats.get("replica")); |
| 565 | + return shardTypeToStats.get("primary").getConsumerStats().totalDuplicateMessageSkippedCount() == 8 |
| 566 | + && shardTypeToStats.get("replica").getConsumerStats().totalDuplicateMessageSkippedCount() == 8; |
| 567 | + }); |
| 568 | + } |
| 569 | + |
508 | 570 | // returns PollingIngestStats for single primary and single replica |
509 | 571 | private Map<String, PollingIngestStats> getPollingIngestStatsForPrimaryAndReplica(String indexName) { |
510 | 572 | IndexStats indexStats = client().admin().indices().prepareStats(indexName).get().getIndex(indexName); |
|
0 commit comments