Search in sources :

Example 1 with ImmutableOpenIntMap

use of org.opensearch.common.collect.ImmutableOpenIntMap in project OpenSearch by opensearch-project.

the class TransportClusterRerouteAction method verifyThenSubmitUpdate.

private void verifyThenSubmitUpdate(ClusterRerouteRequest request, ActionListener<ClusterRerouteResponse> listener, Map<String, List<AbstractAllocateAllocationCommand>> stalePrimaryAllocations) {
    transportService.sendRequest(transportService.getLocalNode(), IndicesShardStoresAction.NAME, new IndicesShardStoresRequest().indices(stalePrimaryAllocations.keySet().toArray(Strings.EMPTY_ARRAY)), new ActionListenerResponseHandler<>(ActionListener.wrap(response -> {
        ImmutableOpenMap<String, ImmutableOpenIntMap<List<IndicesShardStoresResponse.StoreStatus>>> status = response.getStoreStatuses();
        Exception e = null;
        for (Map.Entry<String, List<AbstractAllocateAllocationCommand>> entry : stalePrimaryAllocations.entrySet()) {
            final String index = entry.getKey();
            final ImmutableOpenIntMap<List<IndicesShardStoresResponse.StoreStatus>> indexStatus = status.get(index);
            if (indexStatus == null) {
                // request. We ignore it here since the relevant exception will be thrown by the reroute action later on.
                continue;
            }
            for (AbstractAllocateAllocationCommand command : entry.getValue()) {
                final List<IndicesShardStoresResponse.StoreStatus> shardStatus = indexStatus.get(command.shardId());
                if (shardStatus == null || shardStatus.isEmpty()) {
                    e = ExceptionsHelper.useOrSuppress(e, new IllegalArgumentException("No data for shard [" + command.shardId() + "] of index [" + index + "] found on any node"));
                } else if (shardStatus.stream().noneMatch(storeStatus -> {
                    final DiscoveryNode node = storeStatus.getNode();
                    final String nodeInCommand = command.node();
                    return nodeInCommand.equals(node.getName()) || nodeInCommand.equals(node.getId());
                })) {
                    e = ExceptionsHelper.useOrSuppress(e, new IllegalArgumentException("No data for shard [" + command.shardId() + "] of index [" + index + "] found on node [" + command.node() + ']'));
                }
            }
        }
        if (e == null) {
            submitStateUpdate(request, listener);
        } else {
            listener.onFailure(e);
        }
    }, listener::onFailure), IndicesShardStoresResponse::new));
}
Also used : ImmutableOpenMap(org.opensearch.common.collect.ImmutableOpenMap) ThreadPool(org.opensearch.threadpool.ThreadPool) AllocationService(org.opensearch.cluster.routing.allocation.AllocationService) Priority(org.opensearch.common.Priority) HashMap(java.util.HashMap) TransportMasterNodeAction(org.opensearch.action.support.master.TransportMasterNodeAction) AllocationCommand(org.opensearch.cluster.routing.allocation.command.AllocationCommand) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) IndicesShardStoresAction(org.opensearch.action.admin.indices.shards.IndicesShardStoresAction) AllocateStalePrimaryAllocationCommand(org.opensearch.cluster.routing.allocation.command.AllocateStalePrimaryAllocationCommand) Strings(org.opensearch.common.Strings) ArrayList(java.util.ArrayList) ClusterState(org.opensearch.cluster.ClusterState) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) Map(java.util.Map) AckedClusterStateUpdateTask(org.opensearch.cluster.AckedClusterStateUpdateTask) Inject(org.opensearch.common.inject.Inject) ActionListener(org.opensearch.action.ActionListener) StreamInput(org.opensearch.common.io.stream.StreamInput) IndicesShardStoresResponse(org.opensearch.action.admin.indices.shards.IndicesShardStoresResponse) RoutingExplanations(org.opensearch.cluster.routing.allocation.RoutingExplanations) ImmutableOpenIntMap(org.opensearch.common.collect.ImmutableOpenIntMap) ClusterBlockLevel(org.opensearch.cluster.block.ClusterBlockLevel) ExceptionsHelper(org.opensearch.ExceptionsHelper) ClusterBlockException(org.opensearch.cluster.block.ClusterBlockException) IOException(java.io.IOException) AbstractAllocateAllocationCommand(org.opensearch.cluster.routing.allocation.command.AbstractAllocateAllocationCommand) TransportService(org.opensearch.transport.TransportService) IndicesShardStoresRequest(org.opensearch.action.admin.indices.shards.IndicesShardStoresRequest) ActionFilters(org.opensearch.action.support.ActionFilters) List(java.util.List) Logger(org.apache.logging.log4j.Logger) ActionListenerResponseHandler(org.opensearch.action.ActionListenerResponseHandler) ClusterService(org.opensearch.cluster.service.ClusterService) LogManager(org.apache.logging.log4j.LogManager) IndexNameExpressionResolver(org.opensearch.cluster.metadata.IndexNameExpressionResolver) IndicesShardStoresRequest(org.opensearch.action.admin.indices.shards.IndicesShardStoresRequest) IndicesShardStoresResponse(org.opensearch.action.admin.indices.shards.IndicesShardStoresResponse) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) AbstractAllocateAllocationCommand(org.opensearch.cluster.routing.allocation.command.AbstractAllocateAllocationCommand) ClusterBlockException(org.opensearch.cluster.block.ClusterBlockException) IOException(java.io.IOException) ImmutableOpenIntMap(org.opensearch.common.collect.ImmutableOpenIntMap) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableOpenMap(org.opensearch.common.collect.ImmutableOpenMap) HashMap(java.util.HashMap) Map(java.util.Map) ImmutableOpenIntMap(org.opensearch.common.collect.ImmutableOpenIntMap)

