Search in sources :

Example 11 with DiscoveryNode

use of org.opensearch.cluster.node.DiscoveryNode in project OpenSearch by opensearch-project.

the class ShrinkIndexIT method testShrinkCommitsMergeOnIdle.

public void testShrinkCommitsMergeOnIdle() throws Exception {
    prepareCreate("source").setSettings(Settings.builder().put(indexSettings()).put("index.number_of_replicas", 0).put("number_of_shards", 5)).get();
    for (int i = 0; i < 30; i++) {
        client().prepareIndex("source").setSource("{\"foo\" : \"bar\", \"i\" : " + i + "}", XContentType.JSON).get();
    }
    client().admin().indices().prepareFlush("source").get();
    ImmutableOpenMap<String, DiscoveryNode> dataNodes = client().admin().cluster().prepareState().get().getState().nodes().getDataNodes();
    DiscoveryNode[] discoveryNodes = dataNodes.values().toArray(DiscoveryNode.class);
    // ensure all shards are allocated otherwise the ensure green below might not succeed since we require the merge node
    // if we change the setting too quickly we will end up with one replica unassigned which can't be assigned anymore due
    // to the require._name below.
    ensureGreen();
    // relocate all shards to one node such that we can merge it.
    client().admin().indices().prepareUpdateSettings("source").setSettings(Settings.builder().put("index.routing.allocation.require._name", discoveryNodes[0].getName()).put("index.blocks.write", true)).get();
    ensureGreen();
    IndicesSegmentResponse sourceStats = client().admin().indices().prepareSegments("source").get();
    // disable rebalancing to be able to capture the right stats. balancing can move the target primary
    // making it hard to pin point the source shards.
    client().admin().cluster().prepareUpdateSettings().setTransientSettings(Settings.builder().put(EnableAllocationDecider.CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING.getKey(), "none")).get();
    // now merge source into a single shard index
    assertAcked(client().admin().indices().prepareResizeIndex("source", "target").setSettings(Settings.builder().put("index.number_of_replicas", 0).build()).get());
    ensureGreen();
    ClusterStateResponse clusterStateResponse = client().admin().cluster().prepareState().get();
    IndexMetadata target = clusterStateResponse.getState().getMetadata().index("target");
    client().admin().indices().prepareForceMerge("target").setMaxNumSegments(1).setFlush(false).get();
    IndicesSegmentResponse targetSegStats = client().admin().indices().prepareSegments("target").get();
    ShardSegments segmentsStats = targetSegStats.getIndices().get("target").getShards().get(0).getShards()[0];
    assertTrue(segmentsStats.getNumberOfCommitted() > 0);
    assertNotEquals(segmentsStats.getSegments(), segmentsStats.getNumberOfCommitted());
    Iterable<IndicesService> dataNodeInstances = internalCluster().getDataNodeInstances(IndicesService.class);
    for (IndicesService service : dataNodeInstances) {
        if (service.hasIndex(target.getIndex())) {
            IndexService indexShards = service.indexService(target.getIndex());
            IndexShard shard = indexShards.getShard(0);
            assertTrue(shard.isActive());
            shard.flushOnIdle(0);
            assertFalse(shard.isActive());
        }
    }
    assertBusy(() -> {
        IndicesSegmentResponse targetStats = client().admin().indices().prepareSegments("target").get();
        ShardSegments targetShardSegments = targetStats.getIndices().get("target").getShards().get(0).getShards()[0];
        Map<Integer, IndexShardSegments> source = sourceStats.getIndices().get("source").getShards();
        int numSourceSegments = 0;
        for (IndexShardSegments s : source.values()) {
            numSourceSegments += s.getAt(0).getNumberOfCommitted();
        }
        assertTrue(targetShardSegments.getSegments().size() < numSourceSegments);
        assertEquals(targetShardSegments.getNumberOfCommitted(), targetShardSegments.getNumberOfSearch());
        assertEquals(targetShardSegments.getNumberOfCommitted(), targetShardSegments.getSegments().size());
        assertEquals(1, targetShardSegments.getSegments().size());
    });
    // clean up
    client().admin().cluster().prepareUpdateSettings().setTransientSettings(Settings.builder().put(EnableAllocationDecider.CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING.getKey(), (String) null)).get();
}
Also used : DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) IndexService(org.opensearch.index.IndexService) ClusterStateResponse(org.opensearch.action.admin.cluster.state.ClusterStateResponse) IndexShard(org.opensearch.index.shard.IndexShard) IndicesService(org.opensearch.indices.IndicesService) IndicesSegmentResponse(org.opensearch.action.admin.indices.segments.IndicesSegmentResponse) Matchers.containsString(org.hamcrest.Matchers.containsString) IndexShardSegments(org.opensearch.action.admin.indices.segments.IndexShardSegments) ShardSegments(org.opensearch.action.admin.indices.segments.ShardSegments) IndexShardSegments(org.opensearch.action.admin.indices.segments.IndexShardSegments) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata)

