Adding checks and tests for exceptions on unknown fieldnames
This commit is contained in:
parent
6a7eedd8ae
commit
c57672c9b3
|
@ -36,7 +36,7 @@ import java.util.Objects;
|
|||
* This abstract class holds parameters shared by {@link HighlightBuilder} and {@link HighlightBuilder.Field}
|
||||
* and provides the common setters, equality, hashCode calculation and common serialization
|
||||
*/
|
||||
public abstract class AbstractHighlighterBuilder<HB extends AbstractHighlighterBuilder> {
|
||||
public abstract class AbstractHighlighterBuilder<HB extends AbstractHighlighterBuilder<?>> {
|
||||
|
||||
public static final ParseField PRE_TAGS_FIELD = new ParseField("pre_tags");
|
||||
public static final ParseField POST_TAGS_FIELD = new ParseField("post_tags");
|
||||
|
@ -72,7 +72,7 @@ public abstract class AbstractHighlighterBuilder<HB extends AbstractHighlighterB
|
|||
|
||||
protected String fragmenter;
|
||||
|
||||
protected QueryBuilder highlightQuery;
|
||||
protected QueryBuilder<?> highlightQuery;
|
||||
|
||||
protected String order;
|
||||
|
||||
|
@ -198,7 +198,7 @@ public abstract class AbstractHighlighterBuilder<HB extends AbstractHighlighterB
|
|||
* Sets a query to be used for highlighting instead of the search query.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public HB highlightQuery(QueryBuilder highlightQuery) {
|
||||
public HB highlightQuery(QueryBuilder<?> highlightQuery) {
|
||||
this.highlightQuery = highlightQuery;
|
||||
return (HB) this;
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ public abstract class AbstractHighlighterBuilder<HB extends AbstractHighlighterB
|
|||
/**
|
||||
* @return the value set by {@link #highlightQuery(QueryBuilder)}
|
||||
*/
|
||||
public QueryBuilder highlightQuery() {
|
||||
public QueryBuilder<?> highlightQuery() {
|
||||
return this.highlightQuery;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.elasticsearch.search.highlight;
|
||||
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
|
@ -214,7 +215,7 @@ public class HighlightBuilder extends AbstractHighlighterBuilder<HighlightBuilde
|
|||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
if (highlightFieldName != null) {
|
||||
throw new IllegalArgumentException("If highlighter fields is an array it must contain objects containing a single field");
|
||||
throw new ParsingException(parser.getTokenLocation(), "If highlighter fields is an array it must contain objects containing a single field");
|
||||
}
|
||||
highlightFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
|
@ -222,9 +223,11 @@ public class HighlightBuilder extends AbstractHighlighterBuilder<HighlightBuilde
|
|||
}
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("If highlighter fields is an array it must contain objects containing a single field");
|
||||
throw new ParsingException(parser.getTokenLocation(), "If highlighter fields is an array it must contain objects containing a single field");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new ParsingException(parser.getTokenLocation(), "cannot parse array with name [{}]", topLevelFieldName);
|
||||
}
|
||||
} else if (token.isValue()) {
|
||||
if (parseContext.parseFieldMatcher().match(topLevelFieldName, ORDER_FIELD)) {
|
||||
|
@ -255,12 +258,13 @@ public class HighlightBuilder extends AbstractHighlighterBuilder<HighlightBuilde
|
|||
highlightBuilder.forceSource(parser.booleanValue());
|
||||
} else if (parseContext.parseFieldMatcher().match(topLevelFieldName, PHRASE_LIMIT_FIELD)) {
|
||||
highlightBuilder.phraseLimit(parser.intValue());
|
||||
} else {
|
||||
throw new ParsingException(parser.getTokenLocation(), "unexpected fieldname [{}]", topLevelFieldName);
|
||||
}
|
||||
} else if (token == XContentParser.Token.START_OBJECT && topLevelFieldName != null &&
|
||||
parseContext.parseFieldMatcher().match(topLevelFieldName, OPTIONS_FIELD)) {
|
||||
highlightBuilder.options(parser.map());
|
||||
} else if (token == XContentParser.Token.START_OBJECT && topLevelFieldName != null) {
|
||||
if (parseContext.parseFieldMatcher().match(topLevelFieldName, FIELDS_FIELD)) {
|
||||
if (parseContext.parseFieldMatcher().match(topLevelFieldName, OPTIONS_FIELD)) {
|
||||
highlightBuilder.options(parser.map());
|
||||
} else if (parseContext.parseFieldMatcher().match(topLevelFieldName, FIELDS_FIELD)) {
|
||||
String highlightFieldName = null;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
|
@ -271,12 +275,14 @@ public class HighlightBuilder extends AbstractHighlighterBuilder<HighlightBuilde
|
|||
}
|
||||
} else if (parseContext.parseFieldMatcher().match(topLevelFieldName, HIGHLIGHT_QUERY_FIELD)) {
|
||||
highlightBuilder.highlightQuery(parseContext.parseInnerQueryBuilder());
|
||||
} else {
|
||||
throw new ParsingException(parser.getTokenLocation(), "cannot parse object with name [{}]", topLevelFieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (highlightBuilder.preTags() != null && highlightBuilder.postTags() == null) {
|
||||
throw new IllegalArgumentException("Highlighter global preTags are set, but global postTags are not set");
|
||||
throw new ParsingException(parser.getTokenLocation(), "Highlighter global preTags are set, but global postTags are not set");
|
||||
}
|
||||
return highlightBuilder;
|
||||
}
|
||||
|
@ -435,6 +441,8 @@ public class HighlightBuilder extends AbstractHighlighterBuilder<HighlightBuilde
|
|||
matchedFields.add(parser.text());
|
||||
}
|
||||
field.matchedFields(matchedFields.toArray(new String[matchedFields.size()]));
|
||||
} else {
|
||||
throw new ParsingException(parser.getTokenLocation(), "cannot parse array with name [{}]", currentFieldName);
|
||||
}
|
||||
} else if (token.isValue()) {
|
||||
if (parseContext.parseFieldMatcher().match(currentFieldName, FRAGMENT_SIZE_FIELD)) {
|
||||
|
@ -463,12 +471,16 @@ public class HighlightBuilder extends AbstractHighlighterBuilder<HighlightBuilde
|
|||
field.forceSource(parser.booleanValue());
|
||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, PHRASE_LIMIT_FIELD)) {
|
||||
field.phraseLimit(parser.intValue());
|
||||
} else {
|
||||
throw new ParsingException(parser.getTokenLocation(), "unexpected fieldname [{}]", currentFieldName);
|
||||
}
|
||||
} else if (token == XContentParser.Token.START_OBJECT && currentFieldName != null) {
|
||||
if (parseContext.parseFieldMatcher().match(currentFieldName, HIGHLIGHT_QUERY_FIELD)) {
|
||||
field.highlightQuery(parseContext.parseInnerQueryBuilder());
|
||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, OPTIONS_FIELD)) {
|
||||
field.options(parser.map());
|
||||
} else {
|
||||
throw new ParsingException(parser.getTokenLocation(), "cannot parse object with name [{}]", currentFieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.elasticsearch.search.highlight;
|
||||
|
||||
import org.elasticsearch.common.ParseFieldMatcher;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||
import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput;
|
||||
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
||||
|
@ -151,6 +152,117 @@ public class HighlightBuilderTests extends ESTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* test that unknown array fields cause exception
|
||||
*/
|
||||
public void testUnknownArrayNameExpection() throws IOException {
|
||||
QueryParseContext context = new QueryParseContext(indicesQueriesRegistry);
|
||||
context.parseFieldMatcher(new ParseFieldMatcher(Settings.EMPTY));
|
||||
String highlightElement = "{\n" +
|
||||
" \"bad_fieldname\" : [ \"field1\" 1 \"field2\" ]\n" +
|
||||
"}\n";
|
||||
XContentParser parser = XContentFactory.xContent(highlightElement).createParser(highlightElement);
|
||||
|
||||
context.reset(parser);
|
||||
try {
|
||||
HighlightBuilder.fromXContent(context);
|
||||
fail("expected a parsing exception");
|
||||
} catch (ParsingException e) {
|
||||
assertEquals("cannot parse array with name [bad_fieldname]", e.getMessage());
|
||||
}
|
||||
|
||||
highlightElement = "{\n" +
|
||||
" \"fields\" : {\n" +
|
||||
" \"body\" : {\n" +
|
||||
" \"bad_fieldname\" : [ \"field1\" , \"field2\" ]\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
parser = XContentFactory.xContent(highlightElement).createParser(highlightElement);
|
||||
|
||||
context.reset(parser);
|
||||
try {
|
||||
HighlightBuilder.fromXContent(context);
|
||||
fail("expected a parsing exception");
|
||||
} catch (ParsingException e) {
|
||||
assertEquals("cannot parse array with name [bad_fieldname]", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* test that unknown field name cause exception
|
||||
*/
|
||||
public void testUnknownFieldnameExpection() throws IOException {
|
||||
QueryParseContext context = new QueryParseContext(indicesQueriesRegistry);
|
||||
context.parseFieldMatcher(new ParseFieldMatcher(Settings.EMPTY));
|
||||
String highlightElement = "{\n" +
|
||||
" \"bad_fieldname\" : \"value\"\n" +
|
||||
"}\n";
|
||||
XContentParser parser = XContentFactory.xContent(highlightElement).createParser(highlightElement);
|
||||
|
||||
context.reset(parser);
|
||||
try {
|
||||
HighlightBuilder.fromXContent(context);
|
||||
fail("expected a parsing exception");
|
||||
} catch (ParsingException e) {
|
||||
assertEquals("unexpected fieldname [bad_fieldname]", e.getMessage());
|
||||
}
|
||||
|
||||
highlightElement = "{\n" +
|
||||
" \"fields\" : {\n" +
|
||||
" \"body\" : {\n" +
|
||||
" \"bad_fieldname\" : \"value\"\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
parser = XContentFactory.xContent(highlightElement).createParser(highlightElement);
|
||||
|
||||
context.reset(parser);
|
||||
try {
|
||||
HighlightBuilder.fromXContent(context);
|
||||
fail("expected a parsing exception");
|
||||
} catch (ParsingException e) {
|
||||
assertEquals("unexpected fieldname [bad_fieldname]", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* test that unknown field name cause exception
|
||||
*/
|
||||
public void testUnknownObjectFieldnameExpection() throws IOException {
|
||||
QueryParseContext context = new QueryParseContext(indicesQueriesRegistry);
|
||||
context.parseFieldMatcher(new ParseFieldMatcher(Settings.EMPTY));
|
||||
String highlightElement = "{\n" +
|
||||
" \"bad_fieldname\" : { \"field\" : \"value\" }\n \n" +
|
||||
"}\n";
|
||||
XContentParser parser = XContentFactory.xContent(highlightElement).createParser(highlightElement);
|
||||
|
||||
context.reset(parser);
|
||||
try {
|
||||
HighlightBuilder.fromXContent(context);
|
||||
fail("expected a parsing exception");
|
||||
} catch (ParsingException e) {
|
||||
assertEquals("cannot parse object with name [bad_fieldname]", e.getMessage());
|
||||
}
|
||||
|
||||
highlightElement = "{\n" +
|
||||
" \"fields\" : {\n" +
|
||||
" \"body\" : {\n" +
|
||||
" \"bad_fieldname\" : { \"field\" : \"value\" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
parser = XContentFactory.xContent(highlightElement).createParser(highlightElement);
|
||||
|
||||
context.reset(parser);
|
||||
try {
|
||||
HighlightBuilder.fromXContent(context);
|
||||
fail("expected a parsing exception");
|
||||
} catch (ParsingException e) {
|
||||
assertEquals("cannot parse object with name [bad_fieldname]", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `tags_schema` is not produced by toXContent in the builder but should be parseable, so this
|
||||
* adds a simple json test for this.
|
||||
|
@ -230,7 +342,7 @@ public class HighlightBuilderTests extends ESTestCase {
|
|||
return testHighlighter;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private static void setRandomCommonOptions(AbstractHighlighterBuilder highlightBuilder) {
|
||||
if (randomBoolean()) {
|
||||
// need to set this together, otherwise parsing will complain
|
||||
|
|
Loading…
Reference in New Issue