Example 2 with ImmutableOpenIntMap

use of org.opensearch.common.collect.ImmutableOpenIntMap in project OpenSearch by opensearch-project.

the class PrimaryAllocationIT method testForceStaleReplicaToBePromotedToPrimary.

public void testForceStaleReplicaToBePromotedToPrimary() throws Exception {
    logger.info("--> starting 3 nodes, 1 master, 2 data");
    String master = internalCluster().startMasterOnlyNode(Settings.EMPTY);
    internalCluster().startDataOnlyNodes(2);
    assertAcked(client().admin().indices().prepareCreate("test").setSettings(Settings.builder().put("index.number_of_shards", 1).put("index.number_of_replicas", 1)).get());
    ensureGreen();
    Set<String> historyUUIDs = Arrays.stream(client().admin().indices().prepareStats("test").clear().get().getShards()).map(shard -> shard.getCommitStats().getUserData().get(Engine.HISTORY_UUID_KEY)).collect(Collectors.toSet());
    createStaleReplicaScenario(master);
    if (randomBoolean()) {
        assertAcked(client().admin().indices().prepareClose("test").setWaitForActiveShards(0));
    }
    // if true, use stale replica, otherwise a completely empty copy
    boolean useStaleReplica = randomBoolean();
    logger.info("--> explicitly promote old primary shard");
    final String idxName = "test";
    ImmutableOpenIntMap<List<IndicesShardStoresResponse.StoreStatus>> storeStatuses = client().admin().indices().prepareShardStores(idxName).get().getStoreStatuses().get(idxName);
    ClusterRerouteRequestBuilder rerouteBuilder = client().admin().cluster().prepareReroute();
    for (IntObjectCursor<List<IndicesShardStoresResponse.StoreStatus>> shardStoreStatuses : storeStatuses) {
        int shardId = shardStoreStatuses.key;
        IndicesShardStoresResponse.StoreStatus storeStatus = randomFrom(shardStoreStatuses.value);
        logger.info("--> adding allocation command for shard {}", shardId);
        // force allocation based on node id
        if (useStaleReplica) {
            rerouteBuilder.add(new AllocateStalePrimaryAllocationCommand(idxName, shardId, storeStatus.getNode().getId(), true));
        } else {
            rerouteBuilder.add(new AllocateEmptyPrimaryAllocationCommand(idxName, shardId, storeStatus.getNode().getId(), true));
        }
    }
    final Set<String> expectedAllocationIds = useStaleReplica ? Collections.singleton(RecoverySource.ExistingStoreRecoverySource.FORCED_ALLOCATION_ID) : Collections.emptySet();
    final CountDownLatch clusterStateChangeLatch = new CountDownLatch(1);
    final ClusterStateListener clusterStateListener = event -> {
        final Set<String> allocationIds = event.state().metadata().index(idxName).inSyncAllocationIds(0);
        if (expectedAllocationIds.equals(allocationIds)) {
            clusterStateChangeLatch.countDown();
        }
        logger.info("expected allocation ids: {} actual allocation ids: {}", expectedAllocationIds, allocationIds);
    };
    final ClusterService clusterService = internalCluster().getInstance(ClusterService.class, master);
    clusterService.addListener(clusterStateListener);
    rerouteBuilder.get();
    assertTrue(clusterStateChangeLatch.await(30, TimeUnit.SECONDS));
    clusterService.removeListener(clusterStateListener);
    logger.info("--> check that the stale primary shard gets allocated and that documents are available");
    ensureYellow(idxName);
    if (useStaleReplica == false) {
        // When invoking AllocateEmptyPrimaryAllocationCommand, due to the UnassignedInfo.Reason being changed to INDEX_CREATION,
        // its possible that the shard has not completed initialization, even though the cluster health is yellow, so the
        // search can throw an "all shards failed" exception. We will wait until the shard initialization has completed before
        // verifying the search hit count.
        assertBusy(() -> assertTrue(client().admin().cluster().prepareState().get().getState().routingTable().index(idxName).allPrimaryShardsActive()));
    }
    ShardStats[] shardStats = client().admin().indices().prepareStats("test").setIndicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN_CLOSED).get().getShards();
    for (ShardStats shardStat : shardStats) {
        assertThat(shardStat.getCommitStats().getNumDocs(), equalTo(useStaleReplica ? 1 : 0));
    }
    // allocation id of old primary was cleaned from the in-sync set
    final ClusterState state = client().admin().cluster().prepareState().get().getState();
    assertEquals(Collections.singleton(state.routingTable().index(idxName).shard(0).primary.allocationId().getId()), state.metadata().index(idxName).inSyncAllocationIds(0));
    Set<String> newHistoryUUIds = Stream.of(shardStats).map(shard -> shard.getCommitStats().getUserData().get(Engine.HISTORY_UUID_KEY)).collect(Collectors.toSet());
    assertThat(newHistoryUUIds, everyItem(is(not(in(historyUUIDs)))));
    assertThat(newHistoryUUIds, hasSize(1));
}
Also used : Arrays(java.util.Arrays) IndexResponse(org.opensearch.action.index.IndexResponse) Matchers.not(org.hamcrest.Matchers.not) AllocateStalePrimaryAllocationCommand(org.opensearch.cluster.routing.allocation.command.AllocateStalePrimaryAllocationCommand) Strings(org.opensearch.common.Strings) IndexShardTestCase(org.opensearch.index.shard.IndexShardTestCase) OpenSearchAssertions.assertHitCount(org.opensearch.test.hamcrest.OpenSearchAssertions.assertHitCount) Matchers.everyItem(org.hamcrest.Matchers.everyItem) QueryBuilders.matchAllQuery(org.opensearch.index.query.QueryBuilders.matchAllQuery) ClusterRerouteRequestBuilder(org.opensearch.action.admin.cluster.reroute.ClusterRerouteRequestBuilder) SETTING_NUMBER_OF_REPLICAS(org.opensearch.cluster.metadata.IndexMetadata.SETTING_NUMBER_OF_REPLICAS) EngineTestCase(org.opensearch.index.engine.EngineTestCase) ImmutableOpenIntMap(org.opensearch.common.collect.ImmutableOpenIntMap) Collection(java.util.Collection) IndicesService(org.opensearch.indices.IndicesService) Set(java.util.Set) Settings(org.opensearch.common.settings.Settings) Collectors(java.util.stream.Collectors) Engine(org.opensearch.index.engine.Engine) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Stream(java.util.stream.Stream) GatewayAllocator(org.opensearch.gateway.GatewayAllocator) Matchers.equalTo(org.hamcrest.Matchers.equalTo) DocWriteResponse(org.opensearch.action.DocWriteResponse) Matchers.is(org.hamcrest.Matchers.is) OpenSearchIntegTestCase(org.opensearch.test.OpenSearchIntegTestCase) Matchers.in(org.hamcrest.Matchers.in) AllocateEmptyPrimaryAllocationCommand(org.opensearch.cluster.routing.allocation.command.AllocateEmptyPrimaryAllocationCommand) IntObjectCursor(com.carrotsearch.hppc.cursors.IntObjectCursor) XContentFactory.jsonBuilder(org.opensearch.common.xcontent.XContentFactory.jsonBuilder) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) IndicesOptions(org.opensearch.action.support.IndicesOptions) ClusterStateListener(org.opensearch.cluster.ClusterStateListener) MockTransportService(org.opensearch.test.transport.MockTransportService) InternalTestCluster(org.opensearch.test.InternalTestCluster) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ClusterState(org.opensearch.cluster.ClusterState) IndexShard(org.opensearch.index.shard.IndexShard) InternalSettingsPlugin(org.opensearch.test.InternalSettingsPlugin) Matchers.hasSize(org.hamcrest.Matchers.hasSize) OpenSearchAssertions.assertAcked(org.opensearch.test.hamcrest.OpenSearchAssertions.assertAcked) IndicesShardStoresResponse(org.opensearch.action.admin.indices.shards.IndicesShardStoresResponse) Matchers.empty(org.hamcrest.Matchers.empty) IndexNotFoundException(org.opensearch.index.IndexNotFoundException) Plugin(org.opensearch.plugins.Plugin) ActiveShardCount(org.opensearch.action.support.ActiveShardCount) ShardId(org.opensearch.index.shard.ShardId) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Sets(org.opensearch.common.util.set.Sets) TwoPartitions(org.opensearch.test.disruption.NetworkDisruption.TwoPartitions) BulkResponse(org.opensearch.action.bulk.BulkResponse) ClusterService(org.opensearch.cluster.service.ClusterService) NetworkDisruption(org.opensearch.test.disruption.NetworkDisruption) SETTING_NUMBER_OF_SHARDS(org.opensearch.cluster.metadata.IndexMetadata.SETTING_NUMBER_OF_SHARDS) ShardStats(org.opensearch.action.admin.indices.stats.ShardStats) Collections(java.util.Collections) ShardStats(org.opensearch.action.admin.indices.stats.ShardStats) ClusterState(org.opensearch.cluster.ClusterState) IndicesShardStoresResponse(org.opensearch.action.admin.indices.shards.IndicesShardStoresResponse) Set(java.util.Set) HashSet(java.util.HashSet) ClusterRerouteRequestBuilder(org.opensearch.action.admin.cluster.reroute.ClusterRerouteRequestBuilder) AllocateStalePrimaryAllocationCommand(org.opensearch.cluster.routing.allocation.command.AllocateStalePrimaryAllocationCommand) AllocateEmptyPrimaryAllocationCommand(org.opensearch.cluster.routing.allocation.command.AllocateEmptyPrimaryAllocationCommand) CountDownLatch(java.util.concurrent.CountDownLatch) ClusterStateListener(org.opensearch.cluster.ClusterStateListener) ClusterService(org.opensearch.cluster.service.ClusterService) List(java.util.List) ArrayList(java.util.ArrayList)