Example 12 with DiscoveryNode

use of org.opensearch.cluster.node.DiscoveryNode in project OpenSearch by opensearch-project.

the class ShrinkIndexIT method testCreateShrinkIndex.

public void testCreateShrinkIndex() {
    internalCluster().ensureAtLeastNumDataNodes(2);
    Version version = VersionUtils.randomVersion(random());
    prepareCreate("source").setSettings(Settings.builder().put(indexSettings()).put("number_of_shards", randomIntBetween(2, 7)).put("index.version.created", version)).get();
    final int docs = randomIntBetween(0, 128);
    for (int i = 0; i < docs; i++) {
        client().prepareIndex("source").setSource("{\"foo\" : \"bar\", \"i\" : " + i + "}", XContentType.JSON).get();
    }
    ImmutableOpenMap<String, DiscoveryNode> dataNodes = client().admin().cluster().prepareState().get().getState().nodes().getDataNodes();
    assertTrue("at least 2 nodes but was: " + dataNodes.size(), dataNodes.size() >= 2);
    DiscoveryNode[] discoveryNodes = dataNodes.values().toArray(DiscoveryNode.class);
    // ensure all shards are allocated otherwise the ensure green below might not succeed since we require the merge node
    // if we change the setting too quickly we will end up with one replica unassigned which can't be assigned anymore due
    // to the require._name below.
    ensureGreen();
    // relocate all shards to one node such that we can merge it.
    client().admin().indices().prepareUpdateSettings("source").setSettings(Settings.builder().put("index.routing.allocation.require._name", discoveryNodes[0].getName()).put("index.blocks.write", true)).get();
    ensureGreen();
    final IndicesStatsResponse sourceStats = client().admin().indices().prepareStats("source").setSegments(true).get();
    // disable rebalancing to be able to capture the right stats. balancing can move the target primary
    // making it hard to pin point the source shards.
    client().admin().cluster().prepareUpdateSettings().setTransientSettings(Settings.builder().put(EnableAllocationDecider.CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING.getKey(), "none")).get();
    // now merge source into a single shard index
    final boolean createWithReplicas = randomBoolean();
    assertAcked(client().admin().indices().prepareResizeIndex("source", "target").setSettings(Settings.builder().put("index.number_of_replicas", createWithReplicas ? 1 : 0).putNull("index.blocks.write").putNull("index.routing.allocation.require._name").build()).get());
    ensureGreen();
    // resolve true merge node - this is not always the node we required as all shards may be on another node
    final ClusterState state = client().admin().cluster().prepareState().get().getState();
    DiscoveryNode mergeNode = state.nodes().get(state.getRoutingTable().index("target").shard(0).primaryShard().currentNodeId());
    logger.info("merge node {}", mergeNode);
    final long maxSeqNo = Arrays.stream(sourceStats.getShards()).filter(shard -> shard.getShardRouting().currentNodeId().equals(mergeNode.getId())).map(ShardStats::getSeqNoStats).mapToLong(SeqNoStats::getMaxSeqNo).max().getAsLong();
    final long maxUnsafeAutoIdTimestamp = Arrays.stream(sourceStats.getShards()).filter(shard -> shard.getShardRouting().currentNodeId().equals(mergeNode.getId())).map(ShardStats::getStats).map(CommonStats::getSegments).mapToLong(SegmentsStats::getMaxUnsafeAutoIdTimestamp).max().getAsLong();
    final IndicesStatsResponse targetStats = client().admin().indices().prepareStats("target").get();
    for (final ShardStats shardStats : targetStats.getShards()) {
        final SeqNoStats seqNoStats = shardStats.getSeqNoStats();
        final ShardRouting shardRouting = shardStats.getShardRouting();
        assertThat("failed on " + shardRouting, seqNoStats.getMaxSeqNo(), equalTo(maxSeqNo));
        assertThat("failed on " + shardRouting, seqNoStats.getLocalCheckpoint(), equalTo(maxSeqNo));
        assertThat("failed on " + shardRouting, shardStats.getStats().getSegments().getMaxUnsafeAutoIdTimestamp(), equalTo(maxUnsafeAutoIdTimestamp));
    }
    final int size = docs > 0 ? 2 * docs : 1;
    assertHitCount(client().prepareSearch("target").setSize(size).setQuery(new TermsQueryBuilder("foo", "bar")).get(), docs);
    if (createWithReplicas == false) {
        // bump replicas
        client().admin().indices().prepareUpdateSettings("target").setSettings(Settings.builder().put("index.number_of_replicas", 1)).get();
        ensureGreen();
        assertHitCount(client().prepareSearch("target").setSize(size).setQuery(new TermsQueryBuilder("foo", "bar")).get(), docs);
    }
    for (int i = docs; i < 2 * docs; i++) {
        client().prepareIndex("target").setSource("{\"foo\" : \"bar\", \"i\" : " + i + "}", XContentType.JSON).get();
    }
    flushAndRefresh();
    assertHitCount(client().prepareSearch("target").setSize(2 * size).setQuery(new TermsQueryBuilder("foo", "bar")).get(), 2 * docs);
    assertHitCount(client().prepareSearch("source").setSize(size).setQuery(new TermsQueryBuilder("foo", "bar")).get(), docs);
    GetSettingsResponse target = client().admin().indices().prepareGetSettings("target").get();
    assertEquals(version, target.getIndexToSettings().get("target").getAsVersion("index.version.created", null));
    // clean up
    client().admin().cluster().prepareUpdateSettings().setTransientSettings(Settings.builder().put(EnableAllocationDecider.CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING.getKey(), (String) null)).get();
}
Also used : CommonStats(org.opensearch.action.admin.indices.stats.CommonStats) ImmutableOpenMap(org.opensearch.common.collect.ImmutableOpenMap) SeqNoStats(org.opensearch.index.seqno.SeqNoStats) Arrays(java.util.Arrays) EnableAllocationDecider(org.opensearch.cluster.routing.allocation.decider.EnableAllocationDecider) ClusterStateResponse(org.opensearch.action.admin.cluster.state.ClusterStateResponse) Version(org.opensearch.Version) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) MapperService(org.opensearch.index.mapper.MapperService) OpenSearchAssertions.assertHitCount(org.opensearch.test.hamcrest.OpenSearchAssertions.assertHitCount) ClusterRerouteResponse(org.opensearch.action.admin.cluster.reroute.ClusterRerouteResponse) Map(java.util.Map) SortField(org.apache.lucene.search.SortField) SegmentsStats(org.opensearch.index.engine.SegmentsStats) UnassignedInfo(org.opensearch.cluster.routing.UnassignedInfo) Client(org.opensearch.client.Client) TimeValue(org.opensearch.common.unit.TimeValue) Sort(org.apache.lucene.search.Sort) Index(org.opensearch.index.Index) IndicesService(org.opensearch.indices.IndicesService) SortedSetSortField(org.apache.lucene.search.SortedSetSortField) Settings(org.opensearch.common.settings.Settings) InternalClusterInfoService(org.opensearch.cluster.InternalClusterInfoService) Matchers.equalTo(org.hamcrest.Matchers.equalTo) TermsQueryBuilder(org.opensearch.index.query.TermsQueryBuilder) IndicesStatsResponse(org.opensearch.action.admin.indices.stats.IndicesStatsResponse) XContentType(org.opensearch.common.xcontent.XContentType) OpenSearchIntegTestCase(org.opensearch.test.OpenSearchIntegTestCase) Matchers.containsString(org.hamcrest.Matchers.containsString) IntStream(java.util.stream.IntStream) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) ClusterInfoService(org.opensearch.cluster.ClusterInfoService) Priority(org.opensearch.common.Priority) InternalTestCluster(org.opensearch.test.InternalTestCluster) ClusterState(org.opensearch.cluster.ClusterState) IndexShard(org.opensearch.index.shard.IndexShard) VersionUtils(org.opensearch.test.VersionUtils) Murmur3HashFunction(org.opensearch.cluster.routing.Murmur3HashFunction) OpenSearchAssertions.assertAcked(org.opensearch.test.hamcrest.OpenSearchAssertions.assertAcked) ShardSegments(org.opensearch.action.admin.indices.segments.ShardSegments) ResizeType(org.opensearch.action.admin.indices.shrink.ResizeType) Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) IndexShardSegments(org.opensearch.action.admin.indices.segments.IndexShardSegments) GetSettingsResponse(org.opensearch.action.admin.indices.settings.get.GetSettingsResponse) IndexService(org.opensearch.index.IndexService) ActiveShardCount(org.opensearch.action.support.ActiveShardCount) ShardRouting(org.opensearch.cluster.routing.ShardRouting) ClusterStateRequest(org.opensearch.action.admin.cluster.state.ClusterStateRequest) Constants(org.apache.lucene.util.Constants) SortedSetSelector(org.apache.lucene.search.SortedSetSelector) RoutingTable(org.opensearch.cluster.routing.RoutingTable) ShardStats(org.opensearch.action.admin.indices.stats.ShardStats) IndexRequest(org.opensearch.action.index.IndexRequest) IndicesSegmentResponse(org.opensearch.action.admin.indices.segments.IndicesSegmentResponse) ShardStats(org.opensearch.action.admin.indices.stats.ShardStats) IndicesStatsResponse(org.opensearch.action.admin.indices.stats.IndicesStatsResponse) ClusterState(org.opensearch.cluster.ClusterState) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) GetSettingsResponse(org.opensearch.action.admin.indices.settings.get.GetSettingsResponse) Matchers.containsString(org.hamcrest.Matchers.containsString) SegmentsStats(org.opensearch.index.engine.SegmentsStats) SeqNoStats(org.opensearch.index.seqno.SeqNoStats) Version(org.opensearch.Version) TermsQueryBuilder(org.opensearch.index.query.TermsQueryBuilder) ShardRouting(org.opensearch.cluster.routing.ShardRouting)

