mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-22 12:56:53 +00:00
Check it out: ``` $ curl -u elastic:password -HContent-Type:application/json -XPOST localhost:9200/test/_update/foo?pretty -d'{ "dac": {} }' { "error" : { "root_cause" : [ { "type" : "x_content_parse_exception", "reason" : "[2:3] [UpdateRequest] unknown field [dac] did you mean [doc]?" } ], "type" : "x_content_parse_exception", "reason" : "[2:3] [UpdateRequest] unknown field [dac] did you mean [doc]?" }, "status" : 400 } ``` The tricky thing about implementing this is that x-content doesn't depend on Lucene. So this works by creating an extension point for the error message using SPI. Elasticsearch's server module provides the "spell checking" implementation. s
This commit is contained in:
parent
4bdab0e985
commit
fc5fde7950
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.common.xcontent;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* Extension point to customize the error message for unknown fields. We expect
|
||||
* Elasticsearch to plug a fancy implementation that uses Lucene's spelling
|
||||
* correction infrastructure to suggest corrections.
|
||||
*/
|
||||
public interface ErrorOnUnknown {
|
||||
/**
|
||||
* The implementation of this interface that was loaded from SPI.
|
||||
*/
|
||||
ErrorOnUnknown IMPLEMENTATION = findImplementation();
|
||||
|
||||
/**
|
||||
* Build the error message to use when {@link ObjectParser} encounters an unknown field.
|
||||
* @param parserName the name of the thing we're parsing
|
||||
* @param unknownField the field that we couldn't recognize
|
||||
* @param candidates the possible fields
|
||||
*/
|
||||
String errorMessage(String parserName, String unknownField, Iterable<String> candidates);
|
||||
|
||||
/**
|
||||
* Priority that this error message handler should be used.
|
||||
*/
|
||||
int priority();
|
||||
|
||||
static ErrorOnUnknown findImplementation() {
|
||||
ErrorOnUnknown best = new ErrorOnUnknown() {
|
||||
@Override
|
||||
public String errorMessage(String parserName, String unknownField, Iterable<String> candidates) {
|
||||
return "[" + parserName + "] unknown field [" + unknownField + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
};
|
||||
for (ErrorOnUnknown c : ServiceLoader.load(ErrorOnUnknown.class)) {
|
||||
if (best.priority() < c.priority()) {
|
||||
best = c;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
}
|
@ -81,18 +81,17 @@ public final class ObjectParser<Value, Context> extends AbstractObjectParser<Val
|
||||
}
|
||||
|
||||
private interface UnknownFieldParser<Value, Context> {
|
||||
|
||||
void acceptUnknownField(String parserName, String field, XContentLocation location, XContentParser parser,
|
||||
Value value, Context context) throws IOException;
|
||||
void acceptUnknownField(ObjectParser<Value, Context> objectParser, String field, XContentLocation location, XContentParser parser,
|
||||
Value value, Context context) throws IOException;
|
||||
}
|
||||
|
||||
private static <Value, Context> UnknownFieldParser<Value, Context> ignoreUnknown() {
|
||||
return (n, f, l, p, v, c) -> p.skipChildren();
|
||||
return (op, f, l, p, v, c) -> p.skipChildren();
|
||||
}
|
||||
|
||||
private static <Value, Context> UnknownFieldParser<Value, Context> errorOnUnknown() {
|
||||
return (n, f, l, p, v, c) -> {
|
||||
throw new XContentParseException(l, "[" + n + "] unknown field [" + f + "], parser not found");
|
||||
return (op, f, l, p, v, c) -> {
|
||||
throw new XContentParseException(l, ErrorOnUnknown.IMPLEMENTATION.errorMessage(op.name, f, op.fieldParserMap.keySet()));
|
||||
};
|
||||
}
|
||||
|
||||
@ -104,7 +103,7 @@ public final class ObjectParser<Value, Context> extends AbstractObjectParser<Val
|
||||
}
|
||||
|
||||
private static <Value, Context> UnknownFieldParser<Value, Context> consumeUnknownField(UnknownFieldConsumer<Value> consumer) {
|
||||
return (parserName, field, location, parser, value, context) -> {
|
||||
return (objectParser, field, location, parser, value, context) -> {
|
||||
XContentParser.Token t = parser.currentToken();
|
||||
switch (t) {
|
||||
case VALUE_STRING:
|
||||
@ -127,7 +126,7 @@ public final class ObjectParser<Value, Context> extends AbstractObjectParser<Val
|
||||
break;
|
||||
default:
|
||||
throw new XContentParseException(parser.getTokenLocation(),
|
||||
"[" + parserName + "] cannot parse field [" + field + "] with value type [" + t + "]");
|
||||
"[" + objectParser.name + "] cannot parse field [" + field + "] with value type [" + t + "]");
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -136,12 +135,13 @@ public final class ObjectParser<Value, Context> extends AbstractObjectParser<Val
|
||||
Class<Category> categoryClass,
|
||||
BiConsumer<Value, ? super Category> consumer
|
||||
) {
|
||||
return (parserName, field, location, parser, value, context) -> {
|
||||
return (objectParser, field, location, parser, value, context) -> {
|
||||
Category o;
|
||||
try {
|
||||
o = parser.namedObject(categoryClass, field, context);
|
||||
} catch (NamedObjectNotFoundException e) {
|
||||
throw new XContentParseException(location, "[" + parserName + "] " + e.getBareMessage(), e);
|
||||
// TODO It'd be lovely if we could the options here but we don't have the right stuff plumbed through. We'll get to it!
|
||||
throw new XContentParseException(location, "[" + objectParser.name + "] " + e.getBareMessage(), e);
|
||||
}
|
||||
consumer.accept(value, o);
|
||||
};
|
||||
@ -278,7 +278,7 @@ public final class ObjectParser<Value, Context> extends AbstractObjectParser<Val
|
||||
throw new XContentParseException(parser.getTokenLocation(), "[" + name + "] no field found");
|
||||
}
|
||||
if (fieldParser == null) {
|
||||
unknownFieldParser.acceptUnknownField(name, currentFieldName, currentPosition, parser, value, context);
|
||||
unknownFieldParser.acceptUnknownField(this, currentFieldName, currentPosition, parser, value, context);
|
||||
} else {
|
||||
fieldParser.assertSupports(name, parser, currentFieldName);
|
||||
parseSub(parser, fieldParser, currentFieldName, value, context);
|
||||
|
@ -207,7 +207,7 @@ public class ObjectParserTests extends ESTestCase {
|
||||
{
|
||||
XContentParser parser = createParser(JsonXContent.jsonXContent, "{\"not_supported_field\" : \"foo\"}");
|
||||
XContentParseException ex = expectThrows(XContentParseException.class, () -> objectParser.parse(parser, s, null));
|
||||
assertEquals(ex.getMessage(), "[1:2] [the_parser] unknown field [not_supported_field], parser not found");
|
||||
assertEquals(ex.getMessage(), "[1:2] [the_parser] unknown field [not_supported_field]");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,6 @@ public class RatedRequestsTests extends ESTestCase {
|
||||
exception = exception.getCause();
|
||||
}
|
||||
assertThat(exception.getMessage(), containsString("unknown field"));
|
||||
assertThat(exception.getMessage(), containsString("parser not found"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
---
|
||||
'Misspelled fields get "did you mean"':
|
||||
- skip:
|
||||
version: " - 7.5.99"
|
||||
reason: Implemented in 7.6
|
||||
- do:
|
||||
catch: /\[UpdateRequest\] unknown field \[dac\] did you mean \[doc\]\?/
|
||||
update:
|
||||
index: test
|
||||
id: 1
|
||||
body:
|
||||
dac: { foo: baz }
|
||||
upsert: { foo: bar }
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.common.xcontent;
|
||||
|
||||
import org.apache.lucene.search.spell.LevenshteinDistance;
|
||||
import org.apache.lucene.util.CollectionUtil;
|
||||
import org.elasticsearch.common.collect.Tuple;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
public class SuggestingErrorOnUnknown implements ErrorOnUnknown {
|
||||
@Override
|
||||
public String errorMessage(String parserName, String unknownField, Iterable<String> candidates) {
|
||||
String message = String.format(Locale.ROOT, "[%s] unknown field [%s]", parserName, unknownField);
|
||||
// TODO it'd be nice to combine this with BaseRestHandler's implementation.
|
||||
LevenshteinDistance ld = new LevenshteinDistance();
|
||||
final List<Tuple<Float, String>> scored = new ArrayList<>();
|
||||
for (String candidate : candidates) {
|
||||
float distance = ld.getDistance(unknownField, candidate);
|
||||
if (distance > 0.5f) {
|
||||
scored.add(new Tuple<>(distance, candidate));
|
||||
}
|
||||
}
|
||||
if (scored.isEmpty()) {
|
||||
return message;
|
||||
}
|
||||
CollectionUtil.timSort(scored, (a, b) -> {
|
||||
// sort by distance in reverse order, then parameter name for equal distances
|
||||
int compare = a.v1().compareTo(b.v1());
|
||||
if (compare != 0) {
|
||||
return -compare;
|
||||
}
|
||||
return a.v2().compareTo(b.v2());
|
||||
});
|
||||
List<String> keys = scored.stream().map(Tuple::v2).collect(toList());
|
||||
StringBuilder builder = new StringBuilder(message).append(" did you mean ");
|
||||
if (keys.size() == 1) {
|
||||
builder.append("[").append(keys.get(0)).append("]");
|
||||
} else {
|
||||
builder.append("any of ").append(keys.toString());
|
||||
}
|
||||
builder.append("?");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
org.elasticsearch.common.xcontent.SuggestingErrorOnUnknown
|
@ -56,7 +56,7 @@ public class ClusterUpdateSettingsRequestTests extends ESTestCase {
|
||||
XContentParseException iae = expectThrows(XContentParseException.class,
|
||||
() -> ClusterUpdateSettingsRequest.fromXContent(createParser(xContentType.xContent(), mutated)));
|
||||
assertThat(iae.getMessage(),
|
||||
containsString("[cluster_update_settings_request] unknown field [" + unsupportedField + "], parser not found"));
|
||||
containsString("[cluster_update_settings_request] unknown field [" + unsupportedField + "]"));
|
||||
} else {
|
||||
try (XContentParser parser = createParser(xContentType.xContent(), originalBytes)) {
|
||||
ClusterUpdateSettingsRequest parsedRequest = ClusterUpdateSettingsRequest.fromXContent(parser);
|
||||
|
@ -288,7 +288,7 @@ public class UpdateRequestTests extends ESTestCase {
|
||||
.endObject());
|
||||
|
||||
XContentParseException ex = expectThrows(XContentParseException.class, () -> request.fromXContent(contentParser));
|
||||
assertEquals("[1:2] [UpdateRequest] unknown field [unknown_field], parser not found", ex.getMessage());
|
||||
assertEquals("[1:2] [UpdateRequest] unknown field [unknown_field]", ex.getMessage());
|
||||
|
||||
UpdateRequest request2 = new UpdateRequest("test", "type", "1");
|
||||
XContentParser unknownObject = createParser(XContentFactory.jsonBuilder()
|
||||
@ -299,7 +299,7 @@ public class UpdateRequestTests extends ESTestCase {
|
||||
.endObject()
|
||||
.endObject());
|
||||
ex = expectThrows(XContentParseException.class, () -> request2.fromXContent(unknownObject));
|
||||
assertEquals("[1:76] [UpdateRequest] unknown field [params], parser not found", ex.getMessage());
|
||||
assertEquals("[1:76] [UpdateRequest] unknown field [params]", ex.getMessage());
|
||||
}
|
||||
|
||||
public void testFetchSourceParsing() throws Exception {
|
||||
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.common.xcontent;
|
||||
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
public class SuggestingErrorOnUnknownTests extends ESTestCase {
|
||||
private String errorMessage(String unknownField, String... candidates) {
|
||||
return new SuggestingErrorOnUnknown().errorMessage("test", unknownField, Arrays.asList(candidates));
|
||||
}
|
||||
|
||||
public void testNoCandidates() {
|
||||
assertThat(errorMessage("foo"), equalTo("[test] unknown field [foo]"));
|
||||
}
|
||||
public void testBadCandidates() {
|
||||
assertThat(errorMessage("foo", "bar", "baz"), equalTo("[test] unknown field [foo]"));
|
||||
}
|
||||
public void testOneCandidate() {
|
||||
assertThat(errorMessage("foo", "bar", "fop"), equalTo("[test] unknown field [foo] did you mean [fop]?"));
|
||||
}
|
||||
public void testManyCandidate() {
|
||||
assertThat(errorMessage("foo", "bar", "fop", "fou", "baz"),
|
||||
equalTo("[test] unknown field [foo] did you mean any of [fop, fou]?"));
|
||||
}
|
||||
}
|
@ -163,7 +163,7 @@ public class HighlightBuilderTests extends ESTestCase {
|
||||
XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" +
|
||||
" \"bad_fieldname\" : [ \"field1\" 1 \"field2\" ]\n" +
|
||||
"}\n");
|
||||
assertEquals("[2:5] [highlight] unknown field [bad_fieldname], parser not found", e.getMessage());
|
||||
assertEquals("[2:5] [highlight] unknown field [bad_fieldname]", e.getMessage());
|
||||
}
|
||||
|
||||
{
|
||||
@ -176,7 +176,7 @@ public class HighlightBuilderTests extends ESTestCase {
|
||||
"}\n");
|
||||
assertThat(e.getMessage(), containsString("[highlight] failed to parse field [fields]"));
|
||||
assertThat(e.getCause().getMessage(), containsString("[fields] failed to parse field [body]"));
|
||||
assertEquals("[4:9] [highlight_field] unknown field [bad_fieldname], parser not found", e.getCause().getCause().getMessage());
|
||||
assertEquals("[4:9] [highlight_field] unknown field [bad_fieldname]", e.getCause().getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ public class HighlightBuilderTests extends ESTestCase {
|
||||
XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" +
|
||||
" \"bad_fieldname\" : \"value\"\n" +
|
||||
"}\n");
|
||||
assertEquals("[2:5] [highlight] unknown field [bad_fieldname], parser not found", e.getMessage());
|
||||
assertEquals("[2:5] [highlight] unknown field [bad_fieldname]", e.getMessage());
|
||||
}
|
||||
|
||||
{
|
||||
@ -207,7 +207,7 @@ public class HighlightBuilderTests extends ESTestCase {
|
||||
"}\n");
|
||||
assertThat(e.getMessage(), containsString("[highlight] failed to parse field [fields]"));
|
||||
assertThat(e.getCause().getMessage(), containsString("[fields] failed to parse field [body]"));
|
||||
assertEquals("[4:9] [highlight_field] unknown field [bad_fieldname], parser not found", e.getCause().getCause().getMessage());
|
||||
assertEquals("[4:9] [highlight_field] unknown field [bad_fieldname]", e.getCause().getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,7 +219,7 @@ public class HighlightBuilderTests extends ESTestCase {
|
||||
XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" +
|
||||
" \"bad_fieldname\" : { \"field\" : \"value\" }\n \n" +
|
||||
"}\n");
|
||||
assertEquals("[2:5] [highlight] unknown field [bad_fieldname], parser not found", e.getMessage());
|
||||
assertEquals("[2:5] [highlight] unknown field [bad_fieldname]", e.getMessage());
|
||||
}
|
||||
|
||||
{
|
||||
@ -232,7 +232,7 @@ public class HighlightBuilderTests extends ESTestCase {
|
||||
"}\n");
|
||||
assertThat(e.getMessage(), containsString("[highlight] failed to parse field [fields]"));
|
||||
assertThat(e.getCause().getMessage(), containsString("[fields] failed to parse field [body]"));
|
||||
assertEquals("[4:9] [highlight_field] unknown field [bad_fieldname], parser not found", e.getCause().getCause().getMessage());
|
||||
assertEquals("[4:9] [highlight_field] unknown field [bad_fieldname]", e.getCause().getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ public class QueryRescorerBuilderTests extends ESTestCase {
|
||||
"}\n";
|
||||
try (XContentParser parser = createParser(rescoreElement)) {
|
||||
XContentParseException e = expectThrows(XContentParseException.class, () -> RescorerBuilder.parseFromXContent(parser));
|
||||
assertEquals("[3:17] [query] unknown field [bad_fieldname], parser not found", e.getMessage());
|
||||
assertEquals("[3:17] [query] unknown field [bad_fieldname]", e.getMessage());
|
||||
}
|
||||
|
||||
rescoreElement = "{\n" +
|
||||
|
@ -339,7 +339,7 @@ public class FieldSortBuilderTests extends AbstractSortTestCase<FieldSortBuilder
|
||||
parser.nextToken();
|
||||
|
||||
XContentParseException e = expectThrows(XContentParseException.class, () -> FieldSortBuilder.fromXContent(parser, ""));
|
||||
assertEquals("[1:18] [field_sort] unknown field [reverse], parser not found", e.getMessage());
|
||||
assertEquals("[1:18] [field_sort] unknown field [reverse]", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,7 +228,7 @@ public class ScriptSortBuilderTests extends AbstractSortTestCase<ScriptSortBuild
|
||||
parser.nextToken();
|
||||
|
||||
XContentParseException e = expectThrows(XContentParseException.class, () -> ScriptSortBuilder.fromXContent(parser, null));
|
||||
assertEquals("[1:15] [_script] unknown field [bad_field], parser not found", e.getMessage());
|
||||
assertEquals("[1:15] [_script] unknown field [bad_field]", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,7 +241,7 @@ public class ScriptSortBuilderTests extends AbstractSortTestCase<ScriptSortBuild
|
||||
parser.nextToken();
|
||||
|
||||
XContentParseException e = expectThrows(XContentParseException.class, () -> ScriptSortBuilder.fromXContent(parser, null));
|
||||
assertEquals("[1:15] [_script] unknown field [bad_field], parser not found", e.getMessage());
|
||||
assertEquals("[1:15] [_script] unknown field [bad_field]", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ public class DirectCandidateGeneratorTests extends ESTestCase {
|
||||
// test unknown field
|
||||
directGenerator = "{ \"unknown_param\" : \"f1\" }";
|
||||
assertIllegalXContent(directGenerator, IllegalArgumentException.class,
|
||||
"[direct_generator] unknown field [unknown_param], parser not found");
|
||||
"[direct_generator] unknown field [unknown_param]");
|
||||
|
||||
// test bad value for field (e.g. size expects an int)
|
||||
directGenerator = "{ \"size\" : \"xxl\" }";
|
||||
|
@ -189,7 +189,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
|
||||
if (expectedException == false) {
|
||||
throw new AssertionError("unexpected exception when parsing query:\n" + testQuery, e);
|
||||
}
|
||||
assertThat(e.getMessage(), containsString("unknown field [newField], parser not found"));
|
||||
assertThat(e.getMessage(), containsString("unknown field [newField]"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ public class DatafeedConfigTests extends AbstractSerializingTestCase<DatafeedCon
|
||||
.createParser(xContentRegistry(), DeprecationHandler.THROW_UNSUPPORTED_OPERATION, FUTURE_DATAFEED);
|
||||
XContentParseException e = expectThrows(XContentParseException.class,
|
||||
() -> DatafeedConfig.STRICT_PARSER.apply(parser, null).build());
|
||||
assertEquals("[6:5] [datafeed_config] unknown field [tomorrows_technology_today], parser not found", e.getMessage());
|
||||
assertEquals("[6:5] [datafeed_config] unknown field [tomorrows_technology_today]", e.getMessage());
|
||||
}
|
||||
|
||||
public void testPastQueryConfigParse() throws IOException {
|
||||
|
@ -328,7 +328,7 @@ public class DataFrameAnalyticsConfigTests extends AbstractSerializingTestCase<D
|
||||
XContentFactory.xContent(XContentType.JSON).createParser(
|
||||
xContentRegistry(), DeprecationHandler.THROW_UNSUPPORTED_OPERATION, json)) {
|
||||
Exception e = expectThrows(IllegalArgumentException.class, () -> DataFrameAnalyticsConfig.STRICT_PARSER.apply(parser, null));
|
||||
assertThat(e.getMessage(), containsString("unknown field [create_time], parser not found"));
|
||||
assertThat(e.getMessage(), containsString("unknown field [create_time]"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -343,7 +343,7 @@ public class DataFrameAnalyticsConfigTests extends AbstractSerializingTestCase<D
|
||||
XContentFactory.xContent(XContentType.JSON).createParser(
|
||||
xContentRegistry(), DeprecationHandler.THROW_UNSUPPORTED_OPERATION, json)) {
|
||||
Exception e = expectThrows(IllegalArgumentException.class, () -> DataFrameAnalyticsConfig.STRICT_PARSER.apply(parser, null));
|
||||
assertThat(e.getMessage(), containsString("unknown field [version], parser not found"));
|
||||
assertThat(e.getMessage(), containsString("unknown field [version]"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ public class JobTests extends AbstractSerializingTestCase<Job> {
|
||||
.createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, FUTURE_JOB);
|
||||
XContentParseException e = expectThrows(XContentParseException.class,
|
||||
() -> Job.STRICT_PARSER.apply(parser, null).build());
|
||||
assertEquals("[4:5] [job_details] unknown field [tomorrows_technology_today], parser not found", e.getMessage());
|
||||
assertEquals("[4:5] [job_details] unknown field [tomorrows_technology_today]", e.getMessage());
|
||||
}
|
||||
|
||||
public void testFutureMetadataParse() throws IOException {
|
||||
|
@ -41,7 +41,7 @@ public class ProcessResultsParserTests extends ESTestCase {
|
||||
XContentParseException e = expectThrows(XContentParseException.class,
|
||||
() -> parser.parseResults(inputStream).forEachRemaining(a -> {
|
||||
}));
|
||||
assertEquals("[1:3] [test_result] unknown field [unknown], parser not found", e.getMessage());
|
||||
assertEquals("[1:3] [test_result] unknown field [unknown]", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -350,7 +350,7 @@ public abstract class RestSqlTestCase extends BaseRestSqlTestCase implements Err
|
||||
expectBadRequest(() -> {
|
||||
client().performRequest(request);
|
||||
return Collections.emptyMap();
|
||||
}, containsString("unknown field [columnar], parser not found"));
|
||||
}, containsString("unknown field [columnar]"));
|
||||
}
|
||||
|
||||
public static void expectBadRequest(CheckedSupplier<Map<String, Object>, Exception> code, Matcher<String> errorMessageMatcher) {
|
||||
|
@ -87,7 +87,7 @@ setup:
|
||||
---
|
||||
"Test put config with security headers in the body":
|
||||
- do:
|
||||
catch: /unknown field \[headers\], parser not found/
|
||||
catch: /unknown field \[headers\]/
|
||||
ml.put_data_frame_analytics:
|
||||
id: "data_frame_with_header"
|
||||
body: >
|
||||
@ -107,7 +107,7 @@ setup:
|
||||
"Test put config with create_time in the body":
|
||||
|
||||
- do:
|
||||
catch: /unknown field \[create_time\], parser not found/
|
||||
catch: /unknown field \[create_time\]/
|
||||
ml.put_data_frame_analytics:
|
||||
id: "data_frame_with_create_time"
|
||||
body: >
|
||||
@ -126,7 +126,7 @@ setup:
|
||||
"Test put config with version in the body":
|
||||
|
||||
- do:
|
||||
catch: /unknown field \[version\], parser not found/
|
||||
catch: /unknown field \[version\]/
|
||||
ml.put_data_frame_analytics:
|
||||
id: "data_frame_with_version"
|
||||
body: >
|
||||
@ -443,7 +443,7 @@ setup:
|
||||
"Test put config with unknown top level field":
|
||||
|
||||
- do:
|
||||
catch: /unknown field \[unknown_field\], parser not found/
|
||||
catch: /unknown field \[unknown_field\]/
|
||||
ml.put_data_frame_analytics:
|
||||
id: "unknown_field"
|
||||
body: >
|
||||
|
@ -86,7 +86,7 @@ setup:
|
||||
---
|
||||
"Test put datafeed with security headers in the body":
|
||||
- do:
|
||||
catch: /unknown field \[headers\], parser not found/
|
||||
catch: /unknown field \[headers\]/
|
||||
ml.put_datafeed:
|
||||
datafeed_id: test-datafeed-1
|
||||
body: >
|
||||
|
@ -171,7 +171,7 @@ setup:
|
||||
"Try to include headers":
|
||||
|
||||
- do:
|
||||
catch: /unknown field \[headers\], parser not found/
|
||||
catch: /unknown field \[headers\]/
|
||||
headers:
|
||||
Authorization: "Basic eF9wYWNrX3Jlc3RfdXNlcjp4LXBhY2stdGVzdC1wYXNzd29yZA==" # run as x_pack_rest_user, i.e. the test setup superuser
|
||||
rollup.put_job:
|
||||
|
@ -196,7 +196,7 @@ public class TextTemplateTests extends ESTestCase {
|
||||
TextTemplate.parse(parser);
|
||||
fail("expected parse exception when encountering an unknown field");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage(), containsString("[script] unknown field [unknown_field], parser not found"));
|
||||
assertThat(e.getMessage(), containsString("[script] unknown field [unknown_field]"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,7 +210,7 @@ public class TextTemplateTests extends ESTestCase {
|
||||
XContentParser parser = createParser(JsonXContent.jsonXContent, bytes);
|
||||
parser.nextToken();
|
||||
XContentParseException ex = expectThrows(XContentParseException.class, () -> TextTemplate.parse(parser));
|
||||
assertEquals("[1:2] [script] unknown field [template], parser not found", ex.getMessage());
|
||||
assertEquals("[1:2] [script] unknown field [template]", ex.getMessage());
|
||||
}
|
||||
|
||||
public void testParserInvalidMissingText() throws Exception {
|
||||
@ -222,7 +222,7 @@ public class TextTemplateTests extends ESTestCase {
|
||||
XContentParser parser = createParser(JsonXContent.jsonXContent, bytes);
|
||||
parser.nextToken();
|
||||
XContentParseException ex = expectThrows(XContentParseException.class, () -> TextTemplate.parse(parser));
|
||||
assertEquals("[1:2] [script] unknown field [type], parser not found", ex.getMessage());
|
||||
assertEquals("[1:2] [script] unknown field [type]", ex.getMessage());
|
||||
}
|
||||
|
||||
public void testNullObject() throws Exception {
|
||||
|
Loading…
x
Reference in New Issue
Block a user