Merge branch 'master' into feature/client_aggs_parsing

This commit is contained in:
Christoph Büscher 2017-05-16 11:54:02 +02:00
commit 059b23e92e
38 changed files with 474 additions and 165 deletions

View File

@ -224,10 +224,6 @@ public class MoreLikeThisQuery extends Query {
return likeText; return likeText;
} }
public void setLikeText(String likeText) {
setLikeText(new String[]{likeText});
}
public void setLikeText(String... likeText) { public void setLikeText(String... likeText) {
this.likeText = likeText; this.likeText = likeText;
} }
@ -236,7 +232,7 @@ public class MoreLikeThisQuery extends Query {
return likeFields; return likeFields;
} }
public void setLikeText(Fields... likeFields) { public void setLikeFields(Fields... likeFields) {
this.likeFields = likeFields; this.likeFields = likeFields;
} }
@ -244,7 +240,7 @@ public class MoreLikeThisQuery extends Query {
setLikeText(likeText.toArray(Strings.EMPTY_ARRAY)); setLikeText(likeText.toArray(Strings.EMPTY_ARRAY));
} }
public void setUnlikeText(Fields... unlikeFields) { public void setUnlikeFields(Fields... unlikeFields) {
this.unlikeFields = unlikeFields; this.unlikeFields = unlikeFields;
} }

View File

@ -399,7 +399,7 @@ public final class ObjectParser<Value, Context> extends AbstractObjectParser<Val
LONG(VALUE_NUMBER, VALUE_STRING), LONG(VALUE_NUMBER, VALUE_STRING),
LONG_OR_NULL(VALUE_NUMBER, VALUE_STRING, VALUE_NULL), LONG_OR_NULL(VALUE_NUMBER, VALUE_STRING, VALUE_NULL),
INT(VALUE_NUMBER, VALUE_STRING), INT(VALUE_NUMBER, VALUE_STRING),
BOOLEAN(VALUE_BOOLEAN), BOOLEAN(VALUE_BOOLEAN, VALUE_STRING),
STRING_ARRAY(START_ARRAY, VALUE_STRING), STRING_ARRAY(START_ARRAY, VALUE_STRING),
FLOAT_ARRAY(START_ARRAY, VALUE_NUMBER, VALUE_STRING), FLOAT_ARRAY(START_ARRAY, VALUE_NUMBER, VALUE_STRING),
DOUBLE_ARRAY(START_ARRAY, VALUE_NUMBER, VALUE_STRING), DOUBLE_ARRAY(START_ARRAY, VALUE_NUMBER, VALUE_STRING),

View File

@ -178,6 +178,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
this.index = copy.index; this.index = copy.index;
this.type = copy.type; this.type = copy.type;
this.id = copy.id; this.id = copy.id;
this.routing = copy.routing;
this.doc = copy.doc; this.doc = copy.doc;
this.xContentType = copy.xContentType; this.xContentType = copy.xContentType;
this.fields = copy.fields; this.fields = copy.fields;
@ -343,7 +344,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
/** /**
* Convert this to a {@link TermVectorsRequest} for fetching the terms of the document. * Convert this to a {@link TermVectorsRequest} for fetching the terms of the document.
*/ */
public TermVectorsRequest toTermVectorsRequest() { TermVectorsRequest toTermVectorsRequest() {
TermVectorsRequest termVectorsRequest = new TermVectorsRequest(index, type, id) TermVectorsRequest termVectorsRequest = new TermVectorsRequest(index, type, id)
.selectedFields(fields) .selectedFields(fields)
.routing(routing) .routing(routing)
@ -1085,14 +1086,14 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
// fetching the items with multi-termvectors API // fetching the items with multi-termvectors API
MultiTermVectorsResponse likeItemsResponse = fetchResponse(context.getClient(), likeItems); MultiTermVectorsResponse likeItemsResponse = fetchResponse(context.getClient(), likeItems);
// getting the Fields for liked items // getting the Fields for liked items
mltQuery.setLikeText(getFieldsFor(likeItemsResponse)); mltQuery.setLikeFields(getFieldsFor(likeItemsResponse));
// getting the Fields for unliked items // getting the Fields for unliked items
if (unlikeItems.length > 0) { if (unlikeItems.length > 0) {
MultiTermVectorsResponse unlikeItemsResponse = fetchResponse(context.getClient(), unlikeItems); MultiTermVectorsResponse unlikeItemsResponse = fetchResponse(context.getClient(), unlikeItems);
org.apache.lucene.index.Fields[] unlikeFields = getFieldsFor(unlikeItemsResponse); org.apache.lucene.index.Fields[] unlikeFields = getFieldsFor(unlikeItemsResponse);
if (unlikeFields.length > 0) { if (unlikeFields.length > 0) {
mltQuery.setUnlikeText(unlikeFields); mltQuery.setUnlikeFields(unlikeFields);
} }
} }

View File

@ -105,7 +105,7 @@ public class QueryRewriteContext {
return nowInMillis.getAsLong(); return nowInMillis.getAsLong();
} }
public BytesReference getTemplateBytes(Script template) { public String getTemplateBytes(Script template) {
CompiledTemplate compiledTemplate = scriptService.compileTemplate(template, ScriptContext.Standard.SEARCH); CompiledTemplate compiledTemplate = scriptService.compileTemplate(template, ScriptContext.Standard.SEARCH);
return compiledTemplate.run(template.getParams()); return compiledTemplate.run(template.getParams());
} }

View File

@ -392,7 +392,7 @@ public class QueryShardContext extends QueryRewriteContext {
} }
@Override @Override
public final BytesReference getTemplateBytes(Script template) { public final String getTemplateBytes(Script template) {
failIfFrozen(); failIfFrozen();
return super.getTemplateBytes(template); return super.getTemplateBytes(template);
} }

View File