Example 13 with DiscoveryNode

use of org.opensearch.cluster.node.DiscoveryNode in project OpenSearch by opensearch-project.

the class RetentionLeaseIT method testRetentionLeasesSyncOnRecovery.

public void testRetentionLeasesSyncOnRecovery() throws Exception {
    final int numberOfReplicas = 2 - scaledRandomIntBetween(0, 2);
    internalCluster().ensureAtLeastNumDataNodes(1 + numberOfReplicas);
    /*
         * We effectively disable the background sync to ensure that the retention leases are not synced in the background so that the only
         * source of retention leases on the replicas would be from recovery.
         */
    final Settings.Builder settings = Settings.builder().put("index.number_of_shards", 1).put("index.number_of_replicas", 0).put(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), true).put(IndexService.RETENTION_LEASE_SYNC_INTERVAL_SETTING.getKey(), TimeValue.timeValueHours(24));
    // when we increase the number of replicas below we want to exclude the replicas from being allocated so that they do not recover
    assertAcked(prepareCreate("index", 1, settings));
    ensureYellow("index");
    final AcknowledgedResponse response = client().admin().indices().prepareUpdateSettings("index").setSettings(Settings.builder().put("index.number_of_replicas", numberOfReplicas).build()).get();
    assertTrue(response.isAcknowledged());
    final String primaryShardNodeId = clusterService().state().routingTable().index("index").shard(0).primaryShard().currentNodeId();
    final String primaryShardNodeName = clusterService().state().nodes().get(primaryShardNodeId).getName();
    final IndexShard primary = internalCluster().getInstance(IndicesService.class, primaryShardNodeName).getShardOrNull(new ShardId(resolveIndex("index"), 0));
    final int length = randomIntBetween(1, 8);
    final Map<String, RetentionLease> currentRetentionLeases = new LinkedHashMap<>();
    logger.info("adding retention [{}}] leases", length);
    for (int i = 0; i < length; i++) {
        final String id = randomValueOtherThanMany(currentRetentionLeases.keySet()::contains, () -> randomAlphaOfLength(8));
        final long retainingSequenceNumber = randomLongBetween(0, Long.MAX_VALUE);
        final String source = randomAlphaOfLength(8);
        final CountDownLatch latch = new CountDownLatch(1);
        final ActionListener<ReplicationResponse> listener = countDownLatchListener(latch);
        currentRetentionLeases.put(id, primary.addRetentionLease(id, retainingSequenceNumber, source, listener));
        latch.await();
    }
    logger.info("finished adding [{}] retention leases", length);
    // cause some recoveries to fail to ensure that retention leases are handled properly when retrying a recovery
    assertAcked(client().admin().cluster().prepareUpdateSettings().setPersistentSettings(Settings.builder().put(INDICES_RECOVERY_RETRY_DELAY_NETWORK_SETTING.getKey(), TimeValue.timeValueMillis(100))));
    final Semaphore recoveriesToDisrupt = new Semaphore(scaledRandomIntBetween(0, 4));
    final MockTransportService primaryTransportService = (MockTransportService) internalCluster().getInstance(TransportService.class, primaryShardNodeName);
    primaryTransportService.addSendBehavior((connection, requestId, action, request, options) -> {
        if (action.equals(PeerRecoveryTargetService.Actions.FINALIZE) && recoveriesToDisrupt.tryAcquire()) {
            if (randomBoolean()) {
                // return a ConnectTransportException to the START_RECOVERY action
                final TransportService replicaTransportService = internalCluster().getInstance(TransportService.class, connection.getNode().getName());
                final DiscoveryNode primaryNode = primaryTransportService.getLocalNode();
                replicaTransportService.disconnectFromNode(primaryNode);
                replicaTransportService.connectToNode(primaryNode);
            } else {
                // return an exception to the FINALIZE action
                throw new OpenSearchException("failing recovery for test purposes");
            }
        }
        connection.sendRequest(requestId, action, request, options);
    });
    logger.info("allow [{}] replicas to allocate", numberOfReplicas);
    // now allow the replicas to be allocated and wait for recovery to finalize
    allowNodes("index", 1 + numberOfReplicas);
    ensureGreen("index");
    // check current retention leases have been synced to all replicas
    for (final ShardRouting replicaShard : clusterService().state().routingTable().index("index").shard(0).replicaShards()) {
        final String replicaShardNodeId = replicaShard.currentNodeId();
        final String replicaShardNodeName = clusterService().state().nodes().get(replicaShardNodeId).getName();
        final IndexShard replica = internalCluster().getInstance(IndicesService.class, replicaShardNodeName).getShardOrNull(new ShardId(resolveIndex("index"), 0));
        final Map<String, RetentionLease> retentionLeasesOnReplica = RetentionLeaseUtils.toMapExcludingPeerRecoveryRetentionLeases(replica.getRetentionLeases());
        assertThat(retentionLeasesOnReplica, equalTo(currentRetentionLeases));
        // check retention leases have been written on the replica; see RecoveryTarget#finalizeRecovery
        assertThat(currentRetentionLeases, equalTo(RetentionLeaseUtils.toMapExcludingPeerRecoveryRetentionLeases(replica.loadRetentionLeases())));
    }
}
Also used : DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) MockTransportService(org.opensearch.test.transport.MockTransportService) IndexShard(org.opensearch.index.shard.IndexShard) AcknowledgedResponse(org.opensearch.action.support.master.AcknowledgedResponse) IndicesService(org.opensearch.indices.IndicesService) Semaphore(java.util.concurrent.Semaphore) CountDownLatch(java.util.concurrent.CountDownLatch) LinkedHashMap(java.util.LinkedHashMap) ReplicationResponse(org.opensearch.action.support.replication.ReplicationResponse) ShardId(org.opensearch.index.shard.ShardId) MockTransportService(org.opensearch.test.transport.MockTransportService) TransportService(org.opensearch.transport.TransportService) OpenSearchException(org.opensearch.OpenSearchException) ShardRouting(org.opensearch.cluster.routing.ShardRouting) Settings(org.opensearch.common.settings.Settings) IndexSettings(org.opensearch.index.IndexSettings)

