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();
}
});
}
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) + "]"));
}
Aggregations