@ -48,7 +48,7 @@ public class InternalTemplateService implements TemplateService {
return new Template() { return new Template() {
@Override @Override
public String execute(Map<String, Object> model) { public String execute(Map<String, Object> model) {
return compiledTemplate.run(model).utf8ToString(); return compiledTemplate.run(model);
} }
@Override @Override

View File

@ -64,8 +64,8 @@ public final class ScriptContextRegistry {
/** /**
* @return <tt>true</tt> if the provided {@link ScriptContext} is supported, <tt>false</tt> otherwise * @return <tt>true</tt> if the provided {@link ScriptContext} is supported, <tt>false</tt> otherwise
*/ */
boolean isSupportedContext(ScriptContext scriptContext) { boolean isSupportedContext(String scriptContext) {
return scriptContexts.containsKey(scriptContext.getKey()); return scriptContexts.containsKey(scriptContext);
} }
//script contexts can be used in fine-grained settings, we need to be careful with what we allow here //script contexts can be used in fine-grained settings, we need to be careful with what we allow here

View File

@ -19,13 +19,19 @@
package org.elasticsearch.script; package org.elasticsearch.script;
import org.apache.lucene.util.SetOnce;
import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.function.Function;
/** /**
* Holds the boolean indicating the enabled mode for each of the different scripting languages available, each script source and each * Holds the boolean indicating the enabled mode for each of the different scripting languages available, each script source and each
@ -38,12 +44,55 @@ public class ScriptModes {
final Map<String, Boolean> scriptEnabled; final Map<String, Boolean> scriptEnabled;
ScriptModes(ScriptSettings scriptSettings, Settings settings) { private static final Setting<List<String>> TYPES_ALLOWED_SETTING =
Setting.listSetting("script.types_allowed", Collections.emptyList(), Function.identity(), Setting.Property.NodeScope);
private static final Setting<List<String>> CONTEXTS_ALLOWED_SETTING =
Setting.listSetting("script.contexts_allowed", Collections.emptyList(), Function.identity(), Setting.Property.NodeScope);
private final Set<String> typesAllowed;
private final Set<String> contextsAllowed;
ScriptModes(ScriptContextRegistry scriptContextRegistry, ScriptSettings scriptSettings, Settings settings) {
HashMap<String, Boolean> scriptModes = new HashMap<>(); HashMap<String, Boolean> scriptModes = new HashMap<>();
for (Setting<Boolean> scriptModeSetting : scriptSettings.getScriptLanguageSettings()) { for (Setting<Boolean> scriptModeSetting : scriptSettings.getScriptLanguageSettings()) {
scriptModes.put(scriptModeSetting.getKey(), scriptModeSetting.get(settings)); scriptModes.put(scriptModeSetting.getKey(), scriptModeSetting.get(settings));
} }
this.scriptEnabled = Collections.unmodifiableMap(scriptModes); this.scriptEnabled = Collections.unmodifiableMap(scriptModes);
typesAllowed = TYPES_ALLOWED_SETTING.exists(settings) ? new HashSet<>() : null;
if (typesAllowed != null) {
for (String settingType : TYPES_ALLOWED_SETTING.get(settings)) {
boolean found = false;
for (ScriptType scriptType : ScriptType.values()) {
if (scriptType.getName().equals(settingType)) {
found = true;
typesAllowed.add(settingType);
break;
}
}
if (!found) {
throw new IllegalArgumentException(
"unknown script type [" + settingType + "] found in setting [" + TYPES_ALLOWED_SETTING.getKey() + "].");
}
}
}
contextsAllowed = CONTEXTS_ALLOWED_SETTING.exists(settings) ? new HashSet<>() : null;
if (contextsAllowed != null) {
for (String settingContext : CONTEXTS_ALLOWED_SETTING.get(settings)) {
if (scriptContextRegistry.isSupportedContext(settingContext)) {
contextsAllowed.add(settingContext);
} else {
throw new IllegalArgumentException(
"unknown script context [" + settingContext + "] found in setting [" + CONTEXTS_ALLOWED_SETTING.getKey() + "].");
}
}
}
} }
/** /**
@ -60,6 +109,15 @@ public class ScriptModes {
if (NativeScriptEngine.NAME.equals(lang)) { if (NativeScriptEngine.NAME.equals(lang)) {
return true; return true;
} }
if (typesAllowed != null && typesAllowed.contains(scriptType.getName()) == false) {
throw new IllegalArgumentException("[" + scriptType.getName() + "] scripts cannot be executed");
}
if (contextsAllowed != null && contextsAllowed.contains(scriptContext.getKey()) == false) {
throw new IllegalArgumentException("[" + scriptContext.getKey() + "] scripts cannot be executed");
}
Boolean scriptMode = scriptEnabled.get(getKey(lang, scriptType, scriptContext)); Boolean scriptMode = scriptEnabled.get(getKey(lang, scriptType, scriptContext));
if (scriptMode == null) { if (scriptMode == null) {
throw new IllegalArgumentException("script mode not found for lang [" + lang + "], script_type [" + scriptType + "], operation [" + scriptContext.getKey() + "]"); throw new IllegalArgumentException("script mode not found for lang [" + lang + "], script_type [" + scriptType + "], operation [" + scriptContext.getKey() + "]");

View File

@ -152,7 +152,7 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
this.scriptEnginesByLang = unmodifiableMap(enginesByLangBuilder); this.scriptEnginesByLang = unmodifiableMap(enginesByLangBuilder);
this.scriptEnginesByExt = unmodifiableMap(enginesByExtBuilder); this.scriptEnginesByExt = unmodifiableMap(enginesByExtBuilder);
this.scriptModes = new ScriptModes(scriptSettings, settings); this.scriptModes = new ScriptModes(scriptContextRegistry, scriptSettings, settings);
// add file watcher for static scripts // add file watcher for static scripts
scriptsDirectory = env.scriptsFile(); scriptsDirectory = env.scriptsFile();
@ -325,7 +325,7 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
/** Compiles a template. Note this will be moved to a separate TemplateService in the future. */ /** Compiles a template. Note this will be moved to a separate TemplateService in the future. */
public CompiledTemplate compileTemplate(Script script, ScriptContext scriptContext) { public CompiledTemplate compileTemplate(Script script, ScriptContext scriptContext) {
CompiledScript compiledScript = compile(script, scriptContext); CompiledScript compiledScript = compile(script, scriptContext);
return params -> (BytesReference)executable(compiledScript, params).run(); return params -> (String)executable(compiledScript, params).run();
} }
/** /**
@ -511,7 +511,7 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
private boolean canExecuteScript(String lang, ScriptType scriptType, ScriptContext scriptContext) { private boolean canExecuteScript(String lang, ScriptType scriptType, ScriptContext scriptContext) {
assert lang != null; assert lang != null;
if (scriptContextRegistry.isSupportedContext(scriptContext) == false) { if (scriptContextRegistry.isSupportedContext(scriptContext.getKey()) == false) {
throw new IllegalArgumentException("script context [" + scriptContext.getKey() + "] not supported"); throw new IllegalArgumentException("script context [" + scriptContext.getKey() + "] not supported");
} }
return scriptModes.getScriptEnabled(lang, scriptType, scriptContext); return scriptModes.getScriptEnabled(lang, scriptType, scriptContext);

View File

@ -35,6 +35,7 @@ import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
public class InternalAdjacencyMatrix public class InternalAdjacencyMatrix
extends InternalMultiBucketAggregation<InternalAdjacencyMatrix,InternalAdjacencyMatrix.InternalBucket> extends InternalMultiBucketAggregation<InternalAdjacencyMatrix,InternalAdjacencyMatrix.InternalBucket>
@ -111,6 +112,25 @@ public class InternalAdjacencyMatrix
builder.endObject(); builder.endObject();
return builder; return builder;
} }
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other == null || getClass() != other.getClass()) {
return false;
}
InternalBucket that = (InternalBucket) other;
return Objects.equals(key, that.key)
&& Objects.equals(docCount, that.docCount)
&& Objects.equals(aggregations, that.aggregations);
}
@Override
public int hashCode() {
return Objects.hash(getClass(), key, docCount, aggregations);
}
} }
private final List<InternalBucket> buckets; private final List<InternalBucket> buckets;
@ -215,4 +235,14 @@ public class InternalAdjacencyMatrix
return builder; return builder;
} }
@Override
protected int doHashCode() {
return Objects.hash(buckets);
}
@Override
protected boolean doEquals(Object obj) {
InternalAdjacencyMatrix that = (InternalAdjacencyMatrix) obj;
return Objects.equals(buckets, that.buckets);
}
} }

View File

@ -18,6 +18,7 @@
*/ */
package org.elasticsearch.search.lookup; package org.elasticsearch.search.lookup;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.index.Fields; import org.apache.lucene.index.Fields;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexReaderContext; import org.apache.lucene.index.IndexReaderContext;
@ -26,6 +27,8 @@ import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.ReaderUtil; import org.apache.lucene.index.ReaderUtil;
import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.IndexSearcher;
import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.util.MinimalMap; import org.elasticsearch.common.util.MinimalMap;
import java.io.IOException; import java.io.IOException;
@ -64,7 +67,19 @@ public class LeafIndexLookup extends MinimalMap<String, IndexField> {
// computation is expensive // computation is expensive
private int numDeletedDocs = -1; private int numDeletedDocs = -1;
private boolean deprecationEmitted = false;
private void logDeprecation() {
if (deprecationEmitted == false) {
Logger logger = Loggers.getLogger(getClass());
DeprecationLogger deprecationLogger = new DeprecationLogger(logger);
deprecationLogger.deprecated("Using _index is deprecated. Create a custom ScriptEngine to access index internals.");
deprecationEmitted = true;
}
}
public int numDocs() { public int numDocs() {
logDeprecation();
if (numDocs == -1) { if (numDocs == -1) {
numDocs = parentReader.numDocs(); numDocs = parentReader.numDocs();
} }
@ -72,6 +87,7 @@ public class LeafIndexLookup extends MinimalMap<String, IndexField> {
} }
public int maxDoc() { public int maxDoc() {
logDeprecation();
if (maxDoc == -1) { if (maxDoc == -1) {
maxDoc = parentReader.maxDoc(); maxDoc = parentReader.maxDoc();
} }
@ -79,6 +95,7 @@ public class LeafIndexLookup extends MinimalMap<String, IndexField> {
} }
public int numDeletedDocs() { public int numDeletedDocs() {
logDeprecation();
if (numDeletedDocs == -1) { if (numDeletedDocs == -1) {
numDeletedDocs = parentReader.numDeletedDocs(); numDeletedDocs = parentReader.numDeletedDocs();
} }
@ -127,6 +144,7 @@ public class LeafIndexLookup extends MinimalMap<String, IndexField> {
*/ */
@Override @Override
public IndexField get(Object key) { public IndexField get(Object key) {
logDeprecation();
String stringField = (String) key; String stringField = (String) key;
IndexField indexField = indexFields.get(key); IndexField indexField = indexFields.get(key);
if (indexField == null) { if (indexField == null) {
@ -146,19 +164,23 @@ public class LeafIndexLookup extends MinimalMap<String, IndexField> {
* * * *
*/ */
public Fields termVectors() throws IOException { public Fields termVectors() throws IOException {
logDeprecation();
assert reader != null; assert reader != null;
return reader.getTermVectors(docId); return reader.getTermVectors(docId);
} }
LeafReader getReader() { LeafReader getReader() {
logDeprecation();
return reader; return reader;
} }
public int getDocId() { public int getDocId() {
logDeprecation();
return docId; return docId;
} }
public IndexReader getParentReader() { public IndexReader getParentReader() {
logDeprecation();
if (parentReader == null) { if (parentReader == null) {
return reader; return reader;
} }
@ -166,10 +188,12 @@ public class LeafIndexLookup extends MinimalMap<String, IndexField> {
} }
public IndexSearcher getIndexSearcher() { public IndexSearcher getIndexSearcher() {
logDeprecation();
return indexSearcher; return indexSearcher;
} }
public IndexReaderContext getReaderContext() { public IndexReaderContext getReaderContext() {
logDeprecation();
return getParentReader().getContext(); return getParentReader().getContext();
} }
} }

View File

@ -116,7 +116,7 @@ public final class PhraseSuggester extends Suggester<PhraseSuggestionContext> {
vars.put(SUGGESTION_TEMPLATE_VAR_NAME, spare.toString()); vars.put(SUGGESTION_TEMPLATE_VAR_NAME, spare.toString());
QueryShardContext shardContext = suggestion.getShardContext(); QueryShardContext shardContext = suggestion.getShardContext();
final ExecutableScript executable = collateScript.apply(vars); final ExecutableScript executable = collateScript.apply(vars);
final BytesReference querySource = (BytesReference) executable.run(); final String querySource = (String) executable.run();
try (XContentParser parser = XContentFactory.xContent(querySource).createParser(shardContext.getXContentRegistry(), try (XContentParser parser = XContentFactory.xContent(querySource).createParser(shardContext.getXContentRegistry(),
querySource)) { querySource)) {
QueryBuilder innerQueryBuilder = shardContext.newParseContext(parser).parseInnerQueryBuilder(); QueryBuilder innerQueryBuilder = shardContext.newParseContext(parser).parseInnerQueryBuilder();

View File

@ -31,5 +31,5 @@ import org.elasticsearch.script.ScriptType;
public interface CompiledTemplate { public interface CompiledTemplate {
/** Run a template and return the resulting string, encoded in utf8 bytes. */ /** Run a template and return the resulting string, encoded in utf8 bytes. */
BytesReference run(Map<String, Object> params); String run(Map<String, Object> params);
} }

View File

@ -31,6 +31,7 @@ import java.io.UncheckedIOException;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.hasSize;
@ -108,7 +109,6 @@ public class ObjectParserTests extends ESTestCase {
s = objectParser.parse(parser, null); s = objectParser.parse(parser, null);
assertNotNull(s.object); assertNotNull(s.object);
assertEquals(s.object.test, 0); assertEquals(s.object.test, 0);
} }
/** /**
@ -353,7 +353,11 @@ public class ObjectParserTests extends ESTestCase {
builder.field("string_array_field", "5"); builder.field("string_array_field", "5");
} }
boolean nullValue = randomBoolean(); boolean nullValue = randomBoolean();
builder.field("boolean_field", nullValue); if (randomBoolean()) {
builder.field("boolean_field", nullValue);
} else {
builder.field("boolean_field", Boolean.toString(nullValue));
}
builder.field("string_or_null", nullValue ? null : "5"); builder.field("string_or_null", nullValue ? null : "5");
builder.endObject(); builder.endObject();
XContentParser parser = createParser(JsonXContent.jsonXContent, builder.string()); XContentParser parser = createParser(JsonXContent.jsonXContent, builder.string());
@ -424,19 +428,19 @@ public class ObjectParserTests extends ESTestCase {
objectParser.declareStringOrNull(TestStruct::setString_or_null, new ParseField("string_or_null")); objectParser.declareStringOrNull(TestStruct::setString_or_null, new ParseField("string_or_null"));
objectParser.declareBoolean(TestStruct::setNull_value, new ParseField("boolean_field")); objectParser.declareBoolean(TestStruct::setNull_value, new ParseField("boolean_field"));
TestStruct parse = objectParser.parse(parser, new TestStruct(), null); TestStruct parse = objectParser.parse(parser, new TestStruct(), null);
assertArrayEquals(parse.double_array_field.toArray(), Arrays.asList(2.1d).toArray()); assertArrayEquals(parse.double_array_field.toArray(), Collections.singletonList(2.1d).toArray());
assertEquals(parse.double_field, 2.1d, 0.0d); assertEquals(parse.double_field, 2.1d, 0.0d);
assertArrayEquals(parse.long_array_field.toArray(), Arrays.asList(4L).toArray()); assertArrayEquals(parse.long_array_field.toArray(), Collections.singletonList(4L).toArray());
assertEquals(parse.long_field, 4L); assertEquals(parse.long_field, 4L);
assertArrayEquals(parse.string_array_field.toArray(), Arrays.asList("5").toArray()); assertArrayEquals(parse.string_array_field.toArray(), Collections.singletonList("5").toArray());
assertEquals(parse.string_field, "5"); assertEquals(parse.string_field, "5");
assertArrayEquals(parse.int_array_field.toArray(), Arrays.asList(1).toArray()); assertArrayEquals(parse.int_array_field.toArray(), Collections.singletonList(1).toArray());
assertEquals(parse.int_field, 1); assertEquals(parse.int_field, 1);
assertArrayEquals(parse.float_array_field.toArray(), Arrays.asList(3.1f).toArray()); assertArrayEquals(parse.float_array_field.toArray(), Collections.singletonList(3.1f).toArray());
assertEquals(parse.float_field, 3.1f, 0.0f); assertEquals(parse.float_field, 3.1f, 0.0f);
assertEquals(nullValue, parse.null_value); assertEquals(nullValue, parse.null_value);

View File

@ -23,6 +23,7 @@ import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
import org.apache.lucene.index.Fields; import org.apache.lucene.index.Fields;
import org.apache.lucene.index.MultiFields; import org.apache.lucene.index.MultiFields;
import org.apache.lucene.index.memory.MemoryIndex; import org.apache.lucene.index.memory.MemoryIndex;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchException;
@ -61,6 +62,7 @@ import java.util.stream.Stream;
import static org.elasticsearch.index.query.QueryBuilders.moreLikeThisQuery; import static org.elasticsearch.index.query.QueryBuilders.moreLikeThisQuery;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.instanceOf;
public class MoreLikeThisQueryBuilderTests extends AbstractQueryTestCase<MoreLikeThisQueryBuilder> { public class MoreLikeThisQueryBuilderTests extends AbstractQueryTestCase<MoreLikeThisQueryBuilder> {
@ -264,6 +266,13 @@ public class MoreLikeThisQueryBuilderTests extends AbstractQueryTestCase<MoreLik
protected void doAssertLuceneQuery(MoreLikeThisQueryBuilder queryBuilder, Query query, SearchContext context) throws IOException { protected void doAssertLuceneQuery(MoreLikeThisQueryBuilder queryBuilder, Query query, SearchContext context) throws IOException {
if (queryBuilder.likeItems() != null && queryBuilder.likeItems().length > 0) { if (queryBuilder.likeItems() != null && queryBuilder.likeItems().length > 0) {
assertThat(query, instanceOf(BooleanQuery.class)); assertThat(query, instanceOf(BooleanQuery.class));
BooleanQuery booleanQuery = (BooleanQuery) query;
for (BooleanClause booleanClause : booleanQuery) {
if (booleanClause.getQuery() instanceof MoreLikeThisQuery) {
MoreLikeThisQuery moreLikeThisQuery = (MoreLikeThisQuery) booleanClause.getQuery();
assertThat(moreLikeThisQuery.getLikeFields().length, greaterThan(0));
}
}
} else { } else {
// we rely on integration tests for a deeper check here // we rely on integration tests for a deeper check here
assertThat(query, instanceOf(MoreLikeThisQuery.class)); assertThat(query, instanceOf(MoreLikeThisQuery.class));
@ -310,6 +319,12 @@ public class MoreLikeThisQueryBuilderTests extends AbstractQueryTestCase<MoreLik
assertEquals(expectedItem, newItem); assertEquals(expectedItem, newItem);
} }
public void testItemCopy() throws IOException {
Item expectedItem = generateRandomItem();
Item newItem = new Item(expectedItem);
assertEquals(expectedItem, newItem);
}
public void testItemFromXContent() throws IOException { public void testItemFromXContent() throws IOException {
Item expectedItem = generateRandomItem(); Item expectedItem = generateRandomItem();
String json = expectedItem.toXContent(XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS).string(); String json = expectedItem.toXContent(XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS).string();

View File

@ -77,6 +77,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import static org.elasticsearch.node.RecoverySettingsChunkSizePlugin.CHUNK_SIZE_SETTING; import static org.elasticsearch.node.RecoverySettingsChunkSizePlugin.CHUNK_SIZE_SETTING;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
@ -348,39 +349,28 @@ public class IndexRecoveryIT extends ESIntegTestCase {
assertRecoveryState(recoveryStates.get(0), 0, PeerRecoverySource.INSTANCE, true, Stage.DONE, nodeA, nodeB); assertRecoveryState(recoveryStates.get(0), 0, PeerRecoverySource.INSTANCE, true, Stage.DONE, nodeA, nodeB);
validateIndexRecoveryState(recoveryStates.get(0).getIndex()); validateIndexRecoveryState(recoveryStates.get(0).getIndex());
Consumer<String> assertNodeHasThrottleTimeAndNoRecoveries = nodeName -> {
statsResponse = client().admin().cluster().prepareNodesStats().clear().setIndices(new CommonStatsFlags(CommonStatsFlags.Flag.Recovery)).get(); NodesStatsResponse nodesStatsResponse = client().admin().cluster().prepareNodesStats().setNodesIds(nodeName)
assertThat(statsResponse.getNodes(), hasSize(2)); .clear().setIndices(new CommonStatsFlags(CommonStatsFlags.Flag.Recovery)).get();
for (NodeStats nodeStats : statsResponse.getNodes()) { assertThat(nodesStatsResponse.getNodes(), hasSize(1));
NodeStats nodeStats = nodesStatsResponse.getNodes().get(0);
final RecoveryStats recoveryStats = nodeStats.getIndices().getRecoveryStats(); final RecoveryStats recoveryStats = nodeStats.getIndices().getRecoveryStats();
assertThat(recoveryStats.currentAsSource(), equalTo(0)); assertThat(recoveryStats.currentAsSource(), equalTo(0));
assertThat(recoveryStats.currentAsTarget(), equalTo(0)); assertThat(recoveryStats.currentAsTarget(), equalTo(0));
if (nodeStats.getNode().getName().equals(nodeA)) { assertThat(nodeName + " throttling should be >0", recoveryStats.throttleTime().millis(), greaterThan(0L));
assertThat("node A throttling should be >0", recoveryStats.throttleTime().millis(), greaterThan(0L)); };
} // we have to use assertBusy as recovery counters are decremented only when the last reference to the RecoveryTarget
if (nodeStats.getNode().getName().equals(nodeB)) { // is decremented, which may happen after the recovery was done.
assertThat("node B throttling should be >0 ", recoveryStats.throttleTime().millis(), greaterThan(0L)); assertBusy(() -> assertNodeHasThrottleTimeAndNoRecoveries.accept(nodeA));
} assertBusy(() -> assertNodeHasThrottleTimeAndNoRecoveries.accept(nodeB));
}
logger.info("--> bump replica count"); logger.info("--> bump replica count");
client().admin().indices().prepareUpdateSettings(INDEX_NAME) client().admin().indices().prepareUpdateSettings(INDEX_NAME)
.setSettings(Settings.builder().put("number_of_replicas", 1)).execute().actionGet(); .setSettings(Settings.builder().put("number_of_replicas", 1)).execute().actionGet();
ensureGreen(); ensureGreen();
statsResponse = client().admin().cluster().prepareNodesStats().clear().setIndices(new CommonStatsFlags(CommonStatsFlags.Flag.Recovery)).get(); assertBusy(() -> assertNodeHasThrottleTimeAndNoRecoveries.accept(nodeA));
assertThat(statsResponse.getNodes(), hasSize(2)); assertBusy(() -> assertNodeHasThrottleTimeAndNoRecoveries.accept(nodeB));
for (NodeStats nodeStats : statsResponse.getNodes()) {
final RecoveryStats recoveryStats = nodeStats.getIndices().getRecoveryStats();
assertThat(recoveryStats.currentAsSource(), equalTo(0));
assertThat(recoveryStats.currentAsTarget(), equalTo(0));
if (nodeStats.getNode().getName().equals(nodeA)) {
assertThat("node A throttling should be >0", recoveryStats.throttleTime().millis(), greaterThan(0L));
}
if (nodeStats.getNode().getName().equals(nodeB)) {
assertThat("node B throttling should be >0 ", recoveryStats.throttleTime().millis(), greaterThan(0L));
}
}
logger.info("--> start node C"); logger.info("--> start node C");
String nodeC = internalCluster().startNode(); String nodeC = internalCluster().startNode();

View File

@ -97,14 +97,14 @@ public class ScriptModesTests extends ESTestCase {
} }
public void testDefaultSettings() { public void testDefaultSettings() {
this.scriptModes = new ScriptModes(scriptSettings, Settings.EMPTY); this.scriptModes = new ScriptModes(scriptContextRegistry, scriptSettings, Settings.EMPTY);
assertScriptModesAllOps(true, ScriptType.FILE); assertScriptModesAllOps(true, ScriptType.FILE);
assertScriptModesAllOps(false, ScriptType.STORED, ScriptType.INLINE); assertScriptModesAllOps(false, ScriptType.STORED, ScriptType.INLINE);
} }
public void testMissingSetting() { public void testMissingSetting() {
assertAllSettingsWereChecked = false; assertAllSettingsWereChecked = false;
this.scriptModes = new ScriptModes(scriptSettings, Settings.EMPTY); this.scriptModes = new ScriptModes(scriptContextRegistry, scriptSettings, Settings.EMPTY);
try { try {
scriptModes.getScriptEnabled("non_existing", randomFrom(ScriptType.values()), randomFrom(scriptContexts)); scriptModes.getScriptEnabled("non_existing", randomFrom(ScriptType.values()), randomFrom(scriptContexts));
fail("Expected IllegalArgumentException"); fail("Expected IllegalArgumentException");
@ -131,7 +131,7 @@ public class ScriptModesTests extends ESTestCase {
builder.put("script" + "." + randomScriptTypes[i].getName(), randomScriptModes[i]); builder.put("script" + "." + randomScriptTypes[i].getName(), randomScriptModes[i]);
deprecated.add("script" + "." + randomScriptTypes[i].getName()); deprecated.add("script" + "." + randomScriptTypes[i].getName());
} }
this.scriptModes = new ScriptModes(scriptSettings, builder.build()); this.scriptModes = new ScriptModes(scriptContextRegistry, scriptSettings, builder.build());
for (int i = 0; i < randomInt; i++) { for (int i = 0; i < randomInt; i++) {
assertScriptModesAllOps(randomScriptModes[i], randomScriptTypes[i]); assertScriptModesAllOps(randomScriptModes[i], randomScriptTypes[i]);
@ -167,7 +167,7 @@ public class ScriptModesTests extends ESTestCase {
builder.put("script" + "." + randomScriptContexts[i].getKey(), randomScriptModes[i]); builder.put("script" + "." + randomScriptContexts[i].getKey(), randomScriptModes[i]);
deprecated.add("script" + "." + randomScriptContexts[i].getKey()); deprecated.add("script" + "." + randomScriptContexts[i].getKey());
} }
this.scriptModes = new ScriptModes(scriptSettings, builder.build()); this.scriptModes = new ScriptModes(scriptContextRegistry, scriptSettings, builder.build());
for (int i = 0; i < randomInt; i++) { for (int i = 0; i < randomInt; i++) {
assertScriptModesAllTypes(randomScriptModes[i], randomScriptContexts[i]); assertScriptModesAllTypes(randomScriptModes[i], randomScriptContexts[i]);
@ -187,7 +187,7 @@ public class ScriptModesTests extends ESTestCase {
.put("script.stored", "true") .put("script.stored", "true")
.put("script.inline", "true"); .put("script.inline", "true");
//operations generic settings have precedence over script type generic settings //operations generic settings have precedence over script type generic settings
this.scriptModes = new ScriptModes(scriptSettings, builder.build()); this.scriptModes = new ScriptModes(scriptContextRegistry, scriptSettings, builder.build());
assertScriptModesAllTypes(false, scriptContext); assertScriptModesAllTypes(false, scriptContext);
ScriptContext[] complementOf = complementOf(scriptContext); ScriptContext[] complementOf = complementOf(scriptContext);
assertScriptModes(true, new ScriptType[]{ScriptType.FILE, ScriptType.STORED}, complementOf); assertScriptModes(true, new ScriptType[]{ScriptType.FILE, ScriptType.STORED}, complementOf);

View File

@ -216,6 +216,69 @@ public class ScriptServiceTests extends ESTestCase {
assertThat(compiledScript1.compiled(), sameInstance(compiledScript2.compiled())); assertThat(compiledScript1.compiled(), sameInstance(compiledScript2.compiled()));
} }
public void testAllowAllScriptTypeSettings() throws IOException {
buildScriptService(Settings.EMPTY);
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.SEARCH);
assertCompileAccepted("painless", "script", ScriptType.STORED, ScriptContext.Standard.SEARCH);
}
public void testAllowAllScriptContextSettings() throws IOException {
buildScriptService(Settings.EMPTY);
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.SEARCH);
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.AGGS);
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.UPDATE);
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.INGEST);
}
public void testAllowSomeScriptTypeSettings() throws IOException {
Settings.Builder builder = Settings.builder();
builder.put("script.types_allowed", "inline");
builder.put("script.engine.painless.stored", false);
buildScriptService(builder.build());
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.SEARCH);
assertCompileRejected("painless", "script", ScriptType.STORED, ScriptContext.Standard.SEARCH);
assertSettingDeprecationsAndWarnings(
ScriptSettingsTests.buildDeprecatedSettingsArray(scriptSettings, "script.engine.painless.stored"));
}
public void testAllowSomeScriptContextSettings() throws IOException {
Settings.Builder builder = Settings.builder();
builder.put("script.contexts_allowed", "search, aggs");
builder.put("script.update", false);
buildScriptService(builder.build());
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.SEARCH);
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.AGGS);
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.Standard.UPDATE);
assertSettingDeprecationsAndWarnings(
ScriptSettingsTests.buildDeprecatedSettingsArray(scriptSettings, "script.update"));
}
public void testAllowNoScriptTypeSettings() throws IOException {
Settings.Builder builder = Settings.builder();
builder.put("script.types_allowed", "");
buildScriptService(builder.build());
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.Standard.SEARCH);
assertCompileRejected("painless", "script", ScriptType.STORED, ScriptContext.Standard.SEARCH);
}
public void testAllowNoScriptContextSettings() throws IOException {
Settings.Builder builder = Settings.builder();
builder.put("script.contexts_allowed", "");
buildScriptService(builder.build());
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.Standard.SEARCH);
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.Standard.AGGS);
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.Standard.UPDATE);
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.Standard.INGEST);
}
public void testDefaultBehaviourFineGrainedSettings() throws IOException { public void testDefaultBehaviourFineGrainedSettings() throws IOException {
Settings.Builder builder = Settings.builder(); Settings.Builder builder = Settings.builder();
//rarely inject the default settings, which have no effect //rarely inject the default settings, which have no effect
@ -345,7 +408,7 @@ public class ScriptServiceTests extends ESTestCase {
do { do {
pluginName = randomAlphaOfLength(randomIntBetween(1, 10)); pluginName = randomAlphaOfLength(randomIntBetween(1, 10));
unknownContext = randomAlphaOfLength(randomIntBetween(1, 30)); unknownContext = randomAlphaOfLength(randomIntBetween(1, 30));
} while(scriptContextRegistry.isSupportedContext(new ScriptContext.Plugin(pluginName, unknownContext))); } while(scriptContextRegistry.isSupportedContext(new ScriptContext.Plugin(pluginName, unknownContext).getKey()));
String type = scriptEngine.getType(); String type = scriptEngine.getType();
try { try {
@ -491,8 +554,8 @@ public class ScriptServiceTests extends ESTestCase {
try { try {
scriptService.compile(new Script(scriptType, lang, script, Collections.emptyMap()), scriptContext); scriptService.compile(new Script(scriptType, lang, script, Collections.emptyMap()), scriptContext);
fail("compile should have been rejected for lang [" + lang + "], script_type [" + scriptType + "], scripted_op [" + scriptContext + "]"); fail("compile should have been rejected for lang [" + lang + "], script_type [" + scriptType + "], scripted_op [" + scriptContext + "]");
} catch(IllegalStateException e) { } catch (IllegalArgumentException | IllegalStateException e) {
//all good // pass
} }
} }

View File

@ -0,0 +1,92 @@
/*
* 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.search.aggregations.bucket.adjacency;
import org.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.search.aggregations.InternalAggregations;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import org.elasticsearch.test.InternalAggregationTestCase;
import org.junit.Before;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class InternalAdjacencyMatrixTests extends InternalAggregationTestCase<InternalAdjacencyMatrix> {
private List<String> keys;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
keys = new ArrayList<>();
int numFilters = randomIntBetween(2, 4);
String[] filters = new String[numFilters];
for (int i = 0; i < numFilters; i++) {
filters[i] = randomAlphaOfLength(5);
}
for (int i = 0; i < filters.length; i++) {
keys.add(filters[i]);
for (int j = i + 1; j < filters.length; j++) {
if (filters[i].compareTo(filters[j]) <= 0) {
keys.add(filters[i] + "&" + filters[j]);
} else {
keys.add(filters[j] + "&" + filters[i]);
}
}
}
}
@Override
protected InternalAdjacencyMatrix createTestInstance(String name, List<PipelineAggregator> pipelineAggregators,
Map<String, Object> metaData) {
final List<InternalAdjacencyMatrix.InternalBucket> buckets = new ArrayList<>();
for (int i = 0; i < keys.size(); ++i) {
String key = keys.get(i);
int docCount = randomIntBetween(0, 1000);
buckets.add(new InternalAdjacencyMatrix.InternalBucket(key, docCount, InternalAggregations.EMPTY));
}
return new InternalAdjacencyMatrix(name, buckets, pipelineAggregators, metaData);
}
@Override
protected void assertReduced(InternalAdjacencyMatrix reduced, List<InternalAdjacencyMatrix> inputs) {
final Map<String, Long> expectedCounts = new TreeMap<>();
for (InternalAdjacencyMatrix input : inputs) {
for (InternalAdjacencyMatrix.InternalBucket bucket : input.getBuckets()) {
expectedCounts.compute(bucket.getKeyAsString(),
(key, oldValue) -> (oldValue == null ? 0 : oldValue) + bucket.getDocCount());
}
}
final Map<String, Long> actualCounts = new TreeMap<>();
for (InternalAdjacencyMatrix.InternalBucket bucket : reduced.getBuckets()) {
actualCounts.compute(bucket.getKeyAsString(),
(key, oldValue) -> (oldValue == null ? 0 : oldValue) + bucket.getDocCount());
}
assertEquals(expectedCounts, actualCounts);
}
@Override
protected Reader<InternalAdjacencyMatrix> instanceReader() {
return InternalAdjacencyMatrix::new;
}
}

View File

@ -623,4 +623,18 @@ public class MoreLikeThisIT extends ESIntegTestCase {
assertSearchResponse(response); assertSearchResponse(response);
assertHitCount(response, 1); assertHitCount(response, 1);
} }
public void testWithRouting() throws IOException {
client().prepareIndex("index", "type", "1").setRouting("3").setSource("text", "this is a document").get();
client().prepareIndex("index", "type", "2").setRouting("1").setSource("text", "this is another document").get();
client().prepareIndex("index", "type", "3").setRouting("4").setSource("text", "this is yet another document").get();
refresh("index");
Item item = new Item("index", "type", "2").routing("1");
MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = new MoreLikeThisQueryBuilder(new String[]{"text"}, null, new Item[]{item});
moreLikeThisQueryBuilder.minTermFreq(1);
moreLikeThisQueryBuilder.minDocFreq(1);
SearchResponse searchResponse = client().prepareSearch("index").setQuery(moreLikeThisQueryBuilder).get();
assertEquals(2, searchResponse.getHits().totalHits);
}
} }

View File

@ -1156,7 +1156,7 @@ public class SuggestSearchIT extends ESIntegTestCase {
@Override @Override
public Object run() { public Object run() {
return new BytesArray(result); return result;
} }
}; };
} }

View File

@ -498,7 +498,7 @@ public class RemoteClusterConnectionTests extends ESTestCase {
barrier.await(); barrier.await();
CountDownLatch latch = new CountDownLatch(numConnectionAttempts); CountDownLatch latch = new CountDownLatch(numConnectionAttempts);
for (int i = 0; i < numConnectionAttempts; i++) { for (int i = 0; i < numConnectionAttempts; i++) {
AtomicReference<RuntimeException> executed = new AtomicReference<>(); AtomicReference<Exception> executed = new AtomicReference<>();
ActionListener<Void> listener = ActionListener.wrap( ActionListener<Void> listener = ActionListener.wrap(
x -> { x -> {
if (executed.compareAndSet(null, new RuntimeException())) { if (executed.compareAndSet(null, new RuntimeException())) {
@ -508,10 +508,21 @@ public class RemoteClusterConnectionTests extends ESTestCase {
} }
}, },
x -> { x -> {
if (executed.compareAndSet(null, new RuntimeException())) { if (executed.compareAndSet(null, x)) {
latch.countDown(); latch.countDown();
} else { } else {
throw new AssertionError("shit's been called twice", executed.get()); final String message = x.getMessage();
if ((executed.get().getClass() == x.getClass()
&& "operation was cancelled reason [connect handler is closed]".equals(message)
&& message.equals(executed.get().getMessage())) == false) {
// we do cancel the operation and that means that if timing allows it, the caller
// of a blocking call as well as the handler will get the exception from the
// ExecutionCancelledException concurrently. unless that is the case we fail
// if we get called more than once!
AssertionError assertionError = new AssertionError("shit's been called twice", x);
assertionError.addSuppressed(executed.get());
throw assertionError;
}
} }
if (x instanceof RejectedExecutionException || x instanceof AlreadyClosedException if (x instanceof RejectedExecutionException || x instanceof AlreadyClosedException
|| x instanceof CancellableThreads.ExecutionCancelledException) { || x instanceof CancellableThreads.ExecutionCancelledException) {

View File

@ -77,7 +77,6 @@
# log4j 2 # log4j 2
-Dlog4j.shutdownHookEnabled=false -Dlog4j.shutdownHookEnabled=false
-Dlog4j2.disable.jmx=true -Dlog4j2.disable.jmx=true
-Dlog4j.skipJansi=true
## heap dumps ## heap dumps

View File

@ -33,7 +33,7 @@ Response:
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE[s/\.\.\./"took": $body.took,"timed_out": false,"_shards": $body._shards,"hits": $body.hits,/] // TESTRESPONSE[s/\.\.\./"took": $body.took,"timed_out": false,"_shards": $body._shards,"hits": $body.hits,/]
The name of the aggregation (`grades_count` above) also serves as the key by which the aggregation result can be The name of the aggregation (`types_count` above) also serves as the key by which the aggregation result can be
retrieved from the returned response. retrieved from the returned response.
==== Script ==== Script
@ -65,7 +65,7 @@ This will interpret the `script` parameter as an `inline` script with the `painl
POST /sales/_search?size=0 POST /sales/_search?size=0
{ {
"aggs" : { "aggs" : {
"grades_count" : { "types_count" : {
"value_count" : { "value_count" : {
"script" : { "script" : {
"file": "my_script", "file": "my_script",

View File

@ -12,3 +12,8 @@ elasticsearch 5.0 and have now been removed. Use painless instead.
milliseconds since epoch as a `long`. The same is true for milliseconds since epoch as a `long`. The same is true for
`doc.some_date_field[some_number]`. Use `doc.some_date_field.value.millis` to `doc.some_date_field[some_number]`. Use `doc.some_date_field.value.millis` to
fetch the milliseconds since epoch if you need it. fetch the milliseconds since epoch if you need it.
==== Script Settings
All of the existing scripting security settings have been deprecated. Instead
they are replaced with `script.allowed_types` and `script.allowed_contexts`.

View File

@ -1,6 +1,11 @@
[[breaking_60_settings_changes]] [[breaking_60_settings_changes]]
=== Settings changes === Settings changes
==== Remove support for elasticsearch.json and elasticsearch.yaml configuration file
The configuration file found in the Elasticsearch config directory could previously have
a `.yml`, `.yaml` or `.json` extension. Only `elasticsearch.yml` is now supported.
==== Duplicate keys in configuration file ==== Duplicate keys in configuration file
In previous versions of Elasticsearch, the configuration file was allowed to In previous versions of Elasticsearch, the configuration file was allowed to
@ -66,3 +71,8 @@ and `http.tcp.blocking_server` settings are not recognized anymore.
The `base` similarity is now ignored as coords and query normalization have The `base` similarity is now ignored as coords and query normalization have
been removed. If provided, this setting will be ignored and issue a been removed. If provided, this setting will be ignored and issue a
deprecation warning. deprecation warning.
==== Script Settings
All of the existing scripting security settings have been deprecated. Instead
they are replaced with `script.allowed_types` and `script.allowed_contexts`.

View File

@ -87,6 +87,51 @@ change from the defaults described above. You should be very, very careful
when allowing more than the defaults. Any extra permissions weakens the total when allowing more than the defaults. Any extra permissions weakens the total
security of the Elasticsearch deployment. security of the Elasticsearch deployment.
[[allowed-script-types-setting]]
[float]
=== Allowed script types setting
By default all script types are allowed to be executed. This can be modified using the
setting `script.allowed_types`. Only the types specified as part of the setting will be
allowed to be executed.
[source,yaml]
----
script.allowed_types: inline <1>
----
<1> This will allow only inline scripts to be executed but not stored scripts
(or any other types).
[[allowed-script-contexts-setting]]
[float]
=== Allowed script contexts setting
By default all script contexts are allowed to be executed. This can be modified using the
setting `script.allowed_contexts`. Only the contexts specified as part of the setting will
be allowed to be executed.
[source,yaml]
----
script.allowed_contexts: search, update <1>
----
<1> This will allow only search and update scripts to be executed but not
aggs or plugin scripts (or any other contexts).
[[deprecated-script=settings]]
[float]
=== Deprecated script settings
The following settings have all been deprecated and will be removed in 6.0:
* <<security-script-source>>
* <<security-script-context>>
* <<security-script-fine>>
Use the following instead:
* <<allowed-script-types-setting>>
* <<allowed-script-contexts-setting>>
[[security-script-source]] [[security-script-source]]
[float] [float]
=== Script source settings === Script source settings

View File

@ -39,6 +39,7 @@ import org.elasticsearch.script.SearchScript;
import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.lookup.SearchLookup;
import java.io.Reader; import java.io.Reader;
import java.io.StringWriter;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
@ -58,21 +59,6 @@ public final class MustacheScriptEngine implements ScriptEngine {
public static final String NAME = "mustache"; public static final String NAME = "mustache";
/** Thread local UTF8StreamWriter to store template execution results in, thread local to save object creation.*/
private static ThreadLocal<SoftReference<UTF8StreamWriter>> utf8StreamWriter = new ThreadLocal<>();
/** If exists, reset and return, otherwise create, reset and return a writer.*/
private static UTF8StreamWriter utf8StreamWriter() {
SoftReference<UTF8StreamWriter> ref = utf8StreamWriter.get();
UTF8StreamWriter writer = (ref == null) ? null : ref.get();
if (writer == null) {
writer = new UTF8StreamWriter(1024 * 4);
utf8StreamWriter.set(new SoftReference<>(writer));
}
writer.reset();
return writer;
}
/** /**
* Compile a template string to (in this case) a Mustache object than can * Compile a template string to (in this case) a Mustache object than can
* later be re-used for execution to fill in missing parameter values. * later be re-used for execution to fill in missing parameter values.
@ -146,8 +132,8 @@ public final class MustacheScriptEngine implements ScriptEngine {
@Override @Override
public Object run() { public Object run() {
final BytesStreamOutput result = new BytesStreamOutput(); final StringWriter writer = new StringWriter();
try (UTF8StreamWriter writer = utf8StreamWriter().setOutput(result)) { try {
// crazy reflection here // crazy reflection here
SpecialPermission.check(); SpecialPermission.check();
AccessController.doPrivileged((PrivilegedAction<Void>) () -> { AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
@ -158,7 +144,7 @@ public final class MustacheScriptEngine implements ScriptEngine {
logger.error((Supplier<?>) () -> new ParameterizedMessage("Error running {}", template), e); logger.error((Supplier<?>) () -> new ParameterizedMessage("Error running {}", template), e);
throw new GeneralScriptException("Error running " + template, e); throw new GeneralScriptException("Error running " + template, e);
} }
return result.bytes(); return writer.toString();
} }
} }

View File

@ -26,6 +26,7 @@ import org.elasticsearch.action.search.TransportSearchAction;
import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.HandledTransportAction; import org.elasticsearch.action.support.HandledTransportAction;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
@ -102,11 +103,10 @@ public class TransportSearchTemplateAction extends HandledTransportAction<Search
Script script = new Script(searchTemplateRequest.getScriptType(), TEMPLATE_LANG, searchTemplateRequest.getScript(), Script script = new Script(searchTemplateRequest.getScriptType(), TEMPLATE_LANG, searchTemplateRequest.getScript(),
searchTemplateRequest.getScriptParams() == null ? Collections.emptyMap() : searchTemplateRequest.getScriptParams()); searchTemplateRequest.getScriptParams() == null ? Collections.emptyMap() : searchTemplateRequest.getScriptParams());
CompiledTemplate compiledScript = scriptService.compileTemplate(script, SEARCH); CompiledTemplate compiledScript = scriptService.compileTemplate(script, SEARCH);
BytesReference source = compiledScript.run(script.getParams()); String source = compiledScript.run(script.getParams());
response.setSource(source); response.setSource(new BytesArray(source));
SearchRequest searchRequest = searchTemplateRequest.getRequest(); SearchRequest searchRequest = searchTemplateRequest.getRequest();
response.setSource(source);
if (searchTemplateRequest.isSimulate()) { if (searchTemplateRequest.isSimulate()) {
return null; return null;
} }

View File

@ -68,8 +68,7 @@ public class CustomMustacheFactoryTests extends ESTestCase {
CompiledScript compiled = new CompiledScript(INLINE, null, MustacheScriptEngine.NAME, script); CompiledScript compiled = new CompiledScript(INLINE, null, MustacheScriptEngine.NAME, script);
ExecutableScript executable = engine.executable(compiled, singletonMap("value", "a \"value\"")); ExecutableScript executable = engine.executable(compiled, singletonMap("value", "a \"value\""));
BytesReference result = (BytesReference) executable.run(); assertThat(executable.run(), equalTo("{\"field\": \"a \\\"value\\\"\"}"));
assertThat(result.utf8ToString(), equalTo("{\"field\": \"a \\\"value\\\"\"}"));
} }
public void testDefaultEncoder() { public void testDefaultEncoder() {
@ -80,8 +79,7 @@ public class CustomMustacheFactoryTests extends ESTestCase {
CompiledScript compiled = new CompiledScript(INLINE, null, MustacheScriptEngine.NAME, script); CompiledScript compiled = new CompiledScript(INLINE, null, MustacheScriptEngine.NAME, script);
ExecutableScript executable = engine.executable(compiled, singletonMap("value", "a \"value\"")); ExecutableScript executable = engine.executable(compiled, singletonMap("value", "a \"value\""));
BytesReference result = (BytesReference) executable.run(); assertThat(executable.run(), equalTo("{\"field\": \"a \"value\"\"}"));
assertThat(result.utf8ToString(), equalTo("{\"field\": \"a \"value\"\"}"));
} }
public void testUrlEncoder() { public void testUrlEncoder() {
@ -92,7 +90,6 @@ public class CustomMustacheFactoryTests extends ESTestCase {
CompiledScript compiled = new CompiledScript(INLINE, null, MustacheScriptEngine.NAME, script); CompiledScript compiled = new CompiledScript(INLINE, null, MustacheScriptEngine.NAME, script);
ExecutableScript executable = engine.executable(compiled, singletonMap("value", "tilde~ AND date:[2016 FROM*]")); ExecutableScript executable = engine.executable(compiled, singletonMap("value", "tilde~ AND date:[2016 FROM*]"));
BytesReference result = (BytesReference) executable.run(); assertThat(executable.run(), equalTo("{\"field\": \"tilde%7E+AND+date%3A%5B2016+FROM*%5D\"}"));
assertThat(result.utf8ToString(), equalTo("{\"field\": \"tilde%7E+AND+date%3A%5B2016+FROM*%5D\"}"));
} }
} }

View File

@ -58,11 +58,11 @@ public class MustacheScriptEngineTests extends ESTestCase {
+ "\"negative\": {\"term\": {\"body\": {\"value\": \"solr\"}" + "}}, \"negative_boost\": {{boost_val}} } }}"; + "\"negative\": {\"term\": {\"body\": {\"value\": \"solr\"}" + "}}, \"negative_boost\": {{boost_val}} } }}";
Map<String, Object> vars = new HashMap<>(); Map<String, Object> vars = new HashMap<>();
vars.put("boost_val", "0.3"); vars.put("boost_val", "0.3");
BytesReference o = (BytesReference) qe.executable(new CompiledScript(ScriptType.INLINE, "", "mustache", String o = (String) qe.executable(new CompiledScript(ScriptType.INLINE, "", "mustache",
qe.compile(null, template, compileParams)), vars).run(); qe.compile(null, template, compileParams)), vars).run();
assertEquals("GET _search {\"query\": {\"boosting\": {\"positive\": {\"match\": {\"body\": \"gift\"}}," assertEquals("GET _search {\"query\": {\"boosting\": {\"positive\": {\"match\": {\"body\": \"gift\"}},"
+ "\"negative\": {\"term\": {\"body\": {\"value\": \"solr\"}}}, \"negative_boost\": 0.3 } }}", + "\"negative\": {\"term\": {\"body\": {\"value\": \"solr\"}}}, \"negative_boost\": 0.3 } }}",
o.utf8ToString()); o);
} }
{ {
String template = "GET _search {\"query\": " + "{\"boosting\": {" + "\"positive\": {\"match\": {\"body\": \"gift\"}}," String template = "GET _search {\"query\": " + "{\"boosting\": {" + "\"positive\": {\"match\": {\"body\": \"gift\"}},"
@ -70,11 +70,11 @@ public class MustacheScriptEngineTests extends ESTestCase {
Map<String, Object> vars = new HashMap<>(); Map<String, Object> vars = new HashMap<>();
vars.put("boost_val", "0.3"); vars.put("boost_val", "0.3");
vars.put("body_val", "\"quick brown\""); vars.put("body_val", "\"quick brown\"");
BytesReference o = (BytesReference) qe.executable(new CompiledScript(ScriptType.INLINE, "", "mustache", String o = (String) qe.executable(new CompiledScript(ScriptType.INLINE, "", "mustache",
qe.compile(null, template, compileParams)), vars).run(); qe.compile(null, template, compileParams)), vars).run();
assertEquals("GET _search {\"query\": {\"boosting\": {\"positive\": {\"match\": {\"body\": \"gift\"}}," assertEquals("GET _search {\"query\": {\"boosting\": {\"positive\": {\"match\": {\"body\": \"gift\"}},"
+ "\"negative\": {\"term\": {\"body\": {\"value\": \"\\\"quick brown\\\"\"}}}, \"negative_boost\": 0.3 } }}", + "\"negative\": {\"term\": {\"body\": {\"value\": \"\\\"quick brown\\\"\"}}}, \"negative_boost\": 0.3 } }}",
o.utf8ToString()); o);
} }
} }
@ -89,7 +89,7 @@ public class MustacheScriptEngineTests extends ESTestCase {
CompiledScript compiledScript = new CompiledScript(ScriptType.INLINE, null, "mustache", CompiledScript compiledScript = new CompiledScript(ScriptType.INLINE, null, "mustache",
qe.compile(null, script.getIdOrCode(), Collections.emptyMap())); qe.compile(null, script.getIdOrCode(), Collections.emptyMap()));
ExecutableScript executableScript = qe.executable(compiledScript, script.getParams()); ExecutableScript executableScript = qe.executable(compiledScript, script.getParams());
assertThat(((BytesReference) executableScript.run()).utf8ToString(), equalTo("{\"match_all\":{}}")); assertThat(executableScript.run(), equalTo("{\"match_all\":{}}"));
} }
public void testParseTemplateAsSingleStringWithConditionalClause() throws IOException { public void testParseTemplateAsSingleStringWithConditionalClause() throws IOException {
@ -105,7 +105,7 @@ public class MustacheScriptEngineTests extends ESTestCase {
CompiledScript compiledScript = new CompiledScript(ScriptType.INLINE, null, "mustache", CompiledScript compiledScript = new CompiledScript(ScriptType.INLINE, null, "mustache",
qe.compile(null, script.getIdOrCode(), Collections.emptyMap())); qe.compile(null, script.getIdOrCode(), Collections.emptyMap()));
ExecutableScript executableScript = qe.executable(compiledScript, script.getParams()); ExecutableScript executableScript = qe.executable(compiledScript, script.getParams());
assertThat(((BytesReference) executableScript.run()).utf8ToString(), equalTo("{ \"match_all\":{} }")); assertThat(executableScript.run(), equalTo("{ \"match_all\":{} }"));
} }
public void testEscapeJson() throws IOException { public void testEscapeJson() throws IOException {

View File

@ -71,7 +71,7 @@ public class MustacheTests extends ESTestCase {
"Mustache templating broken", "Mustache templating broken",
"GET _search {\"query\": {\"boosting\": {\"positive\": {\"match\": {\"body\": \"gift\"}}," "GET _search {\"query\": {\"boosting\": {\"positive\": {\"match\": {\"body\": \"gift\"}},"
+ "\"negative\": {\"term\": {\"body\": {\"value\": \"solr\"}}}, \"negative_boost\": 0.2 } }}", + "\"negative\": {\"term\": {\"body\": {\"value\": \"solr\"}}}, \"negative_boost\": 0.2 } }}",
((BytesReference) result.run()).utf8ToString() result.run()
); );
} }
@ -83,22 +83,16 @@ public class MustacheTests extends ESTestCase {
new String[] { "foo", "bar" }, new String[] { "foo", "bar" },
Arrays.asList("foo", "bar")); Arrays.asList("foo", "bar"));
vars.put("data", data); vars.put("data", data);
Object output = engine.executable(mustache, vars).run(); assertThat(engine.executable(mustache, vars).run(), equalTo("foo bar"));
assertThat(output, notNullValue());
assertThat(output, instanceOf(BytesReference.class));
BytesReference bytes = (BytesReference) output;
assertThat(bytes.utf8ToString(), equalTo("foo bar"));
// Sets can come out in any order // Sets can come out in any order
Set<String> setData = new HashSet<>(); Set<String> setData = new HashSet<>();
setData.add("foo"); setData.add("foo");
setData.add("bar"); setData.add("bar");
vars.put("data", setData); vars.put("data", setData);
output = engine.executable(mustache, vars).run(); Object output = engine.executable(mustache, vars).run();
assertThat(output, notNullValue()); assertThat(output, instanceOf(String.class));
assertThat(output, instanceOf(BytesReference.class)); assertThat((String)output, both(containsString("foo")).and(containsString("bar")));
bytes = (BytesReference) output;
assertThat(bytes.utf8ToString(), both(containsString("foo")).and(containsString("bar")));
} }
public void testArrayInArrayAccess() throws Exception { public void testArrayInArrayAccess() throws Exception {
@ -111,11 +105,7 @@ public class MustacheTests extends ESTestCase {
singleton(new String[] { "foo", "bar" }) singleton(new String[] { "foo", "bar" })
); );
vars.put("data", data); vars.put("data", data);
Object output = engine.executable(mustache, vars).run(); assertThat(engine.executable(mustache, vars).run(), equalTo("foo bar"));
assertThat(output, notNullValue());
assertThat(output, instanceOf(BytesReference.class));
BytesReference bytes = (BytesReference) output;
assertThat(bytes.utf8ToString(), equalTo("foo bar"));
} }
public void testMapInArrayAccess() throws Exception { public void testMapInArrayAccess() throws Exception {
@ -126,22 +116,16 @@ public class MustacheTests extends ESTestCase {
new Object[] { singletonMap("key", "foo"), singletonMap("key", "bar") }, new Object[] { singletonMap("key", "foo"), singletonMap("key", "bar") },
Arrays.asList(singletonMap("key", "foo"), singletonMap("key", "bar"))); Arrays.asList(singletonMap("key", "foo"), singletonMap("key", "bar")));
vars.put("data", data); vars.put("data", data);
Object output = engine.executable(mustache, vars).run(); assertThat(engine.executable(mustache, vars).run(), equalTo("foo bar"));
assertThat(output, notNullValue());
assertThat(output, instanceOf(BytesReference.class));
BytesReference bytes = (BytesReference) output;
assertThat(bytes.utf8ToString(), equalTo("foo bar"));
// HashSet iteration order isn't fixed // HashSet iteration order isn't fixed
Set<Object> setData = new HashSet<>(); Set<Object> setData = new HashSet<>();
setData.add(singletonMap("key", "foo")); setData.add(singletonMap("key", "foo"));
setData.add(singletonMap("key", "bar")); setData.add(singletonMap("key", "bar"));
vars.put("data", setData); vars.put("data", setData);
output = engine.executable(mustache, vars).run(); Object output = engine.executable(mustache, vars).run();
assertThat(output, notNullValue()); assertThat(output, instanceOf(String.class));
assertThat(output, instanceOf(BytesReference.class)); assertThat((String)output, both(containsString("foo")).and(containsString("bar")));
bytes = (BytesReference) output;
assertThat(bytes.utf8ToString(), both(containsString("foo")).and(containsString("bar")));
} }
@ -156,14 +140,8 @@ public class MustacheTests extends ESTestCase {
data.put("list", randomList); data.put("list", randomList);
Map<String, Object> vars = new HashMap<>(); Map<String, Object> vars = new HashMap<>();
vars.put("data", data); vars.put("data", data);
Object output = engine.executable(mustache, vars).run();
assertThat(output, notNullValue());
assertThat(output, instanceOf(BytesReference.class));
BytesReference bytes = (BytesReference) output;
String expectedString = String.format(Locale.ROOT, "%s %s", randomArrayValues.length, randomList.size()); String expectedString = String.format(Locale.ROOT, "%s %s", randomArrayValues.length, randomList.size());
assertThat(bytes.utf8ToString(), equalTo(expectedString)); assertThat(engine.executable(mustache, vars).run(), equalTo(expectedString));
} }
public void testPrimitiveToJSON() throws Exception { public void testPrimitiveToJSON() throws Exception {
@ -399,9 +377,7 @@ public class MustacheTests extends ESTestCase {
private void assertScript(String script, Map<String, Object> vars, Matcher<Object> matcher) { private void assertScript(String script, Map<String, Object> vars, Matcher<Object> matcher) {
Object result = engine.executable(new CompiledScript(INLINE, "inline", "mustache", compile(script)), vars).run(); Object result = engine.executable(new CompiledScript(INLINE, "inline", "mustache", compile(script)), vars).run();
assertThat(result, notNullValue()); assertThat(result, matcher);
assertThat(result, instanceOf(BytesReference.class));
assertThat(((BytesReference) result).utf8ToString(), matcher);
} }
private Object compile(String script) { private Object compile(String script) {

View File

@ -19,13 +19,22 @@
apply plugin: 'elasticsearch.vagrant' apply plugin: 'elasticsearch.vagrant'
dependencies { List<String> plugins = []
// Collect all the plugins for (Project subproj : project.rootProject.subprojects) {
for (Project subproj : project.rootProject.subprojects) { if (subproj.path.startsWith(':plugins:')) {
if (subproj.path.startsWith(':plugins:')) { // add plugin as a dep
dependencies {
bats project(path: "${subproj.path}", configuration: 'zip') bats project(path: "${subproj.path}", configuration: 'zip')
} }
plugins.add(subproj.name)
} }
} }
plugins = plugins.toSorted()
tasks."vagrantCentos6#packagingTest".onlyIf { false } // fails, see https://github.com/elastic/elasticsearch/issues/24645 setupBats {
doFirst {
File expectedPlugins = file('build/plugins/expected')
expectedPlugins.parentFile.mkdirs()
expectedPlugins.setText(plugins.join('\n'), 'UTF-8')
}
}

View File

@ -173,8 +173,6 @@ install_and_check_plugin() {
# $2 description of the source of the plugin list # $2 description of the source of the plugin list
compare_plugins_list() { compare_plugins_list() {
cat $1 | sort > /tmp/plugins cat $1 | sort > /tmp/plugins
ls /elasticsearch/plugins/*/build.gradle | cut -d '/' -f 4 |
sort > /tmp/expected
echo "Checking plugins from $2 (<) against expected plugins (>):" echo "Checking plugins from $2 (<) against expected plugins (>):"
diff /tmp/expected /tmp/plugins diff -w /elasticsearch/qa/vagrant/build/plugins/expected /tmp/plugins
} }

View File

@ -101,18 +101,6 @@ public class BootstrapForTesting {
// initialize paths the same exact way as bootstrap // initialize paths the same exact way as bootstrap
Permissions perms = new Permissions(); Permissions perms = new Permissions();
Security.addClasspathPermissions(perms); Security.addClasspathPermissions(perms);
// crazy jython
for (URL url : JarHell.parseClassPath()) {
Path path = PathUtils.get(url.toURI());
// crazy jython...
String filename = path.getFileName().toString();
if (filename.contains("jython") && filename.endsWith(".jar")) {
// just enough so it won't fail when it does not exist
perms.add(new FilePermission(path.getParent().toString(), "read,readlink"));
perms.add(new FilePermission(path.getParent().resolve("Lib").toString(), "read,readlink"));
}
}
// java.io.tmpdir // java.io.tmpdir
Security.addPath(perms, "java.io.tmpdir", javaTmpDir, "read,readlink,write,delete"); Security.addPath(perms, "java.io.tmpdir", javaTmpDir, "read,readlink,write,delete");
// custom test config file // custom test config file

View File

@ -22,7 +22,6 @@ package org.elasticsearch.script;
import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.Scorer; import org.apache.lucene.search.Scorer;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.search.lookup.LeafSearchLookup; import org.elasticsearch.search.lookup.LeafSearchLookup;
import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.lookup.SearchLookup;
@ -132,7 +131,7 @@ public class MockScriptEngine implements ScriptEngine {
if (vars != null) { if (vars != null) {
context.putAll(vars); context.putAll(vars);
} }
return new MockExecutableScript(context, script != null ? script : ctx -> new BytesArray(source)); return new MockExecutableScript(context, script != null ? script : ctx -> source);
} }
public SearchScript createSearchScript(Map<String, Object> vars, SearchLookup lookup) { public SearchScript createSearchScript(Map<String, Object> vars, SearchLookup lookup) {

View File

@ -177,7 +177,6 @@ public abstract class ESTestCase extends LuceneTestCase {
static { static {
System.setProperty("log4j.shutdownHookEnabled", "false"); System.setProperty("log4j.shutdownHookEnabled", "false");
System.setProperty("log4j2.disable.jmx", "true"); System.setProperty("log4j2.disable.jmx", "true");
System.setProperty("log4j.skipJansi", "true"); // jython has this crazy shaded Jansi version that log4j2 tries to load
// shutdown hook so that when the test JVM exits, logging is shutdown too // shutdown hook so that when the test JVM exits, logging is shutdown too
Runtime.getRuntime().addShutdownHook(new Thread(() -> { Runtime.getRuntime().addShutdownHook(new Thread(() -> {