This commit ensures create index requests do not ignore unknown keys passed to the request. closes #23755
This commit is contained in:
parent
5df77a8c91
commit
6952f7b560
|
@ -374,38 +374,32 @@ public class CreateIndexRequest extends AcknowledgedRequest<CreateIndexRequest>
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public CreateIndexRequest source(Map<String, ?> source) {
|
public CreateIndexRequest source(Map<String, ?> source) {
|
||||||
boolean found = false;
|
|
||||||
for (Map.Entry<String, ?> entry : source.entrySet()) {
|
for (Map.Entry<String, ?> entry : source.entrySet()) {
|
||||||
String name = entry.getKey();
|
String name = entry.getKey();
|
||||||
if (name.equals("settings")) {
|
if (name.equals("settings")) {
|
||||||
found = true;
|
|
||||||
settings((Map<String, Object>) entry.getValue());
|
settings((Map<String, Object>) entry.getValue());
|
||||||
} else if (name.equals("mappings")) {
|
} else if (name.equals("mappings")) {
|
||||||
found = true;
|
|
||||||
Map<String, Object> mappings = (Map<String, Object>) entry.getValue();
|
Map<String, Object> mappings = (Map<String, Object>) entry.getValue();
|
||||||
for (Map.Entry<String, Object> entry1 : mappings.entrySet()) {
|
for (Map.Entry<String, Object> entry1 : mappings.entrySet()) {
|
||||||
mapping(entry1.getKey(), (Map<String, Object>) entry1.getValue());
|
mapping(entry1.getKey(), (Map<String, Object>) entry1.getValue());
|
||||||
}
|
}
|
||||||
} else if (name.equals("aliases")) {
|
} else if (name.equals("aliases")) {
|
||||||
found = true;
|
|
||||||
aliases((Map<String, Object>) entry.getValue());
|
aliases((Map<String, Object>) entry.getValue());
|
||||||
} else {
|
} else {
|
||||||
// maybe custom?
|
// maybe custom?
|
||||||
IndexMetaData.Custom proto = IndexMetaData.lookupPrototype(name);
|
IndexMetaData.Custom proto = IndexMetaData.lookupPrototype(name);
|
||||||
if (proto != null) {
|
if (proto != null) {
|
||||||
found = true;
|
|
||||||
try {
|
try {
|
||||||
customs.put(name, proto.fromMap((Map<String, Object>) entry.getValue()));
|
customs.put(name, proto.fromMap((Map<String, Object>) entry.getValue()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ElasticsearchParseException("failed to parse custom metadata for [{}]", name);
|
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.action.admin.indices.create;
|
package org.elasticsearch.action.admin.indices.create;
|
||||||
|
|
||||||
|
import org.elasticsearch.ElasticsearchParseException;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
|
@ -31,6 +32,7 @@ import org.junit.Before;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class CreateIndexRequestBuilderTests extends ESTestCase {
|
public class CreateIndexRequestBuilderTests extends ESTestCase {
|
||||||
|
@ -58,16 +60,23 @@ public class CreateIndexRequestBuilderTests extends ESTestCase {
|
||||||
*/
|
*/
|
||||||
public void testSetSource() throws IOException {
|
public void testSetSource() throws IOException {
|
||||||
CreateIndexRequestBuilder builder = new CreateIndexRequestBuilder(this.testClient, CreateIndexAction.INSTANCE);
|
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));
|
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();
|
xContent.close();
|
||||||
builder.setSource(xContent);
|
builder.setSource(xContent);
|
||||||
assertEquals(VALUE, builder.request().settings().get(KEY));
|
assertEquals(VALUE, builder.request().settings().get(KEY));
|
||||||
|
|
||||||
ByteArrayOutputStream docOut = new ByteArrayOutputStream();
|
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();
|
doc.close();
|
||||||
builder.setSource(docOut.toByteArray(), XContentType.JSON);
|
builder.setSource(docOut.toByteArray(), XContentType.JSON);
|
||||||
assertEquals(VALUE, builder.request().settings().get(KEY));
|
assertEquals(VALUE, builder.request().settings().get(KEY));
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.action.admin.indices.create;
|
package org.elasticsearch.action.admin.indices.create;
|
||||||
|
|
||||||
|
import org.elasticsearch.ElasticsearchParseException;
|
||||||
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.xcontent.XContentType;
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,25 +86,27 @@ Here is an example:
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
PUT /compound_word_example
|
PUT /compound_word_example
|
||||||
{
|
{
|
||||||
"index": {
|
"settings": {
|
||||||
"analysis": {
|
"index": {
|
||||||
"analyzer": {
|
"analysis": {
|
||||||
"my_analyzer": {
|
"analyzer": {
|
||||||
"type": "custom",
|
"my_analyzer": {
|
||||||
"tokenizer": "standard",
|
"type": "custom",
|
||||||
"filter": ["dictionary_decompounder", "hyphenation_decompounder"]
|
"tokenizer": "standard",
|
||||||
}
|
"filter": ["dictionary_decompounder", "hyphenation_decompounder"]
|
||||||
},
|
}
|
||||||
"filter": {
|
|
||||||
"dictionary_decompounder": {
|
|
||||||
"type": "dictionary_decompounder",
|
|
||||||
"word_list": ["one", "two", "three"]
|
|
||||||
},
|
},
|
||||||
"hyphenation_decompounder": {
|
"filter": {
|
||||||
"type" : "hyphenation_decompounder",
|
"dictionary_decompounder": {
|
||||||
"word_list_path": "analysis/example_word_list.txt",
|
"type": "dictionary_decompounder",
|
||||||
"hyphenation_patterns_path": "analysis/hyphenation_patterns.xml",
|
"word_list": ["one", "two", "three"]
|
||||||
"max_subword_size": 22
|
},
|
||||||
|
"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,8 +3,9 @@
|
||||||
indices.create:
|
indices.create:
|
||||||
index: smb-test
|
index: smb-test
|
||||||
body:
|
body:
|
||||||
index:
|
settings:
|
||||||
store.type: smb_mmap_fs
|
index:
|
||||||
|
store.type: smb_mmap_fs
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
index:
|
index:
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
- do:
|
- do:
|
||||||
indices.create:
|
indices.create:
|
||||||
index: test
|
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:
|
- do:
|
||||||
cluster.state:
|
cluster.state:
|
||||||
|
|
Loading…
Reference in New Issue