Sfoglia il codice sorgente

Validate top-level keys for create index request (#23755) (#23869)

This commit ensures create index requests do not ignore unknown keys passed to the request.

closes #23755
olcbean 8 anni fa
parent
commit
6952f7b560

+ 3 - 9
core/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java

@@ -374,38 +374,32 @@ public class CreateIndexRequest extends AcknowledgedRequest<CreateIndexRequest>
      */
     @SuppressWarnings("unchecked")
     public CreateIndexRequest source(Map<String, ?> source) {
-        boolean found = false;
         for (Map.Entry<String, ?> entry : source.entrySet()) {
             String name = entry.getKey();
             if (name.equals("settings")) {
-                found = true;
                 settings((Map<String, Object>) entry.getValue());
             } else if (name.equals("mappings")) {
-                found = true;
                 Map<String, Object> mappings = (Map<String, Object>) entry.getValue();
                 for (Map.Entry<String, Object> entry1 : mappings.entrySet()) {
                     mapping(entry1.getKey(), (Map<String, Object>) entry1.getValue());
                 }
             } else if (name.equals("aliases")) {
-                found = true;
                 aliases((Map<String, Object>) entry.getValue());
             } else {
                 // maybe custom?
                 IndexMetaData.Custom proto = IndexMetaData.lookupPrototype(name);
                 if (proto != null) {
-                    found = true;
                     try {
                         customs.put(name, proto.fromMap((Map<String, Object>) entry.getValue()));
                     } catch (IOException e) {
                         throw new ElasticsearchParseException("failed to parse custom metadata for [{}]", name);
                     }
+                } else {
+                    // found a key which is neither custom defined nor one of the supported ones
+                    throw new ElasticsearchParseException("unknown key [{}] for create index", name);
                 }
             }
         }
-        if (!found) {
-            // the top level are settings, use them
-            settings(source);
-        }
         return this;
     }
 

+ 12 - 3
core/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestBuilderTests.java

@@ -19,6 +19,7 @@
 
 package org.elasticsearch.action.admin.indices.create;
 
+import org.elasticsearch.ElasticsearchParseException;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
@@ -31,6 +32,7 @@ import org.junit.Before;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.HashMap;
+import java.util.Locale;
 import java.util.Map;
 
 public class CreateIndexRequestBuilderTests extends ESTestCase {
@@ -58,16 +60,23 @@ public class CreateIndexRequestBuilderTests extends ESTestCase {
      */
     public void testSetSource() throws IOException {
         CreateIndexRequestBuilder builder = new CreateIndexRequestBuilder(this.testClient, CreateIndexAction.INSTANCE);
-        builder.setSource("{\""+KEY+"\" : \""+VALUE+"\"}", XContentType.JSON);
+        
+        ElasticsearchParseException e = expectThrows(ElasticsearchParseException.class, 
+                () -> {builder.setSource("{\""+KEY+"\" : \""+VALUE+"\"}", XContentType.JSON);});
+        assertEquals(String.format(Locale.ROOT, "unknown key [%s] for create index", KEY), e.getMessage());
+        
+        builder.setSource("{\"settings\" : {\""+KEY+"\" : \""+VALUE+"\"}}", XContentType.JSON);
         assertEquals(VALUE, builder.request().settings().get(KEY));
 
-        XContentBuilder xContent = XContentFactory.jsonBuilder().startObject().field(KEY, VALUE).endObject();
+        XContentBuilder xContent = XContentFactory.jsonBuilder().startObject()
+                .startObject("settings").field(KEY, VALUE).endObject().endObject();
         xContent.close();
         builder.setSource(xContent);
         assertEquals(VALUE, builder.request().settings().get(KEY));
 
         ByteArrayOutputStream docOut = new ByteArrayOutputStream();
-        XContentBuilder doc = XContentFactory.jsonBuilder(docOut).startObject().field(KEY, VALUE).endObject();
+        XContentBuilder doc = XContentFactory.jsonBuilder(docOut).startObject()
+                .startObject("settings").field(KEY, VALUE).endObject().endObject();
         doc.close();
         builder.setSource(docOut.toByteArray(), XContentType.JSON);
         assertEquals(VALUE, builder.request().settings().get(KEY));

+ 24 - 0
core/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestTests.java

@@ -19,6 +19,7 @@
 
 package org.elasticsearch.action.admin.indices.create;
 
+import org.elasticsearch.ElasticsearchParseException;
 import org.elasticsearch.common.io.stream.BytesStreamOutput;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.xcontent.XContentType;
@@ -45,4 +46,27 @@ public class CreateIndexRequestTests extends ESTestCase {
             }
         }
     }
+    
+    public void testTopLevelKeys() throws IOException {
+        String createIndex =
+                "{\n"
+                + "  \"FOO_SHOULD_BE_ILLEGAL_HERE\": {\n"
+                + "    \"BAR_IS_THE_SAME\": 42\n"
+                + "  },\n"
+                + "  \"mappings\": {\n"
+                + "    \"test\": {\n"
+                + "      \"properties\": {\n"
+                + "        \"field1\": {\n"
+                + "          \"type\": \"text\"\n"
+                + "       }\n"
+                + "     }\n"
+                + "    }\n"
+                + "  }\n"
+                + "}";
+
+        CreateIndexRequest request = new CreateIndexRequest();
+        ElasticsearchParseException e = expectThrows(ElasticsearchParseException.class, 
+                () -> {request.source(createIndex, XContentType.JSON);});
+        assertEquals("unknown key [FOO_SHOULD_BE_ILLEGAL_HERE] for create index", e.getMessage());
+    }
 }

+ 20 - 18
docs/reference/analysis/tokenfilters/compound-word-tokenfilter.asciidoc

@@ -86,25 +86,27 @@ Here is an example:
 --------------------------------------------------
 PUT /compound_word_example
 {
-    "index": {
-        "analysis": {
-            "analyzer": {
-                "my_analyzer": {
-                    "type": "custom",
-                    "tokenizer": "standard",
-                    "filter": ["dictionary_decompounder", "hyphenation_decompounder"]
-                }
-            },
-            "filter": {
-                "dictionary_decompounder": {
-                    "type": "dictionary_decompounder",
-                    "word_list": ["one", "two", "three"]
+    "settings": {
+        "index": {
+            "analysis": {
+                "analyzer": {
+                    "my_analyzer": {
+                        "type": "custom",
+                        "tokenizer": "standard",
+                        "filter": ["dictionary_decompounder", "hyphenation_decompounder"]
+                    }
                 },
-                "hyphenation_decompounder": {
-                    "type" : "hyphenation_decompounder",
-                    "word_list_path": "analysis/example_word_list.txt",
-                    "hyphenation_patterns_path": "analysis/hyphenation_patterns.xml",
-                    "max_subword_size": 22
+                "filter": {
+                    "dictionary_decompounder": {
+                        "type": "dictionary_decompounder",
+                        "word_list": ["one", "two", "three"]
+                    },
+                    "hyphenation_decompounder": {
+                        "type" : "hyphenation_decompounder",
+                        "word_list_path": "analysis/example_word_list.txt",
+                        "hyphenation_patterns_path": "analysis/hyphenation_patterns.xml",
+                        "max_subword_size": 22
+                    }
                 }
             }
         }

+ 3 - 2
plugins/store-smb/src/test/resources/rest-api-spec/test/store_smb/15_index_creation.yml

@@ -3,8 +3,9 @@
       indices.create:
         index: smb-test
         body:
-          index:
-            store.type: smb_mmap_fs
+          settings:
+            index:
+              store.type: smb_mmap_fs
 
   - do:
       index:

+ 1 - 1
rest-api-spec/src/main/resources/rest-api-spec/test/cluster.allocation_explain/10_basic.yml

@@ -47,7 +47,7 @@
   - do:
       indices.create:
         index: test
-        body: { "index.number_of_shards": 1, "index.number_of_replicas": 9 }
+        body: { "settings": { "index.number_of_shards": 1, "index.number_of_replicas": 9 } }
 
   - do:
       cluster.state: