|
@@ -32,7 +32,6 @@ import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest
|
|
|
import org.elasticsearch.action.admin.indices.stats.ShardStats;
|
|
|
import org.elasticsearch.action.bulk.BulkProcessor;
|
|
|
import org.elasticsearch.action.bulk.BulkRequest;
|
|
|
-import org.elasticsearch.action.bulk.BulkRequestBuilder;
|
|
|
import org.elasticsearch.action.bulk.BulkResponse;
|
|
|
import org.elasticsearch.action.get.GetResponse;
|
|
|
import org.elasticsearch.action.index.IndexRequest;
|
|
@@ -61,6 +60,7 @@ import org.elasticsearch.persistent.PersistentTasksCustomMetaData;
|
|
|
import org.elasticsearch.rest.RestStatus;
|
|
|
import org.elasticsearch.snapshots.SnapshotRestoreException;
|
|
|
import org.elasticsearch.tasks.TaskInfo;
|
|
|
+import org.elasticsearch.test.BackgroundIndexer;
|
|
|
import org.elasticsearch.transport.NoSuchRemoteClusterException;
|
|
|
import org.elasticsearch.xpack.CcrIntegTestCase;
|
|
|
import org.elasticsearch.xpack.ccr.action.ShardFollowTask;
|
|
@@ -118,93 +118,85 @@ public class IndexFollowingIT extends CcrIntegTestCase {
|
|
|
} else {
|
|
|
firstBatchNumDocs = randomIntBetween(10, 64);
|
|
|
}
|
|
|
- final int flushPoint = (int) (firstBatchNumDocs * 0.75);
|
|
|
|
|
|
logger.info("Indexing [{}] docs as first batch", firstBatchNumDocs);
|
|
|
- BulkRequestBuilder bulkRequestBuilder = leaderClient().prepareBulk();
|
|
|
- for (int i = 0; i < flushPoint; i++) {
|
|
|
- final String source = String.format(Locale.ROOT, "{\"f\":%d}", i);
|
|
|
- IndexRequest indexRequest = new IndexRequest("index1", "doc", Integer.toString(i))
|
|
|
- .source(source, XContentType.JSON)
|
|
|
- .timeout(TimeValue.timeValueSeconds(1));
|
|
|
- bulkRequestBuilder.add(indexRequest);
|
|
|
- }
|
|
|
- bulkRequestBuilder.get();
|
|
|
-
|
|
|
- leaderClient().admin().indices().prepareFlush("index1").setWaitIfOngoing(true).get();
|
|
|
-
|
|
|
- // Index some docs after the flush that might be recovered in the normal index following operations
|
|
|
- for (int i = flushPoint; i < firstBatchNumDocs; i++) {
|
|
|
- final String source = String.format(Locale.ROOT, "{\"f\":%d}", i);
|
|
|
- leaderClient().prepareIndex("index1", "doc", Integer.toString(i)).setSource(source, XContentType.JSON).get();
|
|
|
- }
|
|
|
+ try (BackgroundIndexer indexer = new BackgroundIndexer("index1", "_doc", leaderClient(), firstBatchNumDocs,
|
|
|
+ randomIntBetween(1, 5))) {
|
|
|
+ waitForDocs(randomInt(firstBatchNumDocs), indexer);
|
|
|
+ leaderClient().admin().indices().prepareFlush("index1").setWaitIfOngoing(true).get();
|
|
|
+ waitForDocs(firstBatchNumDocs, indexer);
|
|
|
+ indexer.assertNoFailures();
|
|
|
|
|
|
- boolean waitOnAll = randomBoolean();
|
|
|
+ boolean waitOnAll = randomBoolean();
|
|
|
|
|
|
- final PutFollowAction.Request followRequest;
|
|
|
- if (waitOnAll) {
|
|
|
- followRequest = putFollow("index1", "index2", ActiveShardCount.ALL);
|
|
|
- } else {
|
|
|
- followRequest = putFollow("index1", "index2", ActiveShardCount.ONE);
|
|
|
- }
|
|
|
- PutFollowAction.Response response = followerClient().execute(PutFollowAction.INSTANCE, followRequest).get();
|
|
|
- assertTrue(response.isFollowIndexCreated());
|
|
|
- assertTrue(response.isFollowIndexShardsAcked());
|
|
|
- assertTrue(response.isIndexFollowingStarted());
|
|
|
-
|
|
|
- ClusterHealthRequest healthRequest = Requests.clusterHealthRequest("index2").waitForNoRelocatingShards(true);
|
|
|
- ClusterIndexHealth indexHealth = followerClient().admin().cluster().health(healthRequest).actionGet().getIndices().get("index2");
|
|
|
- for (ClusterShardHealth shardHealth : indexHealth.getShards().values()) {
|
|
|
+ final PutFollowAction.Request followRequest;
|
|
|
if (waitOnAll) {
|
|
|
- assertTrue(shardHealth.isPrimaryActive());
|
|
|
- assertEquals(1 + numberOfReplicas, shardHealth.getActiveShards());
|
|
|
+ followRequest = putFollow("index1", "index2", ActiveShardCount.ALL);
|
|
|
} else {
|
|
|
- assertTrue(shardHealth.isPrimaryActive());
|
|
|
+ followRequest = putFollow("index1", "index2", ActiveShardCount.ONE);
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- final Map<ShardId, Long> firstBatchNumDocsPerShard = new HashMap<>();
|
|
|
- final ShardStats[] firstBatchShardStats =
|
|
|
- leaderClient().admin().indices().prepareStats("index1").get().getIndex("index1").getShards();
|
|
|
- for (final ShardStats shardStats : firstBatchShardStats) {
|
|
|
- if (shardStats.getShardRouting().primary()) {
|
|
|
- long value = shardStats.getStats().getIndexing().getTotal().getIndexCount() - 1;
|
|
|
- firstBatchNumDocsPerShard.put(shardStats.getShardRouting().shardId(), value);
|
|
|
+ PutFollowAction.Response response = followerClient().execute(PutFollowAction.INSTANCE, followRequest).get();
|
|
|
+ assertTrue(response.isFollowIndexCreated());
|
|
|
+ assertTrue(response.isFollowIndexShardsAcked());
|
|
|
+ assertTrue(response.isIndexFollowingStarted());
|
|
|
+
|
|
|
+ ClusterHealthRequest healthRequest = Requests.clusterHealthRequest("index2").waitForNoRelocatingShards(true);
|
|
|
+ ClusterIndexHealth indexHealth = followerClient().admin().cluster().health(healthRequest).get().getIndices().get("index2");
|
|
|
+ for (ClusterShardHealth shardHealth : indexHealth.getShards().values()) {
|
|
|
+ if (waitOnAll) {
|
|
|
+ assertTrue(shardHealth.isPrimaryActive());
|
|
|
+ assertEquals(1 + numberOfReplicas, shardHealth.getActiveShards());
|
|
|
+ } else {
|
|
|
+ assertTrue(shardHealth.isPrimaryActive());
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- assertBusy(assertTask(numberOfPrimaryShards, firstBatchNumDocsPerShard));
|
|
|
+ final Map<ShardId, Long> firstBatchNumDocsPerShard = new HashMap<>();
|
|
|
+ final ShardStats[] firstBatchShardStats =
|
|
|
+ leaderClient().admin().indices().prepareStats("index1").get().getIndex("index1").getShards();
|
|
|
+ for (final ShardStats shardStats : firstBatchShardStats) {
|
|
|
+ if (shardStats.getShardRouting().primary()) {
|
|
|
+ long value = shardStats.getStats().getIndexing().getTotal().getIndexCount() - 1;
|
|
|
+ firstBatchNumDocsPerShard.put(shardStats.getShardRouting().shardId(), value);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- for (int i = 0; i < firstBatchNumDocs; i++) {
|
|
|
- assertBusy(assertExpectedDocumentRunnable(i));
|
|
|
- }
|
|
|
+ assertBusy(assertTask(numberOfPrimaryShards, firstBatchNumDocsPerShard));
|
|
|
|
|
|
- pauseFollow("index2");
|
|
|
- followerClient().execute(ResumeFollowAction.INSTANCE, resumeFollow("index2")).get();
|
|
|
- final int secondBatchNumDocs = randomIntBetween(2, 64);
|
|
|
- logger.info("Indexing [{}] docs as second batch", secondBatchNumDocs);
|
|
|
- for (int i = firstBatchNumDocs; i < firstBatchNumDocs + secondBatchNumDocs; i++) {
|
|
|
- final String source = String.format(Locale.ROOT, "{\"f\":%d}", i);
|
|
|
- leaderClient().prepareIndex("index1", "doc", Integer.toString(i)).setSource(source, XContentType.JSON).get();
|
|
|
- }
|
|
|
+ for (String docId : indexer.getIds()) {
|
|
|
+ assertBusy(() -> {
|
|
|
+ final GetResponse getResponse = followerClient().prepareGet("index2", "_doc", docId).get();
|
|
|
+ assertTrue("Doc with id [" + docId + "] is missing", getResponse.isExists());
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
- final Map<ShardId, Long> secondBatchNumDocsPerShard = new HashMap<>();
|
|
|
- final ShardStats[] secondBatchShardStats =
|
|
|
- leaderClient().admin().indices().prepareStats("index1").get().getIndex("index1").getShards();
|
|
|
- for (final ShardStats shardStats : secondBatchShardStats) {
|
|
|
- if (shardStats.getShardRouting().primary()) {
|
|
|
- final long value = shardStats.getStats().getIndexing().getTotal().getIndexCount() - 1;
|
|
|
- secondBatchNumDocsPerShard.put(shardStats.getShardRouting().shardId(), value);
|
|
|
+ pauseFollow("index2");
|
|
|
+ followerClient().execute(ResumeFollowAction.INSTANCE, resumeFollow("index2")).get();
|
|
|
+ final int secondBatchNumDocs = randomIntBetween(2, 64);
|
|
|
+ logger.info("Indexing [{}] docs as second batch", secondBatchNumDocs);
|
|
|
+ indexer.continueIndexing(secondBatchNumDocs);
|
|
|
+
|
|
|
+ final Map<ShardId, Long> secondBatchNumDocsPerShard = new HashMap<>();
|
|
|
+ final ShardStats[] secondBatchShardStats =
|
|
|
+ leaderClient().admin().indices().prepareStats("index1").get().getIndex("index1").getShards();
|
|
|
+ for (final ShardStats shardStats : secondBatchShardStats) {
|
|
|
+ if (shardStats.getShardRouting().primary()) {
|
|
|
+ final long value = shardStats.getStats().getIndexing().getTotal().getIndexCount() - 1;
|
|
|
+ secondBatchNumDocsPerShard.put(shardStats.getShardRouting().shardId(), value);
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- assertBusy(assertTask(numberOfPrimaryShards, secondBatchNumDocsPerShard));
|
|
|
+ assertBusy(assertTask(numberOfPrimaryShards, secondBatchNumDocsPerShard));
|
|
|
|
|
|
- for (int i = firstBatchNumDocs; i < firstBatchNumDocs + secondBatchNumDocs; i++) {
|
|
|
- assertBusy(assertExpectedDocumentRunnable(i));
|
|
|
+ for (String docId : indexer.getIds()) {
|
|
|
+ assertBusy(() -> {
|
|
|
+ final GetResponse getResponse = followerClient().prepareGet("index2", "_doc", docId).get();
|
|
|
+ assertTrue("Doc with id [" + docId + "] is missing", getResponse.isExists());
|
|
|
+ });
|
|
|
+ }
|
|
|
+ pauseFollow("index2");
|
|
|
+ assertMaxSeqNoOfUpdatesIsTransferred(resolveLeaderIndex("index1"), resolveFollowerIndex("index2"), numberOfPrimaryShards);
|
|
|
}
|
|
|
- pauseFollow("index2");
|
|
|
- assertMaxSeqNoOfUpdatesIsTransferred(resolveLeaderIndex("index1"), resolveFollowerIndex("index2"), numberOfPrimaryShards);
|
|
|
}
|
|
|
|
|
|
public void testFollowIndexWithConcurrentMappingChanges() throws Exception {
|