Search in sources :

Example 1 with CloseIndexClusterStateUpdateRequest

use of org.opensearch.action.admin.indices.close.CloseIndexClusterStateUpdateRequest in project OpenSearch by opensearch-project.

the class MetadataIndexStateService method closeIndices.

/**
 * Closes one or more indices.
 *
 * Closing indices is a 3 steps process: it first adds a write block to every indices to close, then waits for the operations on shards
 * to be terminated and finally closes the indices by moving their state to CLOSE.
 */
public void closeIndices(final CloseIndexClusterStateUpdateRequest request, final ActionListener<CloseIndexResponse> listener) {
    final Index[] concreteIndices = request.indices();
    if (concreteIndices == null || concreteIndices.length == 0) {
        throw new IllegalArgumentException("Index name is required");
    }
    List<String> writeIndices = new ArrayList<>();
    SortedMap<String, IndexAbstraction> lookup = clusterService.state().metadata().getIndicesLookup();
    for (Index index : concreteIndices) {
        IndexAbstraction ia = lookup.get(index.getName());
        if (ia != null && ia.getParentDataStream() != null && ia.getParentDataStream().getWriteIndex().getIndex().equals(index)) {
            writeIndices.add(index.getName());
        }
    }
    if (writeIndices.size() > 0) {
        throw new IllegalArgumentException("cannot close the following data stream write indices [" + Strings.collectionToCommaDelimitedString(writeIndices) + "]");
    }
    clusterService.submitStateUpdateTask("add-block-index-to-close " + Arrays.toString(concreteIndices), new ClusterStateUpdateTask(Priority.URGENT) {

        private final Map<Index, ClusterBlock> blockedIndices = new HashMap<>();

        @Override
        public ClusterState execute(final ClusterState currentState) {
            return addIndexClosedBlocks(concreteIndices, blockedIndices, currentState);
        }

        @Override
        public void clusterStateProcessed(final String source, final ClusterState oldState, final ClusterState newState) {
            if (oldState == newState) {
                assert blockedIndices.isEmpty() : "List of blocked indices is not empty but cluster state wasn't changed";
                listener.onResponse(new CloseIndexResponse(true, false, Collections.emptyList()));
            } else {
                assert blockedIndices.isEmpty() == false : "List of blocked indices is empty but cluster state was changed";
                threadPool.executor(ThreadPool.Names.MANAGEMENT).execute(new WaitForClosedBlocksApplied(blockedIndices, request, ActionListener.wrap(verifyResults -> clusterService.submitStateUpdateTask("close-indices", new ClusterStateUpdateTask(Priority.URGENT) {

                    private final List<IndexResult> indices = new ArrayList<>();

                    @Override
                    public ClusterState execute(final ClusterState currentState) throws Exception {
                        Tuple<ClusterState, Collection<IndexResult>> closingResult = closeRoutingTable(currentState, blockedIndices, verifyResults);
                        assert verifyResults.size() == closingResult.v2().size();
                        indices.addAll(closingResult.v2());
                        return allocationService.reroute(closingResult.v1(), "indices closed");
                    }

                    @Override
                    public void onFailure(final String source, final Exception e) {
                        listener.onFailure(e);
                    }

                    @Override
                    public void clusterStateProcessed(final String source, final ClusterState oldState, final ClusterState newState) {
                        final boolean acknowledged = indices.stream().noneMatch(IndexResult::hasFailures);
                        final String[] waitForIndices = indices.stream().filter(result -> result.hasFailures() == false).filter(result -> newState.routingTable().hasIndex(result.getIndex())).map(result -> result.getIndex().getName()).toArray(String[]::new);
                        if (waitForIndices.length > 0) {
                            activeShardsObserver.waitForActiveShards(waitForIndices, request.waitForActiveShards(), request.ackTimeout(), shardsAcknowledged -> {
                                if (shardsAcknowledged == false) {
                                    logger.debug("[{}] indices closed, but the operation timed out while waiting " + "for enough shards to be started.", Arrays.toString(waitForIndices));
                                }
                                // acknowledged maybe be false but some indices may have been correctly
                                // closed, so
                                // we maintain a kind of coherency by overriding the shardsAcknowledged
                                // value
                                // (see ShardsAcknowledgedResponse constructor)
                                boolean shardsAcked = acknowledged ? shardsAcknowledged : false;
                                listener.onResponse(new CloseIndexResponse(acknowledged, shardsAcked, indices));
                            }, listener::onFailure);
                        } else {
                            listener.onResponse(new CloseIndexResponse(acknowledged, false, indices));
                        }
                    }
                }), listener::onFailure)));
            }
        }

        @Override
        public void onFailure(final String source, final Exception e) {
            listener.onFailure(e);
        }

        @Override
        public TimeValue timeout() {
            return request.masterNodeTimeout();
        }
    });
}
Also used : Arrays(java.util.Arrays) CountDown(org.opensearch.common.util.concurrent.CountDown) NotifyOnceListener(org.opensearch.action.NotifyOnceListener) AllocationService(org.opensearch.cluster.routing.allocation.AllocationService) Version(org.opensearch.Version) OpenSearchException(org.opensearch.OpenSearchException) SnapshotsService(org.opensearch.snapshots.SnapshotsService) Strings(org.opensearch.common.Strings) CloseIndexResponse(org.opensearch.action.admin.indices.close.CloseIndexResponse) ConcurrentCollections(org.opensearch.common.util.concurrent.ConcurrentCollections) ClusterBlock(org.opensearch.cluster.block.ClusterBlock) Collections.singleton(java.util.Collections.singleton) TransportVerifyShardIndexBlockAction(org.opensearch.action.admin.indices.readonly.TransportVerifyShardIndexBlockAction) Map(java.util.Map) Inject(org.opensearch.common.inject.Inject) AddBlockShardResult(org.opensearch.action.admin.indices.readonly.AddIndexBlockResponse.AddBlockShardResult) ActionListener(org.opensearch.action.ActionListener) EnumSet(java.util.EnumSet) IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) TimeValue(org.opensearch.common.unit.TimeValue) ImmutableOpenIntMap(org.opensearch.common.collect.ImmutableOpenIntMap) Index(org.opensearch.index.Index) Collection(java.util.Collection) IndicesService(org.opensearch.indices.IndicesService) SnapshotInProgressException(org.opensearch.snapshots.SnapshotInProgressException) Set(java.util.Set) Settings(org.opensearch.common.settings.Settings) RestStatus(org.opensearch.rest.RestStatus) ShardResult(org.opensearch.action.admin.indices.close.CloseIndexResponse.ShardResult) Collectors(java.util.stream.Collectors) Tuple(org.opensearch.common.collect.Tuple) List(java.util.List) Logger(org.apache.logging.log4j.Logger) ClusterStateUpdateTask(org.opensearch.cluster.ClusterStateUpdateTask) IndexResult(org.opensearch.action.admin.indices.close.CloseIndexResponse.IndexResult) ReplicationResponse(org.opensearch.action.support.replication.ReplicationResponse) AddIndexBlockClusterStateUpdateRequest(org.opensearch.action.admin.indices.readonly.AddIndexBlockClusterStateUpdateRequest) ClusterStateUpdateResponse(org.opensearch.cluster.ack.ClusterStateUpdateResponse) SortedMap(java.util.SortedMap) IntObjectCursor(com.carrotsearch.hppc.cursors.IntObjectCursor) APIBlock(org.opensearch.cluster.metadata.IndexMetadata.APIBlock) ActionRunnable(org.opensearch.action.ActionRunnable) ThreadPool(org.opensearch.threadpool.ThreadPool) Priority(org.opensearch.common.Priority) HashMap(java.util.HashMap) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) TransportVerifyShardBeforeCloseAction(org.opensearch.action.admin.indices.close.TransportVerifyShardBeforeCloseAction) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) IndexRoutingTable(org.opensearch.cluster.routing.IndexRoutingTable) CloseIndexClusterStateUpdateRequest(org.opensearch.action.admin.indices.close.CloseIndexClusterStateUpdateRequest) ClusterState(org.opensearch.cluster.ClusterState) AddIndexBlockResponse(org.opensearch.action.admin.indices.readonly.AddIndexBlockResponse) LegacyESVersion(org.opensearch.LegacyESVersion) RestoreService(org.opensearch.snapshots.RestoreService) AckedClusterStateUpdateTask(org.opensearch.cluster.AckedClusterStateUpdateTask) UUIDs(org.opensearch.common.UUIDs) ClusterBlocks(org.opensearch.cluster.block.ClusterBlocks) Setting(org.opensearch.common.settings.Setting) ShardLimitValidator(org.opensearch.indices.ShardLimitValidator) ClusterBlockLevel(org.opensearch.cluster.block.ClusterBlockLevel) IndexNotFoundException(org.opensearch.index.IndexNotFoundException) TaskId(org.opensearch.tasks.TaskId) ShardId(org.opensearch.index.shard.ShardId) Consumer(java.util.function.Consumer) AtomicArray(org.opensearch.common.util.concurrent.AtomicArray) AddBlockResult(org.opensearch.action.admin.indices.readonly.AddIndexBlockResponse.AddBlockResult) ActiveShardsObserver(org.opensearch.action.support.ActiveShardsObserver) ClusterService(org.opensearch.cluster.service.ClusterService) RoutingTable(org.opensearch.cluster.routing.RoutingTable) Collections.unmodifiableMap(java.util.Collections.unmodifiableMap) OpenIndexClusterStateUpdateResponse(org.opensearch.cluster.ack.OpenIndexClusterStateUpdateResponse) OpenIndexClusterStateUpdateRequest(org.opensearch.action.admin.indices.open.OpenIndexClusterStateUpdateRequest) LogManager(org.apache.logging.log4j.LogManager) Collections(java.util.Collections) ClusterState(org.opensearch.cluster.ClusterState) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ClusterStateUpdateTask(org.opensearch.cluster.ClusterStateUpdateTask) AckedClusterStateUpdateTask(org.opensearch.cluster.AckedClusterStateUpdateTask) Index(org.opensearch.index.Index) OpenSearchException(org.opensearch.OpenSearchException) SnapshotInProgressException(org.opensearch.snapshots.SnapshotInProgressException) IndexNotFoundException(org.opensearch.index.IndexNotFoundException) ClusterBlock(org.opensearch.cluster.block.ClusterBlock) CloseIndexResponse(org.opensearch.action.admin.indices.close.CloseIndexResponse) IndexResult(org.opensearch.action.admin.indices.close.CloseIndexResponse.IndexResult) Tuple(org.opensearch.common.collect.Tuple) TimeValue(org.opensearch.common.unit.TimeValue)