Example 3 with ImmutableOpenIntMap

use of org.opensearch.common.collect.ImmutableOpenIntMap in project OpenSearch by opensearch-project.

the class IndicesShardStoreResponseTests method testBasicSerialization.

public void testBasicSerialization() throws Exception {
    ImmutableOpenMap.Builder<String, ImmutableOpenIntMap<List<IndicesShardStoresResponse.StoreStatus>>> indexStoreStatuses = ImmutableOpenMap.builder();
    List<IndicesShardStoresResponse.Failure> failures = new ArrayList<>();
    ImmutableOpenIntMap.Builder<List<IndicesShardStoresResponse.StoreStatus>> storeStatuses = ImmutableOpenIntMap.builder();
    DiscoveryNode node1 = new DiscoveryNode("node1", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT);
    DiscoveryNode node2 = new DiscoveryNode("node2", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT);
    List<IndicesShardStoresResponse.StoreStatus> storeStatusList = new ArrayList<>();
    storeStatusList.add(new IndicesShardStoresResponse.StoreStatus(node1, null, IndicesShardStoresResponse.StoreStatus.AllocationStatus.PRIMARY, null));
    storeStatusList.add(new IndicesShardStoresResponse.StoreStatus(node2, UUIDs.randomBase64UUID(), IndicesShardStoresResponse.StoreStatus.AllocationStatus.REPLICA, null));
    storeStatusList.add(new IndicesShardStoresResponse.StoreStatus(node1, UUIDs.randomBase64UUID(), IndicesShardStoresResponse.StoreStatus.AllocationStatus.UNUSED, new IOException("corrupted")));
    storeStatuses.put(0, storeStatusList);
    storeStatuses.put(1, storeStatusList);
    ImmutableOpenIntMap<List<IndicesShardStoresResponse.StoreStatus>> storesMap = storeStatuses.build();
    indexStoreStatuses.put("test", storesMap);
    indexStoreStatuses.put("test2", storesMap);
    failures.add(new IndicesShardStoresResponse.Failure("node1", "test", 3, new NodeDisconnectedException(node1, "")));
    IndicesShardStoresResponse storesResponse = new IndicesShardStoresResponse(indexStoreStatuses.build(), Collections.unmodifiableList(failures));
    XContentBuilder contentBuilder = XContentFactory.jsonBuilder();
    contentBuilder.startObject();
    storesResponse.toXContent(contentBuilder, ToXContent.EMPTY_PARAMS);
    contentBuilder.endObject();
    BytesReference bytes = BytesReference.bytes(contentBuilder);
    try (XContentParser parser = createParser(JsonXContent.jsonXContent, bytes)) {
        Map<String, Object> map = parser.map();
        List<?> failureList = (List<?>) map.get("failures");
        assertThat(failureList.size(), equalTo(1));
        @SuppressWarnings("unchecked") Map<String, ?> failureMap = (Map<String, ?>) failureList.get(0);
        assertThat(failureMap.containsKey("index"), equalTo(true));
        assertThat(((String) failureMap.get("index")), equalTo("test"));
        assertThat(failureMap.containsKey("shard"), equalTo(true));
        assertThat(((int) failureMap.get("shard")), equalTo(3));
        assertThat(failureMap.containsKey("node"), equalTo(true));
        assertThat(((String) failureMap.get("node")), equalTo("node1"));
        @SuppressWarnings("unchecked") Map<String, Object> indices = (Map<String, Object>) map.get("indices");
        for (String index : new String[] { "test", "test2" }) {
            assertThat(indices.containsKey(index), equalTo(true));
            @SuppressWarnings("unchecked") Map<String, Object> shards = ((Map<String, Object>) ((Map<String, Object>) indices.get(index)).get("shards"));
            assertThat(shards.size(), equalTo(2));
            for (String shardId : shards.keySet()) {
                @SuppressWarnings("unchecked") Map<String, ?> shardStoresStatus = (Map<String, ?>) shards.get(shardId);
                assertThat(shardStoresStatus.containsKey("stores"), equalTo(true));
                List<?> stores = (List<?>) shardStoresStatus.get("stores");
                assertThat(stores.size(), equalTo(storeStatusList.size()));
                for (int i = 0; i < stores.size(); i++) {
                    @SuppressWarnings("unchecked") Map<String, ?> storeInfo = ((Map<String, ?>) stores.get(i));
                    IndicesShardStoresResponse.StoreStatus storeStatus = storeStatusList.get(i);
                    assertThat(((String) storeInfo.get("allocation_id")), equalTo((storeStatus.getAllocationId())));
                    assertThat(storeInfo.containsKey("allocation"), equalTo(true));
                    assertThat(((String) storeInfo.get("allocation")), equalTo(storeStatus.getAllocationStatus().value()));
                    assertThat(storeInfo.containsKey(storeStatus.getNode().getId()), equalTo(true));
                    if (storeStatus.getStoreException() != null) {
                        assertThat(storeInfo.containsKey("store_exception"), equalTo(true));
                    }
                }
            }
        }
    }
}
Also used : DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) ArrayList(java.util.ArrayList) ImmutableOpenMap(org.opensearch.common.collect.ImmutableOpenMap) ArrayList(java.util.ArrayList) List(java.util.List) BytesReference(org.opensearch.common.bytes.BytesReference) NodeDisconnectedException(org.opensearch.transport.NodeDisconnectedException) IOException(java.io.IOException) ImmutableOpenIntMap(org.opensearch.common.collect.ImmutableOpenIntMap) Collections.emptyMap(java.util.Collections.emptyMap) ImmutableOpenMap(org.opensearch.common.collect.ImmutableOpenMap) ImmutableOpenIntMap(org.opensearch.common.collect.ImmutableOpenIntMap) Map(java.util.Map) XContentBuilder(org.opensearch.common.xcontent.XContentBuilder) XContentParser(org.opensearch.common.xcontent.XContentParser)

