Kaynağa Gözat

Snapshot/Restore: make handling of expand_wildcards option consistent

Closes #6097
Igor Motov 10 yıl önce
ebeveyn
işleme
7bd4654bf3

+ 1 - 5
src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java

@@ -385,10 +385,6 @@ public class CreateSnapshotRequest extends MasterNodeOperationRequest<CreateSnap
                 } else {
                     throw new ElasticsearchIllegalArgumentException("malformed indices section, should be an array of strings");
                 }
-            } else if (name.equals("ignore_unavailable") || name.equals("ignoreUnavailable")) {
-                ignoreUnavailable = nodeBooleanValue(entry.getValue());
-            } else if (name.equals("allow_no_indices") || name.equals("allowNoIndices")) {
-                allowNoIndices = nodeBooleanValue(entry.getValue());
             } else if (name.equals("expand_wildcards_open") || name.equals("expandWildcardsOpen")) {
                 expandWildcardsOpen = nodeBooleanValue(entry.getValue());
             } else if (name.equals("expand_wildcards_closed") || name.equals("expandWildcardsClosed")) {
@@ -404,7 +400,7 @@ public class CreateSnapshotRequest extends MasterNodeOperationRequest<CreateSnap
                 includeGlobalState = nodeBooleanValue(entry.getValue());
             }
         }
-        indicesOptions(IndicesOptions.fromOptions(ignoreUnavailable, allowNoIndices, expandWildcardsOpen, expandWildcardsClosed));
+        indicesOptions(IndicesOptions.fromMap((Map<String, Object>) source, IndicesOptions.fromOptions(ignoreUnavailable, allowNoIndices, expandWildcardsOpen, expandWildcardsClosed)));
         return this;
     }
 

+ 1 - 5
src/main/java/org/elasticsearch/action/admin/cluster/snapshots/restore/RestoreSnapshotRequest.java

@@ -519,10 +519,6 @@ public class RestoreSnapshotRequest extends MasterNodeOperationRequest<RestoreSn
                 } else {
                     throw new ElasticsearchIllegalArgumentException("malformed indices section, should be an array of strings");
                 }
-            } else if (name.equals("ignore_unavailable") || name.equals("ignoreUnavailable")) {
-                ignoreUnavailable = nodeBooleanValue(entry.getValue());
-            } else if (name.equals("allow_no_indices") || name.equals("allowNoIndices")) {
-                allowNoIndices = nodeBooleanValue(entry.getValue());
             } else if (name.equals("expand_wildcards_open") || name.equals("expandWildcardsOpen")) {
                 expandWildcardsOpen = nodeBooleanValue(entry.getValue());
             } else if (name.equals("expand_wildcards_closed") || name.equals("expandWildcardsClosed")) {
@@ -567,7 +563,7 @@ public class RestoreSnapshotRequest extends MasterNodeOperationRequest<RestoreSn
                 throw new ElasticsearchIllegalArgumentException("Unknown parameter " + name);
             }
         }
-        indicesOptions(IndicesOptions.fromOptions(ignoreUnavailable, allowNoIndices, expandWildcardsOpen, expandWildcardsClosed));
+        indicesOptions(IndicesOptions.fromMap((Map<String, Object>) source, IndicesOptions.fromOptions(ignoreUnavailable, allowNoIndices, expandWildcardsOpen, expandWildcardsClosed)));
         return this;
     }
 

+ 17 - 99
src/main/java/org/elasticsearch/action/percolate/MultiPercolateRequest.java

