use of org.opensearch.index.IndexNotFoundException in project OpenSearch by opensearch-project.
the class SimpleIndexStateIT method testConsistencyAfterIndexCreationFailure.
public void testConsistencyAfterIndexCreationFailure() {
logger.info("--> deleting test index....");
try {
client().admin().indices().prepareDelete("test").get();
} catch (IndexNotFoundException ex) {
// Ignore
}
logger.info("--> creating test index with invalid settings ");
try {
client().admin().indices().prepareCreate("test").setSettings(Settings.builder().put("number_of_shards", "bad")).get();
fail();
} catch (IllegalArgumentException ex) {
assertEquals("Failed to parse value [bad] for setting [index.number_of_shards]", ex.getMessage());
// Expected
}
logger.info("--> creating test index with valid settings ");
CreateIndexResponse response = client().admin().indices().prepareCreate("test").setSettings(Settings.builder().put("number_of_shards", 1)).get();
assertThat(response.isAcknowledged(), equalTo(true));
}
use of org.opensearch.index.IndexNotFoundException in project OpenSearch by opensearch-project.
the class MetadataIndexAliasesService method applyAliasActions.
/**
* Handles the cluster state transition to a version that reflects the provided {@link AliasAction}s.
*/
public ClusterState applyAliasActions(ClusterState currentState, Iterable<AliasAction> actions) {
List<Index> indicesToClose = new ArrayList<>();
Map<String, IndexService> indices = new HashMap<>();
try {
boolean changed = false;
// Gather all the indexes that must be removed first so:
// 1. We don't cause error when attempting to replace an index with a alias of the same name.
// 2. We don't allow removal of aliases from indexes that we're just going to delete anyway. That'd be silly.
Set<Index> indicesToDelete = new HashSet<>();
for (AliasAction action : actions) {
if (action.removeIndex()) {
IndexMetadata index = currentState.metadata().getIndices().get(action.getIndex());
if (index == null) {
throw new IndexNotFoundException(action.getIndex());
}
validateAliasTargetIsNotDSBackingIndex(currentState, action);
indicesToDelete.add(index.getIndex());
changed = true;
}
}
// Remove the indexes if there are any to remove
if (changed) {
currentState = deleteIndexService.deleteIndices(currentState, indicesToDelete);
}
Metadata.Builder metadata = Metadata.builder(currentState.metadata());
// Run the remaining alias actions
final Set<String> maybeModifiedIndices = new HashSet<>();
for (AliasAction action : actions) {
if (action.removeIndex()) {
// Handled above
continue;
}
IndexMetadata index = metadata.get(action.getIndex());
if (index == null) {
throw new IndexNotFoundException(action.getIndex());
}
validateAliasTargetIsNotDSBackingIndex(currentState, action);
NewAliasValidator newAliasValidator = (alias, indexRouting, filter, writeIndex) -> {
/* It is important that we look up the index using the metadata builder we are modifying so we can remove an
* index and replace it with an alias. */
Function<String, IndexMetadata> indexLookup = name -> metadata.get(name);
aliasValidator.validateAlias(alias, action.getIndex(), indexRouting, indexLookup);
if (Strings.hasLength(filter)) {
IndexService indexService = indices.get(index.getIndex().getName());
if (indexService == null) {
indexService = indicesService.indexService(index.getIndex());
if (indexService == null) {
// temporarily create the index and add mappings so we can parse the filter
try {
indexService = indicesService.createIndex(index, emptyList(), false);
indicesToClose.add(index.getIndex());
} catch (IOException e) {
throw new OpenSearchException("Failed to create temporary index for parsing the alias", e);
}
indexService.mapperService().merge(index, MapperService.MergeReason.MAPPING_RECOVERY);
}
indices.put(action.getIndex(), indexService);
}
// the context is only used for validation so it's fine to pass fake values for the shard id,
// but the current timestamp should be set to real value as we may use `now` in a filtered alias
aliasValidator.validateAliasFilter(alias, filter, indexService.newQueryShardContext(0, null, () -> System.currentTimeMillis(), null), xContentRegistry);
}
};
if (action.apply(newAliasValidator, metadata, index)) {
changed = true;
maybeModifiedIndices.add(index.getIndex().getName());
}
}
for (final String maybeModifiedIndex : maybeModifiedIndices) {
final IndexMetadata currentIndexMetadata = currentState.metadata().index(maybeModifiedIndex);
final IndexMetadata newIndexMetadata = metadata.get(maybeModifiedIndex);
// only increment the aliases version if the aliases actually changed for this index
if (currentIndexMetadata.getAliases().equals(newIndexMetadata.getAliases()) == false) {
assert currentIndexMetadata.getAliasesVersion() == newIndexMetadata.getAliasesVersion();
metadata.put(new IndexMetadata.Builder(newIndexMetadata).aliasesVersion(1 + currentIndexMetadata.getAliasesVersion()));
}
}
if (changed) {
ClusterState updatedState = ClusterState.builder(currentState).metadata(metadata).build();
// i.e. remove and add the same alias to the same index
if (!updatedState.metadata().equalsAliases(currentState.metadata())) {
return updatedState;
}
}
return currentState;
} finally {
for (Index index : indicesToClose) {
indicesService.removeIndex(index, NO_LONGER_ASSIGNED, "created for alias processing");
}
}
}
use of org.opensearch.index.IndexNotFoundException in project OpenSearch by opensearch-project.
the class MetadataIndexStateService method closeRoutingTable.
/**
* Step 3 - Move index states from OPEN to CLOSE in cluster state for indices that are ready for closing.
*/
static Tuple<ClusterState, Collection<IndexResult>> closeRoutingTable(final ClusterState currentState, final Map<Index, ClusterBlock> blockedIndices, final Map<Index, IndexResult> verifyResult) {
// Remove the index routing table of closed indices if the cluster is in a mixed version
// that does not support the replication of closed indices
final boolean removeRoutingTable = currentState.nodes().getMinNodeVersion().before(LegacyESVersion.V_7_2_0);
final Metadata.Builder metadata = Metadata.builder(currentState.metadata());
final ClusterBlocks.Builder blocks = ClusterBlocks.builder().blocks(currentState.blocks());
final RoutingTable.Builder routingTable = RoutingTable.builder(currentState.routingTable());
final Set<String> closedIndices = new HashSet<>();
Map<Index, IndexResult> closingResults = new HashMap<>(verifyResult);
for (Map.Entry<Index, IndexResult> result : verifyResult.entrySet()) {
final Index index = result.getKey();
final boolean acknowledged = result.getValue().hasFailures() == false;
try {
if (acknowledged == false) {
logger.debug("verification of shards before closing {} failed [{}]", index, result);
continue;
}
final IndexMetadata indexMetadata = metadata.getSafe(index);
if (indexMetadata.getState() == IndexMetadata.State.CLOSE) {
logger.debug("verification of shards before closing {} succeeded but index is already closed", index);
assert currentState.blocks().hasIndexBlock(index.getName(), INDEX_CLOSED_BLOCK);
continue;
}
final ClusterBlock closingBlock = blockedIndices.get(index);
assert closingBlock != null;
if (currentState.blocks().hasIndexBlock(index.getName(), closingBlock) == false) {
// we should report error in this case as the index can be left as open.
closingResults.put(result.getKey(), new IndexResult(result.getKey(), new IllegalStateException("verification of shards before closing " + index + " succeeded but block has been removed in the meantime")));
logger.debug("verification of shards before closing {} succeeded but block has been removed in the meantime", index);
continue;
}
// Check if index closing conflicts with any running restores
Set<Index> restoringIndices = RestoreService.restoringIndices(currentState, singleton(index));
if (restoringIndices.isEmpty() == false) {
closingResults.put(result.getKey(), new IndexResult(result.getKey(), new IllegalStateException("verification of shards before closing " + index + " succeeded but index is being restored in the meantime")));
logger.debug("verification of shards before closing {} succeeded but index is being restored in the meantime", index);
continue;
}
// Check if index closing conflicts with any running snapshots
Set<Index> snapshottingIndices = SnapshotsService.snapshottingIndices(currentState, singleton(index));
if (snapshottingIndices.isEmpty() == false) {
closingResults.put(result.getKey(), new IndexResult(result.getKey(), new IllegalStateException("verification of shards before closing " + index + " succeeded but index is being snapshot in the meantime")));
logger.debug("verification of shards before closing {} succeeded but index is being snapshot in the meantime", index);
continue;
}
blocks.removeIndexBlockWithId(index.getName(), INDEX_CLOSED_BLOCK_ID);
blocks.addIndexBlock(index.getName(), INDEX_CLOSED_BLOCK);
final IndexMetadata.Builder updatedMetadata = IndexMetadata.builder(indexMetadata).state(IndexMetadata.State.CLOSE);
if (removeRoutingTable) {
metadata.put(updatedMetadata);
routingTable.remove(index.getName());
} else {
metadata.put(updatedMetadata.settingsVersion(indexMetadata.getSettingsVersion() + 1).settings(Settings.builder().put(indexMetadata.getSettings()).put(VERIFIED_BEFORE_CLOSE_SETTING.getKey(), true)));
routingTable.addAsFromOpenToClose(metadata.getSafe(index));
}
logger.debug("closing index {} succeeded", index);
closedIndices.add(index.getName());
} catch (final IndexNotFoundException e) {
logger.debug("index {} has been deleted since it was blocked before closing, ignoring", index);
}
}
logger.info("completed closing of indices {}", closedIndices);
return Tuple.tuple(ClusterState.builder(currentState).blocks(blocks).metadata(metadata).routingTable(routingTable.build()).build(), closingResults.values());
}
use of org.opensearch.index.IndexNotFoundException in project OpenSearch by opensearch-project.
the class MetadataIndexStateService method finalizeBlock.
/**
* Finalizes the addition of blocks by turning the temporary UUID-based blocks into full blocks.
* @param currentState the cluster state to update
* @param blockedIndices the indices and their temporary UUID-based blocks to convert
* @param verifyResult the index-level results for adding the block
* @param block the full block to convert to
* @return the updated cluster state, as well as the (failed and successful) index-level results for adding the block
*/
static Tuple<ClusterState, Collection<AddBlockResult>> finalizeBlock(final ClusterState currentState, final Map<Index, ClusterBlock> blockedIndices, final Map<Index, AddBlockResult> verifyResult, final APIBlock block) {
final Metadata.Builder metadata = Metadata.builder(currentState.metadata());
final ClusterBlocks.Builder blocks = ClusterBlocks.builder().blocks(currentState.blocks());
final RoutingTable.Builder routingTable = RoutingTable.builder(currentState.routingTable());
final Set<String> effectivelyBlockedIndices = new HashSet<>();
Map<Index, AddBlockResult> blockingResults = new HashMap<>(verifyResult);
for (Map.Entry<Index, AddBlockResult> result : verifyResult.entrySet()) {
final Index index = result.getKey();
final boolean acknowledged = result.getValue().hasFailures() == false;
try {
if (acknowledged == false) {
logger.debug("verification of shards before blocking {} failed [{}]", index, result);
continue;
}
final IndexMetadata indexMetadata = metadata.getSafe(index);
final ClusterBlock tempBlock = blockedIndices.get(index);
assert tempBlock != null;
assert tempBlock.uuid() != null;
final ClusterBlock currentBlock = currentState.blocks().getIndexBlockWithId(index.getName(), tempBlock.id());
if (currentBlock != null && currentBlock.equals(block.block)) {
logger.debug("verification of shards for {} succeeded, but block finalization already occurred" + " (possibly for another block) [{}]", index, result);
continue;
}
if (currentBlock == null || currentBlock.equals(tempBlock) == false) {
// we should report error in this case as the index can be left as open.
blockingResults.put(result.getKey(), new AddBlockResult(result.getKey(), new IllegalStateException("verification of shards before blocking " + index + " succeeded but block has been removed in the meantime")));
logger.debug("verification of shards before blocking {} succeeded but block has been removed in the meantime", index);
continue;
}
assert currentBlock != null && currentBlock.equals(tempBlock) && currentBlock.id() == block.block.id();
blocks.removeIndexBlockWithId(index.getName(), tempBlock.id());
blocks.addIndexBlock(index.getName(), block.block);
logger.debug("add block {} to index {} succeeded", block.block, index);
effectivelyBlockedIndices.add(index.getName());
} catch (final IndexNotFoundException e) {
logger.debug("index {} has been deleted since blocking it started, ignoring", index);
}
}
logger.info("completed adding block {} to indices {}", block.name, effectivelyBlockedIndices);
return Tuple.tuple(ClusterState.builder(currentState).blocks(blocks).metadata(metadata).routingTable(routingTable.build()).build(), blockingResults.values());
}
use of org.opensearch.index.IndexNotFoundException in project OpenSearch by opensearch-project.
the class IndexNameExpressionResolver method concreteIndices.
Index[] concreteIndices(Context context, String... indexExpressions) {
if (indexExpressions == null || indexExpressions.length == 0) {
indexExpressions = new String[] { Metadata.ALL };
}
Metadata metadata = context.getState().metadata();
IndicesOptions options = context.getOptions();
// If only one index is specified then whether we fail a request if an index is missing depends on the allow_no_indices
// option. At some point we should change this, because there shouldn't be a reason why whether a single index
// or multiple indices are specified yield different behaviour.
final boolean failNoIndices = indexExpressions.length == 1 ? !options.allowNoIndices() : !options.ignoreUnavailable();
List<String> expressions = Arrays.asList(indexExpressions);
for (ExpressionResolver expressionResolver : expressionResolvers) {
expressions = expressionResolver.resolve(context, expressions);
}
if (expressions.isEmpty()) {
if (!options.allowNoIndices()) {
IndexNotFoundException infe;
if (indexExpressions.length == 1) {
if (indexExpressions[0].equals(Metadata.ALL)) {
infe = new IndexNotFoundException("no indices exist", (String) null);
} else {
infe = new IndexNotFoundException((String) null);
}
} else {
infe = new IndexNotFoundException((String) null);
}
infe.setResources("index_expression", indexExpressions);
throw infe;
} else {
return Index.EMPTY_ARRAY;
}
}
boolean excludedDataStreams = false;
final Set<Index> concreteIndices = new HashSet<>(expressions.size());
for (String expression : expressions) {
IndexAbstraction indexAbstraction = metadata.getIndicesLookup().get(expression);
if (indexAbstraction == null) {
if (failNoIndices) {
IndexNotFoundException infe;
if (expression.equals(Metadata.ALL)) {
infe = new IndexNotFoundException("no indices exist", expression);
} else {
infe = new IndexNotFoundException(expression);
}
infe.setResources("index_expression", expression);
throw infe;
} else {
continue;
}
} else if (indexAbstraction.getType() == IndexAbstraction.Type.ALIAS && context.getOptions().ignoreAliases()) {
if (failNoIndices) {
throw aliasesNotSupportedException(expression);
} else {
continue;
}
} else if (indexAbstraction.getType() == IndexAbstraction.Type.DATA_STREAM && context.includeDataStreams() == false) {
excludedDataStreams = true;
continue;
}
if (indexAbstraction.getType() == IndexAbstraction.Type.ALIAS && context.isResolveToWriteIndex()) {
IndexMetadata writeIndex = indexAbstraction.getWriteIndex();
if (writeIndex == null) {
throw new IllegalArgumentException("no write index is defined for alias [" + indexAbstraction.getName() + "]." + " The write index may be explicitly disabled using is_write_index=false or the alias points to multiple" + " indices without one being designated as a write index");
}
if (addIndex(writeIndex, context)) {
concreteIndices.add(writeIndex.getIndex());
}
} else if (indexAbstraction.getType() == IndexAbstraction.Type.DATA_STREAM && context.isResolveToWriteIndex()) {
IndexMetadata writeIndex = indexAbstraction.getWriteIndex();
if (addIndex(writeIndex, context)) {
concreteIndices.add(writeIndex.getIndex());
}
} else {
if (indexAbstraction.getIndices().size() > 1 && !options.allowAliasesToMultipleIndices()) {
String[] indexNames = new String[indexAbstraction.getIndices().size()];
int i = 0;
for (IndexMetadata indexMetadata : indexAbstraction.getIndices()) {
indexNames[i++] = indexMetadata.getIndex().getName();
}
throw new IllegalArgumentException(indexAbstraction.getType().getDisplayName() + " [" + expression + "] has more than one index associated with it " + Arrays.toString(indexNames) + ", can't execute a single index op");
}
for (IndexMetadata index : indexAbstraction.getIndices()) {
if (shouldTrackConcreteIndex(context, options, index)) {
concreteIndices.add(index.getIndex());
}
}
}
}
if (options.allowNoIndices() == false && concreteIndices.isEmpty()) {
IndexNotFoundException infe = new IndexNotFoundException((String) null);
infe.setResources("index_expression", indexExpressions);
if (excludedDataStreams) {
// Allows callers to handle IndexNotFoundException differently based on whether data streams were excluded.
infe.addMetadata(EXCLUDED_DATA_STREAMS_KEY, "true");
}
throw infe;
}
checkSystemIndexAccess(context, metadata, concreteIndices, indexExpressions);
return concreteIndices.toArray(new Index[concreteIndices.size()]);
}
Aggregations