Example 14 with DiscoveryNode

use of org.opensearch.cluster.node.DiscoveryNode in project OpenSearch by opensearch-project.

the class ShardIndexingPressureSettingsIT method testNodeAttributeSetForShardIndexingPressure.

public void testNodeAttributeSetForShardIndexingPressure() throws Exception {
    assertAcked(prepareCreate(INDEX_NAME, Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1).put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 1)));
    ensureGreen(INDEX_NAME);
    for (DiscoveryNode nodes : client().admin().cluster().prepareState().get().getState().nodes()) {
        assertEquals("true", nodes.getAttributes().get("shard_indexing_pressure_enabled"));
    }
}
Also used : DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode)

Example 15 with DiscoveryNode

use of org.opensearch.cluster.node.DiscoveryNode in project OpenSearch by opensearch-project.

the class ReplicaShardAllocatorIT method testRecentPrimaryInformation.

/**
 * Ensure that we fetch the latest shard store from the primary when a new node joins so we won't cancel the current recovery
 * for the copy on the newly joined node unless we can perform a noop recovery with that node.
 */
public void testRecentPrimaryInformation() throws Exception {
    String indexName = "test";
    String nodeWithPrimary = internalCluster().startNode();
    assertAcked(client().admin().indices().prepareCreate(indexName).setSettings(Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1).put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 1).put(IndexSettings.FILE_BASED_RECOVERY_THRESHOLD_SETTING.getKey(), 0.1f).put(IndexService.GLOBAL_CHECKPOINT_SYNC_INTERVAL_SETTING.getKey(), "100ms").put(IndexService.RETENTION_LEASE_SYNC_INTERVAL_SETTING.getKey(), "100ms").put(UnassignedInfo.INDEX_DELAYED_NODE_LEFT_TIMEOUT_SETTING.getKey(), "1ms")));
    String nodeWithReplica = internalCluster().startDataOnlyNode();
    DiscoveryNode discoNodeWithReplica = internalCluster().getInstance(ClusterService.class, nodeWithReplica).localNode();
    Settings nodeWithReplicaSettings = internalCluster().dataPathSettings(nodeWithReplica);
    ensureGreen(indexName);
    indexRandom(randomBoolean(), false, randomBoolean(), IntStream.range(0, between(10, 100)).mapToObj(n -> client().prepareIndex(indexName).setSource("f", "v")).collect(Collectors.toList()));
    internalCluster().stopRandomNode(InternalTestCluster.nameFilter(nodeWithReplica));
    if (randomBoolean()) {
        indexRandom(randomBoolean(), false, randomBoolean(), IntStream.range(0, between(10, 100)).mapToObj(n -> client().prepareIndex(indexName).setSource("f", "v")).collect(Collectors.toList()));
    }
    CountDownLatch blockRecovery = new CountDownLatch(1);
    CountDownLatch recoveryStarted = new CountDownLatch(1);
    MockTransportService transportServiceOnPrimary = (MockTransportService) internalCluster().getInstance(TransportService.class, nodeWithPrimary);
    transportServiceOnPrimary.addSendBehavior((connection, requestId, action, request, options) -> {
        if (PeerRecoveryTargetService.Actions.FILES_INFO.equals(action)) {
            recoveryStarted.countDown();
            try {
                blockRecovery.await();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        connection.sendRequest(requestId, action, request, options);
    });
    String newNode = internalCluster().startDataOnlyNode();
    recoveryStarted.await();
    // Index more documents and flush to destroy sync_id and remove the retention lease (as file_based_recovery_threshold reached).
    indexRandom(randomBoolean(), randomBoolean(), randomBoolean(), IntStream.range(0, between(50, 200)).mapToObj(n -> client().prepareIndex(indexName).setSource("f", "v")).collect(Collectors.toList()));
    client().admin().indices().prepareFlush(indexName).get();
    assertBusy(() -> {
        for (ShardStats shardStats : client().admin().indices().prepareStats(indexName).get().getShards()) {
            for (RetentionLease lease : shardStats.getRetentionLeaseStats().retentionLeases().leases()) {
                assertThat(lease.id(), not(equalTo(ReplicationTracker.getPeerRecoveryRetentionLeaseId(discoNodeWithReplica.getId()))));
            }
        }
    });
    // AllocationService only calls GatewayAllocator if there are unassigned shards
    assertAcked(client().admin().indices().prepareCreate("dummy-index").setWaitForActiveShards(0).setSettings(Settings.builder().put("index.routing.allocation.require.attr", "not-found")));
    internalCluster().startDataOnlyNode(nodeWithReplicaSettings);
    // need to wait for events to ensure the reroute has happened since we perform it async when a new node joins.
    client().admin().cluster().prepareHealth(indexName).setWaitForYellowStatus().setWaitForEvents(Priority.LANGUID).get();
    blockRecovery.countDown();
    ensureGreen(indexName);
    assertThat(internalCluster().nodesInclude(indexName), hasItem(newNode));
    for (RecoveryState recovery : client().admin().indices().prepareRecoveries(indexName).get().shardRecoveryStates().get(indexName)) {
        if (recovery.getPrimary() == false) {
            assertThat(recovery.getIndex().fileDetails(), not(empty()));
        }
    }
    transportServiceOnPrimary.clearAllRules();
}
Also used : ShardStats(org.opensearch.action.admin.indices.stats.ShardStats) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) ClusterService(org.opensearch.cluster.service.ClusterService) MockTransportService(org.opensearch.test.transport.MockTransportService) MockTransportService(org.opensearch.test.transport.MockTransportService) TransportService(org.opensearch.transport.TransportService) RetentionLease(org.opensearch.index.seqno.RetentionLease) CountDownLatch(java.util.concurrent.CountDownLatch) RecoveryState(org.opensearch.indices.recovery.RecoveryState) Settings(org.opensearch.common.settings.Settings) IndexSettings(org.opensearch.index.IndexSettings)

Aggregations

DiscoveryNode (org.opensearch.cluster.node.DiscoveryNode)673 ClusterState (org.opensearch.cluster.ClusterState)164 Settings (org.opensearch.common.settings.Settings)152 ArrayList (java.util.ArrayList)137 DiscoveryNodes (org.opensearch.cluster.node.DiscoveryNodes)123 ThreadPool (org.opensearch.threadpool.ThreadPool)103 ClusterService (org.opensearch.cluster.service.ClusterService)100 CountDownLatch (java.util.concurrent.CountDownLatch)98 HashSet (java.util.HashSet)93 TransportService (org.opensearch.transport.TransportService)92 IOException (java.io.IOException)89 ActionListener (org.opensearch.action.ActionListener)88 Matchers.containsString (org.hamcrest.Matchers.containsString)84 ClusterName (org.opensearch.cluster.ClusterName)82 Version (org.opensearch.Version)80 List (java.util.List)78 IndexMetadata (org.opensearch.cluster.metadata.IndexMetadata)78 HashMap (java.util.HashMap)77 TimeValue (org.opensearch.common.unit.TimeValue)77 ShardId (org.opensearch.index.shard.ShardId)76