Core: `ignore_unavailable` shouldn't ignore closed indices if a single index is specified in a search or broadcast request.

Closes #9047
Closes #7153
This commit is contained in:
Martijn van Groningen 2014-12-23 14:47:13 +01:00
parent 7678ab5264
commit a345e98575
3 changed files with 180 additions and 20 deletions

View File

@ -23,15 +23,13 @@ import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.search.type.*; import org.elasticsearch.action.search.type.*;
import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.HandledTransportAction; import org.elasticsearch.action.support.HandledTransportAction;
import org.elasticsearch.action.support.TransportAction;
import org.elasticsearch.cluster.ClusterService; import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.indices.IndexClosedException;
import org.elasticsearch.indices.IndexMissingException; import org.elasticsearch.indices.IndexMissingException;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.BaseTransportRequestHandler;
import org.elasticsearch.transport.TransportChannel;
import org.elasticsearch.transport.TransportService; import org.elasticsearch.transport.TransportService;
import java.util.Map; import java.util.Map;
@ -89,9 +87,8 @@ public class TransportSearchAction extends HandledTransportAction<SearchRequest,
// if we only have one group, then we always want Q_A_F, no need for DFS, and no need to do THEN since we hit one shard // if we only have one group, then we always want Q_A_F, no need for DFS, and no need to do THEN since we hit one shard
searchRequest.searchType(QUERY_AND_FETCH); searchRequest.searchType(QUERY_AND_FETCH);
} }
} catch (IndexMissingException e) { } catch (IndexMissingException|IndexClosedException e) {
// ignore this, we will notify the search response if its really the case // ignore these failures, we will notify the search response if its really the case from the actual action
// from the actual action
} catch (Exception e) { } catch (Exception e) {
logger.debug("failed to optimize search type, continue as normal", e); logger.debug("failed to optimize search type, continue as normal", e);
} }

View File

@ -679,7 +679,7 @@ public class MetaData implements Iterable<IndexMetaData> {
// optimize for single element index (common case) // optimize for single element index (common case)
if (aliasesOrIndices.length == 1) { if (aliasesOrIndices.length == 1) {
return concreteIndices(aliasesOrIndices[0], indicesOptions.allowNoIndices(), failClosed, indicesOptions.allowAliasesToMultipleIndices()); return concreteIndices(aliasesOrIndices[0], indicesOptions.allowNoIndices(), indicesOptions);
} }
// check if its a possible aliased index, if not, just return the passed array // check if its a possible aliased index, if not, just return the passed array
@ -712,7 +712,7 @@ public class MetaData implements Iterable<IndexMetaData> {
Set<String> actualIndices = new HashSet<>(); Set<String> actualIndices = new HashSet<>();
for (String aliasOrIndex : aliasesOrIndices) { for (String aliasOrIndex : aliasesOrIndices) {
String[] indices = concreteIndices(aliasOrIndex, indicesOptions.ignoreUnavailable(), failClosed, indicesOptions.allowAliasesToMultipleIndices()); String[] indices = concreteIndices(aliasOrIndex, indicesOptions.ignoreUnavailable(), indicesOptions);
Collections.addAll(actualIndices, indices); Collections.addAll(actualIndices, indices);
} }
@ -723,7 +723,6 @@ public class MetaData implements Iterable<IndexMetaData> {
} }
/** /**
*
* Utility method that allows to resolve an index or alias to its corresponding single concrete index. * Utility method that allows to resolve an index or alias to its corresponding single concrete index.
* Callers should make sure they provide proper {@link org.elasticsearch.action.support.IndicesOptions} * Callers should make sure they provide proper {@link org.elasticsearch.action.support.IndicesOptions}
* that require a single index as a result. The indices resolution must in fact return a single index when * that require a single index as a result. The indices resolution must in fact return a single index when
@ -743,12 +742,18 @@ public class MetaData implements Iterable<IndexMetaData> {
return indices[0]; return indices[0];
} }
private String[] concreteIndices(String aliasOrIndex, boolean allowNoIndices, boolean failClosed, boolean allowMultipleIndices) throws IndexMissingException, ElasticsearchIllegalArgumentException { private String[] concreteIndices(String aliasOrIndex, boolean allowNoIndices, IndicesOptions options) throws IndexMissingException, ElasticsearchIllegalArgumentException {
boolean failClosed = options.forbidClosedIndices() && !options.ignoreUnavailable();
// a quick check, if this is an actual index, if so, return it // a quick check, if this is an actual index, if so, return it
IndexMetaData indexMetaData = indices.get(aliasOrIndex); IndexMetaData indexMetaData = indices.get(aliasOrIndex);
if (indexMetaData != null) { if (indexMetaData != null) {
if (indexMetaData.getState() == IndexMetaData.State.CLOSE && failClosed) { if (indexMetaData.getState() == IndexMetaData.State.CLOSE) {
if (failClosed) {
throw new IndexClosedException(new Index(aliasOrIndex)); throw new IndexClosedException(new Index(aliasOrIndex));
} else {
return options.forbidClosedIndices() ? Strings.EMPTY_ARRAY : new String[]{aliasOrIndex};
}
} else { } else {
return new String[]{aliasOrIndex}; return new String[]{aliasOrIndex};
} }
@ -758,13 +763,19 @@ public class MetaData implements Iterable<IndexMetaData> {
if (indices.length == 0 && !allowNoIndices) { if (indices.length == 0 && !allowNoIndices) {
throw new IndexMissingException(new Index(aliasOrIndex)); throw new IndexMissingException(new Index(aliasOrIndex));
} }
if (indices.length > 1 && !allowMultipleIndices) { if (indices.length > 1 && !options.allowAliasesToMultipleIndices()) {
throw new ElasticsearchIllegalArgumentException("Alias [" + aliasOrIndex + "] has more than one indices associated with it [" + Arrays.toString(indices) + "], can't execute a single index op"); throw new ElasticsearchIllegalArgumentException("Alias [" + aliasOrIndex + "] has more than one indices associated with it [" + Arrays.toString(indices) + "], can't execute a single index op");
} }
indexMetaData = this.indices.get(aliasOrIndex); indexMetaData = this.indices.get(aliasOrIndex);
if (indexMetaData != null && indexMetaData.getState() == IndexMetaData.State.CLOSE && failClosed) { if (indexMetaData != null && indexMetaData.getState() == IndexMetaData.State.CLOSE) {
if (failClosed) {
throw new IndexClosedException(new Index(aliasOrIndex)); throw new IndexClosedException(new Index(aliasOrIndex));
} else {
if (options.forbidClosedIndices()) {
return Strings.EMPTY_ARRAY;
}
}
} }
return indices; return indices;
} }
@ -1317,7 +1328,7 @@ public class MetaData implements Iterable<IndexMetaData> {
for (ObjectObjectCursor<String, Custom> cursor : metaData.customs()) { for (ObjectObjectCursor<String, Custom> cursor : metaData.customs()) {
Custom.Factory factory = lookupFactorySafe(cursor.key); Custom.Factory factory = lookupFactorySafe(cursor.key);
if(factory.context().contains(context)) { if (factory.context().contains(context)) {
builder.startObject(cursor.key); builder.startObject(cursor.key);
factory.toXContent(cursor.value, builder, params); factory.toXContent(cursor.value, builder, params);
builder.endObject(); builder.endObject();

View File

@ -68,7 +68,7 @@ import static org.hamcrest.Matchers.*;
public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest { public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest {
@Test @Test
public void testSpecifiedIndexUnavailable() throws Exception { public void testSpecifiedIndexUnavailable_multipleIndices() throws Exception {
createIndex("test1"); createIndex("test1");
ensureYellow(); ensureYellow();
@ -167,6 +167,158 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
verify(getSettings("test1", "test2").setIndicesOptions(options), false); verify(getSettings("test1", "test2").setIndicesOptions(options), false);
} }
@Test
public void testSpecifiedIndexUnavailable_singleIndexThatIsClosed() throws Exception {
assertAcked(prepareCreate("test1"));
ensureYellow();
assertAcked(client().admin().indices().prepareClose("test1"));
IndicesOptions options = IndicesOptions.strictExpandOpenAndForbidClosed();
verify(search("test1").setIndicesOptions(options), true);
verify(msearch(options, "test1"), true);
verify(count("test1").setIndicesOptions(options), true);
verify(clearCache("test1").setIndicesOptions(options), true);
verify(_flush("test1").setIndicesOptions(options),true);
verify(segments("test1").setIndicesOptions(options), true);
verify(stats("test1").setIndicesOptions(options), true);
verify(optimize("test1").setIndicesOptions(options), true);
verify(refresh("test1").setIndicesOptions(options), true);
verify(validateQuery("test1").setIndicesOptions(options), true);
verify(aliasExists("test1").setIndicesOptions(options), true);
verify(typesExists("test1").setIndicesOptions(options), true);
verify(deleteByQuery("test1").setIndicesOptions(options), true);
verify(percolate("test1").setIndicesOptions(options), true);
verify(mpercolate(options, "test1").setIndicesOptions(options), true);
verify(suggest("test1").setIndicesOptions(options), true);
verify(getAliases("test1").setIndicesOptions(options), true);
verify(getFieldMapping("test1").setIndicesOptions(options), true);
verify(getMapping("test1").setIndicesOptions(options), true);
verify(getWarmer("test1").setIndicesOptions(options), true);
verify(getSettings("test1").setIndicesOptions(options), true);
options = IndicesOptions.fromOptions(true, options.allowNoIndices(), options.expandWildcardsOpen(), options.expandWildcardsClosed(), options);
verify(search("test1").setIndicesOptions(options), false);
verify(msearch(options, "test1"), false);
verify(count("test1").setIndicesOptions(options), false);
verify(clearCache("test1").setIndicesOptions(options), false);
verify(_flush("test1").setIndicesOptions(options),false);
verify(segments("test1").setIndicesOptions(options), false);
verify(stats("test1").setIndicesOptions(options), false);
verify(optimize("test1").setIndicesOptions(options), false);
verify(refresh("test1").setIndicesOptions(options), false);
verify(validateQuery("test1").setIndicesOptions(options), false);
verify(aliasExists("test1").setIndicesOptions(options), false);
verify(typesExists("test1").setIndicesOptions(options), false);
verify(deleteByQuery("test1").setIndicesOptions(options), false);
verify(percolate("test1").setIndicesOptions(options), false);
verify(mpercolate(options, "test1").setIndicesOptions(options), false);
verify(suggest("test1").setIndicesOptions(options), false);
verify(getAliases("test1").setIndicesOptions(options), false);
verify(getFieldMapping("test1").setIndicesOptions(options), false);
verify(getMapping("test1").setIndicesOptions(options), false);
verify(getWarmer("test1").setIndicesOptions(options), false);
verify(getSettings("test1").setIndicesOptions(options), false);
assertAcked(client().admin().indices().prepareOpen("test1"));
ensureYellow();
options = IndicesOptions.strictExpandOpenAndForbidClosed();
verify(search("test1").setIndicesOptions(options), false);
verify(msearch(options, "test1"), false);
verify(count("test1").setIndicesOptions(options), false);
verify(clearCache("test1").setIndicesOptions(options), false);
verify(_flush("test1").setIndicesOptions(options),false);
verify(segments("test1").setIndicesOptions(options), false);
verify(stats("test1").setIndicesOptions(options), false);
verify(optimize("test1").setIndicesOptions(options), false);
verify(refresh("test1").setIndicesOptions(options), false);
verify(validateQuery("test1").setIndicesOptions(options), false);
verify(aliasExists("test1").setIndicesOptions(options), false);
verify(typesExists("test1").setIndicesOptions(options), false);
verify(deleteByQuery("test1").setIndicesOptions(options), false);
verify(percolate("test1").setIndicesOptions(options), false);
verify(mpercolate(options, "test1").setIndicesOptions(options), false);
verify(suggest("test1").setIndicesOptions(options), false);
verify(getAliases("test1").setIndicesOptions(options), false);
verify(getFieldMapping("test1").setIndicesOptions(options), false);
verify(getMapping("test1").setIndicesOptions(options), false);
verify(getWarmer("test1").setIndicesOptions(options), false);
verify(getSettings("test1").setIndicesOptions(options), false);
}
@Test
public void testSpecifiedIndexUnavailable_singleIndex() throws Exception {
IndicesOptions options = IndicesOptions.strictExpandOpenAndForbidClosed();
verify(search("test1").setIndicesOptions(options), true);
verify(msearch(options, "test1"), true);
verify(count("test1").setIndicesOptions(options), true);
verify(clearCache("test1").setIndicesOptions(options), true);
verify(_flush("test1").setIndicesOptions(options),true);
verify(segments("test1").setIndicesOptions(options), true);
verify(stats("test1").setIndicesOptions(options), true);
verify(optimize("test1").setIndicesOptions(options), true);
verify(refresh("test1").setIndicesOptions(options), true);
verify(validateQuery("test1").setIndicesOptions(options), true);
verify(aliasExists("test1").setIndicesOptions(options), true);
verify(typesExists("test1").setIndicesOptions(options), true);
verify(deleteByQuery("test1").setIndicesOptions(options), true);
verify(percolate("test1").setIndicesOptions(options), true);
verify(suggest("test1").setIndicesOptions(options), true);
verify(getAliases("test1").setIndicesOptions(options), true);
verify(getFieldMapping("test1").setIndicesOptions(options), true);
verify(getMapping("test1").setIndicesOptions(options), true);
verify(getWarmer("test1").setIndicesOptions(options), true);
verify(getSettings("test1").setIndicesOptions(options), true);
options = IndicesOptions.fromOptions(true, options.allowNoIndices(), options.expandWildcardsOpen(), options.expandWildcardsClosed(), options);
verify(search("test1").setIndicesOptions(options), false);
verify(msearch(options, "test1"), false);
verify(count("test1").setIndicesOptions(options), false);
verify(clearCache("test1").setIndicesOptions(options), false);
verify(_flush("test1").setIndicesOptions(options),false);
verify(segments("test1").setIndicesOptions(options), false);
verify(stats("test1").setIndicesOptions(options), false);
verify(optimize("test1").setIndicesOptions(options), false);
verify(refresh("test1").setIndicesOptions(options), false);
verify(validateQuery("test1").setIndicesOptions(options), false);
verify(aliasExists("test1").setIndicesOptions(options), false);
verify(typesExists("test1").setIndicesOptions(options), false);
verify(deleteByQuery("test1").setIndicesOptions(options), false);
verify(percolate("test1").setIndicesOptions(options), false);
verify(suggest("test1").setIndicesOptions(options), false);
verify(getAliases("test1").setIndicesOptions(options), false);
verify(getFieldMapping("test1").setIndicesOptions(options), false);
verify(getMapping("test1").setIndicesOptions(options), false);
verify(getWarmer("test1").setIndicesOptions(options), false);
verify(getSettings("test1").setIndicesOptions(options), false);
assertAcked(prepareCreate("test1"));
ensureYellow();
options = IndicesOptions.strictExpandOpenAndForbidClosed();
verify(search("test1").setIndicesOptions(options), false);
verify(msearch(options, "test1"), false);
verify(count("test1").setIndicesOptions(options), false);
verify(clearCache("test1").setIndicesOptions(options), false);
verify(_flush("test1").setIndicesOptions(options),false);
verify(segments("test1").setIndicesOptions(options), false);
verify(stats("test1").setIndicesOptions(options), false);
verify(optimize("test1").setIndicesOptions(options), false);
verify(refresh("test1").setIndicesOptions(options), false);
verify(validateQuery("test1").setIndicesOptions(options), false);
verify(aliasExists("test1").setIndicesOptions(options), false);
verify(typesExists("test1").setIndicesOptions(options), false);
verify(deleteByQuery("test1").setIndicesOptions(options), false);
verify(percolate("test1").setIndicesOptions(options), false);
verify(suggest("test1").setIndicesOptions(options), false);
verify(getAliases("test1").setIndicesOptions(options), false);
verify(getFieldMapping("test1").setIndicesOptions(options), false);
verify(getMapping("test1").setIndicesOptions(options), false);
verify(getWarmer("test1").setIndicesOptions(options), false);
verify(getSettings("test1").setIndicesOptions(options), false);
}
@Test @Test
public void testSpecifiedIndexUnavailable_snapshotRestore() throws Exception { public void testSpecifiedIndexUnavailable_snapshotRestore() throws Exception {
createIndex("test1"); createIndex("test1");