Example 4 with ImmutableOpenIntMap

use of org.opensearch.common.collect.ImmutableOpenIntMap in project OpenSearch by opensearch-project.

the class ClusterStateHealthTests method generateClusterStates.

private List<ClusterState> generateClusterStates(final ClusterState originalClusterState, final String indexName, final int numberOfReplicas, final boolean withPrimaryAllocationFailures) {
    // generate random node ids
    final Set<String> nodeIds = new HashSet<>();
    final int numNodes = randomIntBetween(numberOfReplicas + 1, 10);
    for (int i = 0; i < numNodes; i++) {
        nodeIds.add(randomAlphaOfLength(8));
    }
    final List<ClusterState> clusterStates = new ArrayList<>();
    clusterStates.add(originalClusterState);
    ClusterState clusterState = originalClusterState;
    // initialize primaries
    RoutingTable routingTable = originalClusterState.routingTable();
    IndexRoutingTable indexRoutingTable = routingTable.index(indexName);
    IndexRoutingTable.Builder newIndexRoutingTable = IndexRoutingTable.builder(indexRoutingTable.getIndex());
    for (final ObjectCursor<IndexShardRoutingTable> shardEntry : indexRoutingTable.getShards().values()) {
        final IndexShardRoutingTable shardRoutingTable = shardEntry.value;
        for (final ShardRouting shardRouting : shardRoutingTable.getShards()) {
            if (shardRouting.primary()) {
                newIndexRoutingTable.addShard(shardRouting.initialize(randomFrom(nodeIds), null, shardRouting.getExpectedShardSize()));
            } else {
                newIndexRoutingTable.addShard(shardRouting);
            }
        }
    }
    routingTable = RoutingTable.builder(routingTable).add(newIndexRoutingTable).build();
    clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build();
    clusterStates.add(clusterState);
    // some primaries started
    indexRoutingTable = routingTable.index(indexName);
    newIndexRoutingTable = IndexRoutingTable.builder(indexRoutingTable.getIndex());
    ImmutableOpenIntMap.Builder<Set<String>> allocationIds = ImmutableOpenIntMap.<Set<String>>builder();
    for (final ObjectCursor<IndexShardRoutingTable> shardEntry : indexRoutingTable.getShards().values()) {
        final IndexShardRoutingTable shardRoutingTable = shardEntry.value;
        for (final ShardRouting shardRouting : shardRoutingTable.getShards()) {
            if (shardRouting.primary() && randomBoolean()) {
                final ShardRouting newShardRouting = shardRouting.moveToStarted();
                allocationIds.fPut(newShardRouting.getId(), Sets.newHashSet(newShardRouting.allocationId().getId()));
                newIndexRoutingTable.addShard(newShardRouting);
            } else {
                newIndexRoutingTable.addShard(shardRouting);
            }
        }
    }
    routingTable = RoutingTable.builder(routingTable).add(newIndexRoutingTable).build();
    IndexMetadata.Builder idxMetaBuilder = IndexMetadata.builder(clusterState.metadata().index(indexName));
    for (final IntObjectCursor<Set<String>> entry : allocationIds.build()) {
        idxMetaBuilder.putInSyncAllocationIds(entry.key, entry.value);
    }
    Metadata.Builder metadataBuilder = Metadata.builder(clusterState.metadata()).put(idxMetaBuilder);
    clusterState = ClusterState.builder(clusterState).routingTable(routingTable).metadata(metadataBuilder).build();
    clusterStates.add(clusterState);
    if (withPrimaryAllocationFailures) {
        boolean alreadyFailedPrimary = false;
        // some primaries failed to allocate
        indexRoutingTable = routingTable.index(indexName);
        newIndexRoutingTable = IndexRoutingTable.builder(indexRoutingTable.getIndex());
        for (final ObjectCursor<IndexShardRoutingTable> shardEntry : indexRoutingTable.getShards().values()) {
            final IndexShardRoutingTable shardRoutingTable = shardEntry.value;
            for (final ShardRouting shardRouting : shardRoutingTable.getShards()) {
                if (shardRouting.primary() && (shardRouting.started() == false || alreadyFailedPrimary == false)) {
                    newIndexRoutingTable.addShard(shardRouting.moveToUnassigned(new UnassignedInfo(UnassignedInfo.Reason.ALLOCATION_FAILED, "unlucky shard")));
                    alreadyFailedPrimary = true;
                } else {
                    newIndexRoutingTable.addShard(shardRouting);
                }
            }
        }
        routingTable = RoutingTable.builder(routingTable).add(newIndexRoutingTable).build();
        clusterStates.add(ClusterState.builder(clusterState).routingTable(routingTable).build());
        return clusterStates;
    }
    // all primaries started
    indexRoutingTable = routingTable.index(indexName);
    newIndexRoutingTable = IndexRoutingTable.builder(indexRoutingTable.getIndex());
    allocationIds = ImmutableOpenIntMap.<Set<String>>builder();
    for (final ObjectCursor<IndexShardRoutingTable> shardEntry : indexRoutingTable.getShards().values()) {
        final IndexShardRoutingTable shardRoutingTable = shardEntry.value;
        for (final ShardRouting shardRouting : shardRoutingTable.getShards()) {
            if (shardRouting.primary() && shardRouting.started() == false) {
                final ShardRouting newShardRouting = shardRouting.moveToStarted();
                allocationIds.fPut(newShardRouting.getId(), Sets.newHashSet(newShardRouting.allocationId().getId()));
                newIndexRoutingTable.addShard(newShardRouting);
            } else {
                newIndexRoutingTable.addShard(shardRouting);
            }
        }
    }
    routingTable = RoutingTable.builder(routingTable).add(newIndexRoutingTable).build();
    idxMetaBuilder = IndexMetadata.builder(clusterState.metadata().index(indexName));
    for (final IntObjectCursor<Set<String>> entry : allocationIds.build()) {
        idxMetaBuilder.putInSyncAllocationIds(entry.key, entry.value);
    }
    metadataBuilder = Metadata.builder(clusterState.metadata()).put(idxMetaBuilder);
    clusterState = ClusterState.builder(clusterState).routingTable(routingTable).metadata(metadataBuilder).build();
    clusterStates.add(clusterState);
    // initialize replicas
    indexRoutingTable = routingTable.index(indexName);
    newIndexRoutingTable = IndexRoutingTable.builder(indexRoutingTable.getIndex());
    for (final ObjectCursor<IndexShardRoutingTable> shardEntry : indexRoutingTable.getShards().values()) {
        final IndexShardRoutingTable shardRoutingTable = shardEntry.value;
        final String primaryNodeId = shardRoutingTable.primaryShard().currentNodeId();
        Set<String> allocatedNodes = new HashSet<>();
        allocatedNodes.add(primaryNodeId);
        for (final ShardRouting shardRouting : shardRoutingTable.getShards()) {
            if (shardRouting.primary() == false) {
                // give the replica a different node id than the primary
                String replicaNodeId = randomFrom(Sets.difference(nodeIds, allocatedNodes));
                newIndexRoutingTable.addShard(shardRouting.initialize(replicaNodeId, null, shardRouting.getExpectedShardSize()));
                allocatedNodes.add(replicaNodeId);
            } else {
                newIndexRoutingTable.addShard(shardRouting);
            }
        }
    }
    routingTable = RoutingTable.builder(routingTable).add(newIndexRoutingTable).build();
    clusterStates.add(ClusterState.builder(clusterState).routingTable(routingTable).build());
    // some replicas started
    indexRoutingTable = routingTable.index(indexName);
    newIndexRoutingTable = IndexRoutingTable.builder(indexRoutingTable.getIndex());
    for (final ObjectCursor<IndexShardRoutingTable> shardEntry : indexRoutingTable.getShards().values()) {
        final IndexShardRoutingTable shardRoutingTable = shardEntry.value;
        for (final ShardRouting shardRouting : shardRoutingTable.getShards()) {
            if (shardRouting.primary() == false && randomBoolean()) {
                newIndexRoutingTable.addShard(shardRouting.moveToStarted());
            } else {
                newIndexRoutingTable.addShard(shardRouting);
            }
        }
    }
    routingTable = RoutingTable.builder(routingTable).add(newIndexRoutingTable).build();
    clusterStates.add(ClusterState.builder(clusterState).routingTable(routingTable).build());
    // all replicas started
    boolean replicaStateChanged = false;
    indexRoutingTable = routingTable.index(indexName);
    newIndexRoutingTable = IndexRoutingTable.builder(indexRoutingTable.getIndex());
    for (final ObjectCursor<IndexShardRoutingTable> shardEntry : indexRoutingTable.getShards().values()) {
        final IndexShardRoutingTable shardRoutingTable = shardEntry.value;
        for (final ShardRouting shardRouting : shardRoutingTable.getShards()) {
            if (shardRouting.primary() == false && shardRouting.started() == false) {
                newIndexRoutingTable.addShard(shardRouting.moveToStarted());
                replicaStateChanged = true;
            } else {
                newIndexRoutingTable.addShard(shardRouting);
            }
        }
    }
    // all of the replicas may have moved to started in the previous phase already
    if (replicaStateChanged) {
        routingTable = RoutingTable.builder(routingTable).add(newIndexRoutingTable).build();
        clusterStates.add(ClusterState.builder(clusterState).routingTable(routingTable).build());
    }
    return clusterStates;
}
Also used : ClusterState(org.opensearch.cluster.ClusterState) IndexRoutingTable(org.opensearch.cluster.routing.IndexRoutingTable) IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) Set(java.util.Set) HashSet(java.util.HashSet) UnassignedInfo(org.opensearch.cluster.routing.UnassignedInfo) ArrayList(java.util.ArrayList) Metadata(org.opensearch.cluster.metadata.Metadata) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) IndexRoutingTable(org.opensearch.cluster.routing.IndexRoutingTable) RoutingTable(org.opensearch.cluster.routing.RoutingTable) ImmutableOpenIntMap(org.opensearch.common.collect.ImmutableOpenIntMap) ShardRouting(org.opensearch.cluster.routing.ShardRouting) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) HashSet(java.util.HashSet)

Aggregations

ArrayList (java.util.ArrayList)4 ImmutableOpenIntMap (org.opensearch.common.collect.ImmutableOpenIntMap)4 List (java.util.List)3 ClusterState (org.opensearch.cluster.ClusterState)3 IOException (java.io.IOException)2 HashSet (java.util.HashSet)2 Map (java.util.Map)2 Set (java.util.Set)2 IndicesShardStoresResponse (org.opensearch.action.admin.indices.shards.IndicesShardStoresResponse)2 IndexMetadata (org.opensearch.cluster.metadata.IndexMetadata)2 DiscoveryNode (org.opensearch.cluster.node.DiscoveryNode)2 IntObjectCursor (com.carrotsearch.hppc.cursors.IntObjectCursor)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 Collections.emptyMap (java.util.Collections.emptyMap)1 HashMap (java.util.HashMap)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 ExecutionException (java.util.concurrent.ExecutionException)1 TimeUnit (java.util.concurrent.TimeUnit)1