Example 2 with CloseIndexClusterStateUpdateRequest

use of org.opensearch.action.admin.indices.close.CloseIndexClusterStateUpdateRequest in project OpenSearch by opensearch-project.

the class MetadataIndexStateServiceTests method testCloseCurrentWriteIndexForDataStream.

public void testCloseCurrentWriteIndexForDataStream() {
    int numDataStreams = randomIntBetween(1, 3);
    List<Tuple<String, Integer>> dataStreamsToCreate = new ArrayList<>();
    List<String> writeIndices = new ArrayList<>();
    for (int k = 0; k < numDataStreams; k++) {
        String dataStreamName = randomAlphaOfLength(6).toLowerCase(Locale.ROOT);
        int numBackingIndices = randomIntBetween(1, 5);
        dataStreamsToCreate.add(new Tuple<>(dataStreamName, numBackingIndices));
        writeIndices.add(DataStream.getDefaultBackingIndexName(dataStreamName, numBackingIndices));
    }
    ClusterState cs = DeleteDataStreamRequestTests.getClusterStateWithDataStreams(dataStreamsToCreate, org.opensearch.common.collect.List.of());
    ClusterService clusterService = mock(ClusterService.class);
    when(clusterService.state()).thenReturn(cs);
    List<String> indicesToDelete = randomSubsetOf(randomIntBetween(1, numDataStreams), writeIndices);
    Index[] indicesToDeleteArray = new Index[indicesToDelete.size()];
    for (int k = 0; k < indicesToDelete.size(); k++) {
        Index indexToDelete = cs.metadata().index(indicesToDelete.get(k)).getIndex();
        indicesToDeleteArray[k] = indexToDelete;
    }
    MetadataIndexStateService service = new MetadataIndexStateService(clusterService, null, null, null, null, null, null, null);
    CloseIndexClusterStateUpdateRequest request = new CloseIndexClusterStateUpdateRequest(0L).indices(indicesToDeleteArray);
    Exception e = expectThrows(IllegalArgumentException.class, () -> service.closeIndices(request, null));
    assertThat(e.getMessage(), CoreMatchers.containsString("cannot close the following data stream write indices [" + Strings.collectionToCommaDelimitedString(indicesToDelete) + "]"));
}
Also used : ClusterState(org.opensearch.cluster.ClusterState) ArrayList(java.util.ArrayList) Index(org.opensearch.index.Index) Matchers.containsString(org.hamcrest.Matchers.containsString) SnapshotInProgressException(org.opensearch.snapshots.SnapshotInProgressException) IndexNotFoundException(org.opensearch.index.IndexNotFoundException) ClusterService(org.opensearch.cluster.service.ClusterService) CloseIndexClusterStateUpdateRequest(org.opensearch.action.admin.indices.close.CloseIndexClusterStateUpdateRequest) Tuple(org.opensearch.common.collect.Tuple)

Aggregations

ArrayList (java.util.ArrayList)2 CloseIndexClusterStateUpdateRequest (org.opensearch.action.admin.indices.close.CloseIndexClusterStateUpdateRequest)2 ClusterState (org.opensearch.cluster.ClusterState)2 IntObjectCursor (com.carrotsearch.hppc.cursors.IntObjectCursor)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 Collections.singleton (java.util.Collections.singleton)1 Collections.unmodifiableMap (java.util.Collections.unmodifiableMap)1 EnumSet (java.util.EnumSet)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 SortedMap (java.util.SortedMap)1 Consumer (java.util.function.Consumer)1 Collectors (java.util.stream.Collectors)1 LogManager (org.apache.logging.log4j.LogManager)1 Logger (org.apache.logging.log4j.Logger)1