@@ -37,12 +37,12 @@ import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.common.xcontent.XContentParser;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import static org.elasticsearch.action.ValidateActions.addValidationError;
+import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeStringArrayValue;
+import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeStringValue;
 
 /**
  * A multi percolate request that encapsulates multiple {@link PercolateRequest} instances in a single api call.
@@ -175,13 +175,7 @@ public class MultiPercolateRequest extends ActionRequest<MultiPercolateRequest>
     private void parsePercolateAction(XContentParser parser, PercolateRequest percolateRequest, boolean allowExplicitIndex) throws IOException {
         String globalIndex = indices != null && indices.length > 0 ? indices[0] : null;
 
-        Map<String, Object> header = parseToMap(parser);
-
-        IndicesOptions defaultOptions = indicesOptions;
-        boolean ignoreUnavailable = defaultOptions.ignoreUnavailable();
-        boolean allowNoIndices = defaultOptions.allowNoIndices();
-        boolean expandWildcardsOpen = defaultOptions.expandWildcardsOpen();
-        boolean expandWildcardsClosed = defaultOptions.expandWildcardsClosed();
+        Map<String, Object> header = parser.map();
 
         if (header.containsKey("id")) {
             GetRequest getRequest = new GetRequest(globalIndex);
@@ -189,52 +183,27 @@ public class MultiPercolateRequest extends ActionRequest<MultiPercolateRequest>
             for (Map.Entry<String, Object> entry : header.entrySet()) {
                 Object value = entry.getValue();
                 if ("id".equals(entry.getKey())) {
-                    getRequest.id((String) value);
+                    getRequest.id(nodeStringValue(value, null));
                     header.put("id", entry.getValue());
                 } else if ("index".equals(entry.getKey()) || "indices".equals(entry.getKey())) {
                     if (!allowExplicitIndex) {
                         throw new ElasticsearchIllegalArgumentException("explicit index in multi percolate is not allowed");
                     }
-                    getRequest.index((String) value);
+                    getRequest.index(nodeStringValue(value, null));
                 } else if ("type".equals(entry.getKey())) {
-                    getRequest.type((String) value);
+                    getRequest.type(nodeStringValue(value, null));
                 } else if ("preference".equals(entry.getKey())) {
-                    getRequest.preference((String) value);
+                    getRequest.preference(nodeStringValue(value, null));
                 } else if ("routing".equals(entry.getKey())) {
-                    getRequest.routing((String) value);
+                    getRequest.routing(nodeStringValue(value, null));
                 } else if ("percolate_index".equals(entry.getKey()) || "percolate_indices".equals(entry.getKey()) || "percolateIndex".equals(entry.getKey()) || "percolateIndices".equals(entry.getKey())) {
-                    if (value instanceof String[]) {
-                        percolateRequest.indices((String[]) value);
-                    } else {
-                        percolateRequest.indices(Strings.splitStringByCommaToArray((String) value));
-                    }
+                    percolateRequest.indices(nodeStringArrayValue(value));
                 } else if ("percolate_type".equals(entry.getKey()) || "percolateType".equals(entry.getKey())) {
-                    percolateRequest.documentType((String) value);
+                    percolateRequest.documentType(nodeStringValue(value, null));
                 } else if ("percolate_preference".equals(entry.getKey()) || "percolatePreference".equals(entry.getKey())) {
-                    percolateRequest.preference((String) value);
+                    percolateRequest.preference(nodeStringValue(value, null));
                 } else if ("percolate_routing".equals(entry.getKey()) || "percolateRouting".equals(entry.getKey())) {
-                    percolateRequest.routing((String) value);
-                } else if ("ignore_unavailable".equals(entry.getKey()) || "ignoreUnavailable".equals(entry.getKey())) {
-                    ignoreUnavailable = Boolean.valueOf((String) value);
-                } else if ("allow_no_indices".equals(entry.getKey()) || "allowNoIndices".equals(entry.getKey())) {
-                    allowNoIndices = Boolean.valueOf((String) value);
-                } else if ("expand_wildcards".equals(entry.getKey()) || "expandWildcards".equals(entry.getKey())) {
-                    String[] wildcards;
-                    if (value instanceof String[]) {
-                        wildcards = (String[]) value;
-                    } else {
-                        wildcards = Strings.splitStringByCommaToArray((String) value);
-                    }
-
-                    for (String wildcard : wildcards) {
-                        if ("open".equals(wildcard)) {
-                            expandWildcardsOpen = true;
-                        } else if ("closed".equals(wildcard)) {
-                            expandWildcardsClosed = true;
-                        } else {
-                            throw new ElasticsearchIllegalArgumentException("No valid expand wildcard value [" + wildcard + "]");
-                        }
-                    }
+                    percolateRequest.routing(nodeStringValue(value, null));
                 }
             }
 
@@ -258,68 +227,17 @@ public class MultiPercolateRequest extends ActionRequest<MultiPercolateRequest>
                     if (!allowExplicitIndex) {
                         throw new ElasticsearchIllegalArgumentException("explicit index in multi percolate is not allowed");
                     }
-                    if (value instanceof String[]) {
-                        percolateRequest.indices((String[]) value);
-                    } else {
-                        percolateRequest.indices(Strings.splitStringByCommaToArray((String) value));
-                    }
+                    percolateRequest.indices(nodeStringArrayValue(value));
                 } else if ("type".equals(entry.getKey())) {
-                    percolateRequest.documentType((String) value);
+                    percolateRequest.documentType(nodeStringValue(value, null));
                 } else if ("preference".equals(entry.getKey())) {
-                    percolateRequest.preference((String) value);
+                    percolateRequest.preference(nodeStringValue(value, null));
                 } else if ("routing".equals(entry.getKey())) {
-                    percolateRequest.routing((String) value);
-                } else if ("ignore_unavailable".equals(entry.getKey()) || "ignoreUnavailable".equals(entry.getKey())) {
-                    ignoreUnavailable = Boolean.valueOf((String) value);
-                } else if ("allow_no_indices".equals(entry.getKey()) || "allowNoIndices".equals(entry.getKey())) {
-                    allowNoIndices = Boolean.valueOf((String) value);
-                } else if ("expand_wildcards".equals(entry.getKey()) || "expandWildcards".equals(entry.getKey())) {
-                    String[] wildcards;
-                    if (value instanceof String[]) {
-                        wildcards = (String[]) value;
-                    } else {
-                        wildcards = Strings.splitStringByCommaToArray((String) value);
-                    }
-
-                    for (String wildcard : wildcards) {
-                        if ("open".equals(wildcard)) {
-                            expandWildcardsOpen = true;
-                        } else if ("closed".equals(wildcard)) {
-                            expandWildcardsClosed = true;
-                        } else {
-                            throw new ElasticsearchIllegalArgumentException("No valid expand wildcard value [" + wildcard + "]");
-                        }
-                    }
+                    percolateRequest.routing(nodeStringValue(value, null));
                 }
             }
         }
-        percolateRequest.indicesOptions(IndicesOptions.fromOptions(ignoreUnavailable, allowNoIndices, expandWildcardsOpen, expandWildcardsClosed, defaultOptions));
-    }
-
-    private Map<String, Object> parseToMap(XContentParser parser) throws IOException {
-        Map<String, Object> header = new HashMap<>();
-
-        String currentFieldName = null;
-        XContentParser.Token token;
-        while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
-            if (token == XContentParser.Token.FIELD_NAME) {
-                currentFieldName = parser.currentName();
-            } else if (token.isValue()) {
-                header.put(currentFieldName, parser.text());
-            } else if (token == XContentParser.Token.START_ARRAY) {
-                header.put(currentFieldName, parseArray(parser));
-            }
-        }
-        return header;
-    }
-
-    private String[] parseArray(XContentParser parser) throws IOException {
-        final List<String> list = new ArrayList<>();
-        assert parser.currentToken() == XContentParser.Token.START_ARRAY;
-        while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
-            list.add(parser.text());
-        }
-        return list.toArray(new String[list.size()]);
+        percolateRequest.indicesOptions(IndicesOptions.fromMap(header, indicesOptions));
     }
 
     private int findNextMarker(byte marker, int from, BytesReference data, int length) {

+ 24 - 67
src/main/java/org/elasticsearch/action/search/MultiSearchRequest.java

@@ -40,8 +40,12 @@ import org.elasticsearch.common.xcontent.XContentParser;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import static org.elasticsearch.action.ValidateActions.addValidationError;
+import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue;
+import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeStringArrayValue;
+import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeStringValue;
 
 /**
  * A multi search API request.
@@ -111,82 +115,35 @@ public class MultiSearchRequest extends ActionRequest<MultiSearchRequest> implem
             searchRequest.searchType(searchType);
 
             IndicesOptions defaultOptions = IndicesOptions.strictExpandOpenAndForbidClosed();
-            boolean ignoreUnavailable = defaultOptions.ignoreUnavailable();
-            boolean allowNoIndices = defaultOptions.allowNoIndices();
-            boolean expandWildcardsOpen = defaultOptions.expandWildcardsOpen();
-            boolean expandWildcardsClosed = defaultOptions.expandWildcardsClosed();
+
 
             // now parse the action
             if (nextMarker - from > 0) {
                 try (XContentParser parser = xContent.createParser(data.slice(from, nextMarker - from))) {
-                    // Move to START_OBJECT, if token is null, its an empty data
-                    XContentParser.Token token = parser.nextToken();
-                    if (token != null) {
-                        assert token == XContentParser.Token.START_OBJECT;
-                        String currentFieldName = null;
-                        while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
-                            if (token == XContentParser.Token.FIELD_NAME) {
-                                currentFieldName = parser.currentName();
-                            } else if (token.isValue()) {
-                                if ("index".equals(currentFieldName) || "indices".equals(currentFieldName)) {
-                                    if (!allowExplicitIndex) {
-                                        throw new ElasticsearchIllegalArgumentException("explicit index in multi search is not allowed");
-                                    }
-                                    searchRequest.indices(Strings.splitStringByCommaToArray(parser.text()));
-                                } else if ("type".equals(currentFieldName) || "types".equals(currentFieldName)) {
-                                    searchRequest.types(Strings.splitStringByCommaToArray(parser.text()));
-                                } else if ("search_type".equals(currentFieldName) || "searchType".equals(currentFieldName)) {
-                                    searchRequest.searchType(parser.text());
-                                } else if ("query_cache".equals(currentFieldName) || "queryCache".equals(currentFieldName)) {
-                                    searchRequest.queryCache(parser.booleanValue());
-                                } else if ("preference".equals(currentFieldName)) {
-                                    searchRequest.preference(parser.text());
-                                } else if ("routing".equals(currentFieldName)) {
-                                    searchRequest.routing(parser.text());
-                                } else if ("ignore_unavailable".equals(currentFieldName) || "ignoreUnavailable".equals(currentFieldName)) {
-                                    ignoreUnavailable = parser.booleanValue();
-                                } else if ("allow_no_indices".equals(currentFieldName) || "allowNoIndices".equals(currentFieldName)) {
-                                    allowNoIndices = parser.booleanValue();
-                                } else if ("expand_wildcards".equals(currentFieldName) || "expandWildcards".equals(currentFieldName)) {
-                                    String[] wildcards = Strings.splitStringByCommaToArray(parser.text());
-                                    for (String wildcard : wildcards) {
-                                        if ("open".equals(wildcard)) {
-                                            expandWildcardsOpen = true;
-                                        } else if ("closed".equals(wildcard)) {
-                                            expandWildcardsClosed = true;
-                                        } else {
-                                            throw new ElasticsearchIllegalArgumentException("No valid expand wildcard value [" + wildcard + "]");
-                                        }
-                                    }
-                                }
-                            } else if (token == XContentParser.Token.START_ARRAY) {
-                                if ("index".equals(currentFieldName) || "indices".equals(currentFieldName)) {
-                                    if (!allowExplicitIndex) {
-                                        throw new ElasticsearchIllegalArgumentException("explicit index in multi search is not allowed");
-                                    }
-                                    searchRequest.indices(parseArray(parser));
-                                } else if ("type".equals(currentFieldName) || "types".equals(currentFieldName)) {
-                                    searchRequest.types(parseArray(parser));
-                                } else if ("expand_wildcards".equals(currentFieldName) || "expandWildcards".equals(currentFieldName)) {
-                                    String[] wildcards = parseArray(parser);
-                                    for (String wildcard : wildcards) {
-                                        if ("open".equals(wildcard)) {
-                                            expandWildcardsOpen = true;
-                                        } else if ("closed".equals(wildcard)) {
-                                            expandWildcardsClosed = true;
-                                        } else {
-                                            throw new ElasticsearchIllegalArgumentException("No valid expand wildcard value [" + wildcard + "]");
-                                        }
-                                    }
-                                } else {
-                                    throw new ElasticsearchParseException(currentFieldName + " doesn't support arrays");
-                                }
+                    Map<String, Object> source = parser.map();
+                    for (Map.Entry<String, Object> entry : source.entrySet()) {
+                        Object value = entry.getValue();
+                        if ("index".equals(entry.getKey()) || "indices".equals(entry.getKey())) {
+                            if (!allowExplicitIndex) {
+                                throw new ElasticsearchIllegalArgumentException("explicit index in multi percolate is not allowed");
                             }
+                            searchRequest.indices(nodeStringArrayValue(value));
+                        } else if ("type".equals(entry.getKey()) || "types".equals(entry.getKey())) {
+                            searchRequest.types(nodeStringArrayValue(value));
+                        } else if ("search_type".equals(entry.getKey()) || "searchType".equals(entry.getKey())) {
+                            searchRequest.searchType(nodeStringValue(value, null));
+                        } else if ("query_cache".equals(entry.getKey()) || "queryCache".equals(entry.getKey())) {
+                            searchRequest.queryCache(nodeBooleanValue(value));
+                        } else if ("preference".equals(entry.getKey())) {
+                            searchRequest.preference(nodeStringValue(value, null));
+                        } else if ("routing".equals(entry.getKey())) {
+                            searchRequest.routing(nodeStringValue(value, null));
                         }
                     }
+                    defaultOptions = IndicesOptions.fromMap(source, defaultOptions);
                 }
             }
-            searchRequest.indicesOptions(IndicesOptions.fromOptions(ignoreUnavailable, allowNoIndices, expandWildcardsOpen, expandWildcardsClosed, defaultOptions));
+            searchRequest.indicesOptions(defaultOptions);
 
             // move pointers
             from = nextMarker + 1;

+ 36 - 13
src/main/java/org/elasticsearch/action/support/IndicesOptions.java

@@ -25,6 +25,10 @@ import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.rest.RestRequest;
 
 import java.io.IOException;
+import java.util.Map;
+
+import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue;
+import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeStringArrayValue;
 
 /**
  * Controls how to deal with unavailable concrete indices (closed or missing), how wildcard expressions are expanded
@@ -136,20 +140,33 @@ public class IndicesOptions {
     }
 
     public static IndicesOptions fromRequest(RestRequest request, IndicesOptions defaultSettings) {
-        String sWildcards = request.param("expand_wildcards");
-        String sIgnoreUnavailable = request.param("ignore_unavailable");
-        String sAllowNoIndices = request.param("allow_no_indices");
-        if (sWildcards == null && sIgnoreUnavailable == null && sAllowNoIndices == null) {
+        return fromParameters(
+                request.param("expand_wildcards"),
+                request.param("ignore_unavailable"),
+                request.param("allow_no_indices"),
+                defaultSettings);
+    }
+
+    public static IndicesOptions fromMap(Map<String, Object> map, IndicesOptions defaultSettings) {
+        return fromParameters(
+                map.containsKey("expand_wildcards") ? map.get("expand_wildcards") : map.get("expandWildcards"),
+                map.containsKey("ignore_unavailable") ? map.get("ignore_unavailable") : map.get("ignoreUnavailable"),
+                map.containsKey("allow_no_indices") ? map.get("allow_no_indices") : map.get("allowNoIndices"),
+                defaultSettings);
+    }
+
+    public static IndicesOptions fromParameters(Object wildcardsString, Object ignoreUnavailableString, Object allowNoIndicesString, IndicesOptions defaultSettings) {
+        if (wildcardsString == null && ignoreUnavailableString == null && allowNoIndicesString == null) {
             return defaultSettings;
         }
 
         boolean expandWildcardsOpen = false;
         boolean expandWildcardsClosed = false;
-        if (sWildcards == null) {
+        if (wildcardsString == null) {
             expandWildcardsOpen = defaultSettings.expandWildcardsOpen();
             expandWildcardsClosed = defaultSettings.expandWildcardsClosed();
         } else {
-            String[] wildcards = Strings.splitStringByCommaToArray(sWildcards);
+            String[] wildcards = nodeStringArrayValue(wildcardsString);
             for (String wildcard : wildcards) {
                 if ("open".equals(wildcard)) {
                     expandWildcardsOpen = true;
@@ -169,8 +186,8 @@ public class IndicesOptions {
 
         //note that allowAliasesToMultipleIndices is not exposed, always true (only for internal use)
         return fromOptions(
-                toBool(sIgnoreUnavailable, defaultSettings.ignoreUnavailable()),
-                toBool(sAllowNoIndices, defaultSettings.allowNoIndices()),
+                nodeBooleanValue(ignoreUnavailableString, defaultSettings.ignoreUnavailable()),
+                nodeBooleanValue(allowNoIndicesString, defaultSettings.allowNoIndices()),
                 expandWildcardsOpen,
                 expandWildcardsClosed,
                 defaultSettings.allowAliasesToMultipleIndices(),
@@ -245,10 +262,16 @@ public class IndicesOptions {
         return id;
     }
 
-    private static boolean toBool(String sValue, boolean defaultValue) {
-        if (sValue == null) {
-            return defaultValue;
-        }
-        return !(sValue.equals("false") || sValue.equals("0") || sValue.equals("off"));
+    @Override
+    public String toString() {
+        return "IndicesOptions[" +
+                "id=" + id +
+                ", ignore_unavailable=" + ignoreUnavailable() +
+                ", allow_no_indices=" + allowNoIndices() +
+                ", expand_wildcards_open=" + expandWildcardsOpen() +
+                ", expand_wildcards_closed=" + expandWildcardsClosed() +
+                ", allow_alisases_to_multiple_indices=" + allowAliasesToMultipleIndices() +
+                ", forbid_closed_indices=" + forbidClosedIndices() +
+                ']';
     }
 }

+ 19 - 0
src/main/java/org/elasticsearch/common/xcontent/support/XContentMapValues.java

@@ -387,4 +387,23 @@ public class XContentMapValues {
             throw new ElasticsearchParseException(desc + " should be a hash but was of type: " + node.getClass());
         }
     }
+
+    /**
+     * Returns an array of string value from a node value.
+     *
+     * If the node represents an array the corresponding array of strings is returned.
+     * Otherwise the node is treated as a comma-separated string.
+     */
+    public static String[] nodeStringArrayValue(Object node) {
+        if (isArray(node)) {
+            List list = (List) node;
+            String[] arr = new String[list.size()];
+            for (int i = 0; i < arr.length; i++) {
+                arr[i] = nodeStringValue(list.get(i), null);
+            }
+            return arr;
+        } else {
+            return Strings.splitStringByCommaToArray(node.toString());
+        }
+    }
 }

+ 43 - 11
src/test/java/org/elasticsearch/action/percolate/MultiPercolatorRequestTests.java

@@ -38,7 +38,7 @@ public class MultiPercolatorRequestTests extends ElasticsearchTestCase {
         byte[] data = Streams.copyToBytesFromClasspath("/org/elasticsearch/action/percolate/mpercolate1.json");
         MultiPercolateRequest request = new MultiPercolateRequest().add(data, 0, data.length);
 
-        assertThat(request.requests().size(), equalTo(6));
+        assertThat(request.requests().size(), equalTo(8));
         PercolateRequest percolateRequest = request.requests().get(0);
         assertThat(percolateRequest.indices()[0], equalTo("my-index1"));
         assertThat(percolateRequest.documentType(), equalTo("my-type1"));
@@ -61,8 +61,8 @@ public class MultiPercolatorRequestTests extends ElasticsearchTestCase {
         assertThat(percolateRequest.onlyCount(), equalTo(false));
         assertThat(percolateRequest.getRequest(), nullValue());
         assertThat(percolateRequest.source(), notNullValue());
-        sourceMap =  XContentFactory.xContent(percolateRequest.source()).createParser(percolateRequest.source()).map();
-        assertThat(sourceMap.get("doc"), equalTo((Object)MapBuilder.newMapBuilder().put("field1", "value2").map()));
+        sourceMap = XContentFactory.xContent(percolateRequest.source()).createParser(percolateRequest.source()).map();
+        assertThat(sourceMap.get("doc"), equalTo((Object) MapBuilder.newMapBuilder().put("field1", "value2").map()));
 
         percolateRequest = request.requests().get(2);
         assertThat(percolateRequest.indices()[0], equalTo("my-index4"));
@@ -74,8 +74,8 @@ public class MultiPercolatorRequestTests extends ElasticsearchTestCase {
         assertThat(percolateRequest.onlyCount(), equalTo(true));
         assertThat(percolateRequest.getRequest(), nullValue());
         assertThat(percolateRequest.source(), notNullValue());
-        sourceMap =  XContentFactory.xContent(percolateRequest.source()).createParser(percolateRequest.source()).map();
-        assertThat(sourceMap.get("doc"), equalTo((Object)MapBuilder.newMapBuilder().put("field1", "value3").map()));
+        sourceMap = XContentFactory.xContent(percolateRequest.source()).createParser(percolateRequest.source()).map();
+        assertThat(sourceMap.get("doc"), equalTo((Object) MapBuilder.newMapBuilder().put("field1", "value3").map()));
 
         percolateRequest = request.requests().get(3);
         assertThat(percolateRequest.indices()[0], equalTo("my-index6"));
@@ -114,8 +114,40 @@ public class MultiPercolatorRequestTests extends ElasticsearchTestCase {
         assertThat(percolateRequest.onlyCount(), equalTo(false));
         assertThat(percolateRequest.getRequest(), nullValue());
         assertThat(percolateRequest.source(), notNullValue());
-        sourceMap =  XContentFactory.xContent(percolateRequest.source()).createParser(percolateRequest.source()).map();
-        assertThat(sourceMap.get("doc"), equalTo((Object)MapBuilder.newMapBuilder().put("field1", "value4").map()));
+        sourceMap = XContentFactory.xContent(percolateRequest.source()).createParser(percolateRequest.source()).map();
+        assertThat(sourceMap.get("doc"), equalTo((Object) MapBuilder.newMapBuilder().put("field1", "value4").map()));
+
+        percolateRequest = request.requests().get(6);
+        assertThat(percolateRequest.indices()[0], equalTo("percolate-index1"));
+        assertThat(percolateRequest.documentType(), equalTo("other-type"));
+        assertThat(percolateRequest.routing(), equalTo("percolate-routing-1"));
+        assertThat(percolateRequest.preference(), equalTo("_local"));
+        assertThat(percolateRequest.getRequest(), notNullValue());
+        assertThat(percolateRequest.getRequest().indices()[0], equalTo("my-index9"));
+        assertThat(percolateRequest.getRequest().type(), equalTo("my-type1"));
+        assertThat(percolateRequest.getRequest().routing(), nullValue());
+        assertThat(percolateRequest.getRequest().preference(), nullValue());
+        assertThat(percolateRequest.indicesOptions(), equalTo(IndicesOptions.strictExpandOpenAndForbidClosed()));
+        assertThat(percolateRequest.onlyCount(), equalTo(false));
+        assertThat(percolateRequest.source(), notNullValue());
+        sourceMap = XContentFactory.xContent(percolateRequest.source()).createParser(percolateRequest.source()).map();
+        assertThat(sourceMap.get("doc"), nullValue());
+
+        percolateRequest = request.requests().get(7);
+        assertThat(percolateRequest.indices()[0], equalTo("my-index10"));
+        assertThat(percolateRequest.documentType(), equalTo("my-type1"));
+        assertThat(percolateRequest.routing(), nullValue());
+        assertThat(percolateRequest.preference(), nullValue());
+        assertThat(percolateRequest.getRequest(), notNullValue());
+        assertThat(percolateRequest.getRequest().indices()[0], equalTo("my-index10"));
+        assertThat(percolateRequest.getRequest().type(), equalTo("my-type1"));
+        assertThat(percolateRequest.getRequest().routing(), nullValue());
+        assertThat(percolateRequest.getRequest().preference(), nullValue());
+        assertThat(percolateRequest.indicesOptions(), equalTo(IndicesOptions.fromOptions(false, false, true, false, IndicesOptions.strictExpandOpenAndForbidClosed())));
+        assertThat(percolateRequest.onlyCount(), equalTo(false));
+        assertThat(percolateRequest.source(), notNullValue());
+        sourceMap = XContentFactory.xContent(percolateRequest.source()).createParser(percolateRequest.source()).map();
+        assertThat(sourceMap.get("doc"), nullValue());
     }
 
     @Test
@@ -147,8 +179,8 @@ public class MultiPercolatorRequestTests extends ElasticsearchTestCase {
         assertThat(percolateRequest.onlyCount(), equalTo(false));
         assertThat(percolateRequest.getRequest(), nullValue());
         assertThat(percolateRequest.source(), notNullValue());
-        sourceMap =  XContentFactory.xContent(percolateRequest.source()).createParser(percolateRequest.source()).map();
-        assertThat(sourceMap.get("doc"), equalTo((Object)MapBuilder.newMapBuilder().put("field1", "value2").map()));
+        sourceMap = XContentFactory.xContent(percolateRequest.source()).createParser(percolateRequest.source()).map();
+        assertThat(sourceMap.get("doc"), equalTo((Object) MapBuilder.newMapBuilder().put("field1", "value2").map()));
 
         percolateRequest = request.requests().get(2);
         assertThat(percolateRequest.indices()[0], equalTo("my-index1"));
@@ -157,8 +189,8 @@ public class MultiPercolatorRequestTests extends ElasticsearchTestCase {
         assertThat(percolateRequest.onlyCount(), equalTo(false));
         assertThat(percolateRequest.getRequest(), nullValue());
         assertThat(percolateRequest.source(), notNullValue());
-        sourceMap =  XContentFactory.xContent(percolateRequest.source()).createParser(percolateRequest.source()).map();
-        assertThat(sourceMap.get("doc"), equalTo((Object)MapBuilder.newMapBuilder().put("field1", "value3").map()));
+        sourceMap = XContentFactory.xContent(percolateRequest.source()).createParser(percolateRequest.source()).map();
+        assertThat(sourceMap.get("doc"), equalTo((Object) MapBuilder.newMapBuilder().put("field1", "value3").map()));
     }
 
 }

+ 4 - 0
src/test/java/org/elasticsearch/action/percolate/mpercolate1.json

@@ -10,3 +10,7 @@
 {}
 {"percolate" : {"index" : "my-index8", "type" : "my-type1", "routing" : "my-routing-1", "preference" : "primary"}}
 {"doc" : {"field1" : "value4"}}
+{"percolate" : {"id" : "3", "index" : "my-index9", "type" : "my-type1", "percolate_index": "percolate-index1", "percolate_type": "other-type", "percolate_preference": "_local", "percolate_routing": "percolate-routing-1"}}
+{}
+{"percolate" : {"id" : "4", "index" : "my-index10", "type" : "my-type1", "allow_no_indices": false, "expand_wildcards" : ["open"]}}
+{}

+ 35 - 8
src/test/java/org/elasticsearch/action/search/MultiSearchRequestTests.java

@@ -35,20 +35,26 @@ public class MultiSearchRequestTests extends ElasticsearchTestCase {
     public void simpleAdd() throws Exception {
         byte[] data = Streams.copyToBytesFromClasspath("/org/elasticsearch/action/search/simple-msearch1.json");
         MultiSearchRequest request = new MultiSearchRequest().add(data, 0, data.length, null, null, null);
-        assertThat(request.requests().size(), equalTo(5));
+        assertThat(request.requests().size(), equalTo(8));
         assertThat(request.requests().get(0).indices()[0], equalTo("test"));
         assertThat(request.requests().get(0).indicesOptions(), equalTo(IndicesOptions.fromOptions(true, true, true, true, IndicesOptions.strictExpandOpenAndForbidClosed())));
         assertThat(request.requests().get(0).types().length, equalTo(0));
         assertThat(request.requests().get(1).indices()[0], equalTo("test"));
         assertThat(request.requests().get(1).indicesOptions(), equalTo(IndicesOptions.fromOptions(false, true, true, true, IndicesOptions.strictExpandOpenAndForbidClosed())));
         assertThat(request.requests().get(1).types()[0], equalTo("type1"));
-        assertThat(request.requests().get(2).indices(), nullValue());
-        assertThat(request.requests().get(2).types().length, equalTo(0));
-        assertThat(request.requests().get(3).indices(), nullValue());
-        assertThat(request.requests().get(3).types().length, equalTo(0));
-        assertThat(request.requests().get(3).searchType(), equalTo(SearchType.DFS_QUERY_THEN_FETCH));
-        assertThat(request.requests().get(4).indices(), nullValue());
-        assertThat(request.requests().get(4).types().length, equalTo(0));
+        assertThat(request.requests().get(2).indices()[0], equalTo("test"));
+        assertThat(request.requests().get(2).indicesOptions(), equalTo(IndicesOptions.fromOptions(false, true, true, false, IndicesOptions.strictExpandOpenAndForbidClosed())));
+        assertThat(request.requests().get(3).indices()[0], equalTo("test"));
+        assertThat(request.requests().get(3).indicesOptions(), equalTo(IndicesOptions.fromOptions(true, true, true, true, IndicesOptions.strictExpandOpenAndForbidClosed())));
+        assertThat(request.requests().get(4).indices()[0], equalTo("test"));
+        assertThat(request.requests().get(4).indicesOptions(), equalTo(IndicesOptions.fromOptions(true, false, false, true, IndicesOptions.strictExpandOpenAndForbidClosed())));
+        assertThat(request.requests().get(5).indices(), nullValue());
+        assertThat(request.requests().get(5).types().length, equalTo(0));
+        assertThat(request.requests().get(6).indices(), nullValue());
+        assertThat(request.requests().get(6).types().length, equalTo(0));
+        assertThat(request.requests().get(6).searchType(), equalTo(SearchType.DFS_QUERY_THEN_FETCH));
+        assertThat(request.requests().get(7).indices(), nullValue());
+        assertThat(request.requests().get(7).types().length, equalTo(0));
     }
 
     @Test
@@ -87,4 +93,25 @@ public class MultiSearchRequestTests extends ElasticsearchTestCase {
         assertThat(request.requests().get(3).types().length, equalTo(0));
         assertThat(request.requests().get(3).searchType(), equalTo(SearchType.DFS_QUERY_THEN_FETCH));
     }
+
+    @Test
+    public void simpleAdd4() throws Exception {
+        byte[] data = Streams.copyToBytesFromClasspath("/org/elasticsearch/action/search/simple-msearch4.json");
+        MultiSearchRequest request = new MultiSearchRequest().add(data, 0, data.length, null, null, null);
+        assertThat(request.requests().size(), equalTo(3));
+        assertThat(request.requests().get(0).indices()[0], equalTo("test0"));
+        assertThat(request.requests().get(0).indices()[1], equalTo("test1"));
+        assertThat(request.requests().get(0).queryCache(), equalTo(true));
+        assertThat(request.requests().get(0).preference(), nullValue());
+        assertThat(request.requests().get(1).indices()[0], equalTo("test2"));
+        assertThat(request.requests().get(1).indices()[1], equalTo("test3"));
+        assertThat(request.requests().get(1).types()[0], equalTo("type1"));
+        assertThat(request.requests().get(1).queryCache(), nullValue());
+        assertThat(request.requests().get(1).preference(), equalTo("_local"));
+        assertThat(request.requests().get(2).indices()[0], equalTo("test4"));
+        assertThat(request.requests().get(2).indices()[1], equalTo("test1"));
+        assertThat(request.requests().get(2).types()[0], equalTo("type2"));
+        assertThat(request.requests().get(2).types()[1], equalTo("type1"));
+        assertThat(request.requests().get(2).routing(), equalTo("123"));
+    }
 }

+ 6 - 0
src/test/java/org/elasticsearch/action/search/simple-msearch1.json

@@ -2,6 +2,12 @@
 {"query" : {"match_all" {}}}
 {"index" : "test", "type" : "type1", "expand_wildcards" : ["open", "closed"]}
 {"query" : {"match_all" {}}}
+{"index":"test", "ignore_unavailable" : false, "expand_wildcards" : ["open"]}}
+{"query" : {"match_all" {}}}
+{"index":"test", "ignore_unavailable" : true, "allow_no_indices": true, "expand_wildcards" : ["open", "closed"]}}
+{"query" : {"match_all" {}}}
+{"index":"test", "ignore_unavailable" : true, "allow_no_indices": false, "expand_wildcards" : ["closed"]}}
+{"query" : {"match_all" {}}}
 {}
 {"query" : {"match_all" {}}}
 {"search_type" : "dfs_query_then_fetch"}

+ 6 - 0
src/test/java/org/elasticsearch/action/search/simple-msearch4.json

@@ -0,0 +1,6 @@
+{"index":["test0", "test1"], "query_cache": true}
+{"query" : {"match_all" {}}}
+{"index" : "test2,test3", "type" : "type1", "preference": "_local"}
+{"query" : {"match_all" {}}}
+{"index" : ["test4", "test1"], "type" :  [ "type2", "type1" ], "routing": "123"}
+{"query" : {"match_all" {}}}