Test: Convert test script engine impls to use MockScriptEngine (#24854)
This commit cleans up tests which currently use custom script engine implementations, converting them to use a MockScriptEngine with script functions provided by the tests. It also creates a common set of metric scripts which were copied across a couple metric agg tests.
This commit is contained in:
parent
2e570fc6fa
commit
bf49d37ab3
|
@ -23,6 +23,7 @@ import java.nio.file.Path;
|
|||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.elasticsearch.ResourceNotFoundException;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
|
||||
|
@ -46,7 +47,6 @@ import static org.hamcrest.CoreMatchers.containsString;
|
|||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.sameInstance;
|
||||
|
||||
//TODO: this needs to be a base test class, and all scripting engines extend it
|
||||
public class ScriptServiceTests extends ESTestCase {
|
||||
|
||||
private ScriptEngine scriptEngine;
|
||||
|
@ -63,15 +63,18 @@ public class ScriptServiceTests extends ESTestCase {
|
|||
.put(Environment.PATH_CONF_SETTING.getKey(), genericConfigFolder)
|
||||
.put(ScriptService.SCRIPT_MAX_COMPILATIONS_PER_MINUTE.getKey(), 10000)
|
||||
.build();
|
||||
scriptEngine = new TestEngine();
|
||||
TestEngine defaultScriptServiceEngine = new TestEngine(Script.DEFAULT_SCRIPT_LANG) {};
|
||||
//randomly register custom script contexts
|
||||
int randomInt = randomIntBetween(0, 3);
|
||||
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
scripts.put(i + "+" + i, p -> null); // only care about compilation, not execution
|
||||
}
|
||||
scripts.put("script", p -> null);
|
||||
scriptEngine = new MockScriptEngine(Script.DEFAULT_SCRIPT_LANG, scripts);
|
||||
|
||||
//prevent duplicates using map
|
||||
contexts = new HashMap<>(ScriptContext.BUILTINS);
|
||||
engines = new HashMap<>();
|
||||
engines.put(scriptEngine.getType(), scriptEngine);
|
||||
engines.put(defaultScriptServiceEngine.getType(), defaultScriptServiceEngine);
|
||||
engines.put("test", new MockScriptEngine("test", scripts));
|
||||
logger.info("--> setup script service");
|
||||
}
|
||||
|
||||
|
@ -81,7 +84,7 @@ public class ScriptServiceTests extends ESTestCase {
|
|||
@Override
|
||||
StoredScriptSource getScriptFromClusterState(String id, String lang) {
|
||||
//mock the script that gets retrieved from an index
|
||||
return new StoredScriptSource(lang, "100", Collections.emptyMap());
|
||||
return new StoredScriptSource(lang, "1+1", Collections.emptyMap());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -215,10 +218,10 @@ public class ScriptServiceTests extends ESTestCase {
|
|||
|
||||
public void testMultipleCompilationsCountedInCompilationStats() throws IOException {
|
||||
buildScriptService(Settings.EMPTY);
|
||||
int numberOfCompilations = randomIntBetween(1, 1024);
|
||||
int numberOfCompilations = randomIntBetween(1, 20);
|
||||
for (int i = 0; i < numberOfCompilations; i++) {
|
||||
scriptService
|
||||
.compile(new Script(ScriptType.INLINE, "test", i + " + " + i, Collections.emptyMap()), randomFrom(contexts.values()));
|
||||
.compile(new Script(ScriptType.INLINE, "test", i + "+" + i, Collections.emptyMap()), randomFrom(contexts.values()));
|
||||
}
|
||||
assertEquals(numberOfCompilations, scriptService.stats().getCompilations());
|
||||
}
|
||||
|
@ -253,7 +256,7 @@ public class ScriptServiceTests extends ESTestCase {
|
|||
Settings.Builder builder = Settings.builder();
|
||||
buildScriptService(builder.build());
|
||||
CompiledScript script = scriptService.compile(
|
||||
new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, "1 + 1", Collections.emptyMap()), randomFrom(contexts.values()));
|
||||
new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, "1+1", Collections.emptyMap()), randomFrom(contexts.values()));
|
||||
assertEquals(script.lang(), Script.DEFAULT_SCRIPT_LANG);
|
||||
}
|
||||
|
||||
|
@ -314,43 +317,4 @@ public class ScriptServiceTests extends ESTestCase {
|
|||
);
|
||||
}
|
||||
|
||||
public static class TestEngine implements ScriptEngine {
|
||||
|
||||
public static final String NAME = "test";
|
||||
|
||||
private final String name;
|
||||
|
||||
public TestEngine() {
|
||||
this(NAME);
|
||||
}
|
||||
|
||||
public TestEngine(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String scriptName, String scriptText, Map<String, String> params) {
|
||||
return "compiled_" + scriptText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutableScript executable(final CompiledScript compiledScript, @Nullable Map<String, Object> vars) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, @Nullable Map<String, Object> vars) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,37 +18,24 @@
|
|||
*/
|
||||
package org.elasticsearch.search.aggregations.metrics;
|
||||
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.search.Scorer;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.plugins.ScriptPlugin;
|
||||
import org.elasticsearch.script.CompiledScript;
|
||||
import org.elasticsearch.script.ExecutableScript;
|
||||
import org.elasticsearch.script.LeafSearchScript;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptEngine;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
import org.elasticsearch.search.aggregations.BucketOrder;
|
||||
import org.elasticsearch.search.aggregations.InternalAggregation;
|
||||
import org.elasticsearch.search.aggregations.bucket.filter.Filter;
|
||||
import org.elasticsearch.search.aggregations.bucket.global.Global;
|
||||
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
|
||||
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
|
||||
import org.elasticsearch.search.aggregations.metrics.avg.Avg;
|
||||
import org.elasticsearch.search.aggregations.BucketOrder;
|
||||
import org.elasticsearch.search.lookup.LeafSearchLookup;
|
||||
import org.elasticsearch.search.lookup.SearchLookup;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
|
||||
|
@ -57,6 +44,11 @@ import static org.elasticsearch.search.aggregations.AggregationBuilders.filter;
|
|||
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
|
||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
|
||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
|
||||
import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.METRIC_SCRIPT_ENGINE;
|
||||
import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.VALUE_FIELD_SCRIPT;
|
||||
import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.SUM_FIELD_PARAMS_SCRIPT;
|
||||
import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.SUM_VALUES_FIELD_SCRIPT;
|
||||
import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.VALUE_SCRIPT;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
|
||||
|
@ -68,9 +60,7 @@ public class AvgIT extends AbstractNumericTestCase {
|
|||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> nodePlugins() {
|
||||
return Arrays.asList(
|
||||
ExtractFieldScriptPlugin.class,
|
||||
FieldValueScriptPlugin.class);
|
||||
return Collections.singleton(MetricAggScriptPlugin.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -168,7 +158,7 @@ public class AvgIT extends AbstractNumericTestCase {
|
|||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(avg("avg").field("value")
|
||||
.script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", Collections.emptyMap())))
|
||||
.script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, Collections.emptyMap())))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -185,7 +175,7 @@ public class AvgIT extends AbstractNumericTestCase {
|
|||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(avg("avg").field("value")
|
||||
.script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", params)))
|
||||
.script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, params)))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -229,7 +219,7 @@ public class AvgIT extends AbstractNumericTestCase {
|
|||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(avg("avg").field("values")
|
||||
.script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", Collections.emptyMap())))
|
||||
.script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, Collections.emptyMap())))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -246,7 +236,7 @@ public class AvgIT extends AbstractNumericTestCase {
|
|||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(avg("avg").field("values")
|
||||
.script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", params)))
|
||||
.script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, params)))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -262,7 +252,7 @@ public class AvgIT extends AbstractNumericTestCase {
|
|||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(avg("avg")
|
||||
.script(new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "value", Collections.emptyMap())))
|
||||
.script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_FIELD_SCRIPT, Collections.emptyMap())))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -275,11 +265,13 @@ public class AvgIT extends AbstractNumericTestCase {
|
|||
|
||||
@Override
|
||||
public void testScriptSingleValuedWithParams() throws Exception {
|
||||
Map<String, Object> params = Collections.singletonMap("inc", 1);
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("inc", 1);
|
||||
params.put("field", "value");
|
||||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(avg("avg")
|
||||
.script(new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "value", params)))
|
||||
.script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_FIELD_PARAMS_SCRIPT, params)))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -295,7 +287,7 @@ public class AvgIT extends AbstractNumericTestCase {
|
|||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(avg("avg")
|
||||
.script(new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "values", Collections.emptyMap())))
|
||||
.script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_VALUES_FIELD_SCRIPT, Collections.emptyMap())))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -308,11 +300,13 @@ public class AvgIT extends AbstractNumericTestCase {
|
|||
|
||||
@Override
|
||||
public void testScriptMultiValuedWithParams() throws Exception {
|
||||
Map<String, Object> params = Collections.singletonMap("inc", 1);
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("inc", 1);
|
||||
params.put("field", "values");
|
||||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(avg("avg")
|
||||
.script(new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "values", params)))
|
||||
.script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_FIELD_PARAMS_SCRIPT, params)))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -373,7 +367,7 @@ public class AvgIT extends AbstractNumericTestCase {
|
|||
// Test that a request using a script does not get cached
|
||||
SearchResponse r = client().prepareSearch("cache_test_idx").setSize(0)
|
||||
.addAggregation(avg("foo").field("d").script(
|
||||
new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", Collections.emptyMap()))).get();
|
||||
new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_FIELD_SCRIPT, Collections.emptyMap()))).get();
|
||||
assertSearchResponse(r);
|
||||
|
||||
assertThat(client().admin().indices().prepareStats("cache_test_idx").setRequestCache(true).get().getTotal().getRequestCache()
|
||||
|
@ -391,202 +385,4 @@ public class AvgIT extends AbstractNumericTestCase {
|
|||
assertThat(client().admin().indices().prepareStats("cache_test_idx").setRequestCache(true).get().getTotal().getRequestCache()
|
||||
.getMissCount(), equalTo(1L));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock plugin for the {@link ExtractFieldScriptEngine}
|
||||
*/
|
||||
public static class ExtractFieldScriptPlugin extends Plugin implements ScriptPlugin {
|
||||
@Override
|
||||
public ScriptEngine getScriptEngine(Settings settings) {
|
||||
return new ExtractFieldScriptEngine();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This mock script returns the field that is specified by name in the script body
|
||||
*/
|
||||
public static class ExtractFieldScriptEngine implements ScriptEngine {
|
||||
|
||||
public static final String NAME = "extract_field";
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
|
||||
return scriptSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@Override
|
||||
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
|
||||
final long inc;
|
||||
if (vars == null || vars.containsKey("inc") == false) {
|
||||
inc = 0;
|
||||
} else {
|
||||
inc = ((Number) vars.get("inc")).longValue();
|
||||
}
|
||||
return new SearchScript() {
|
||||
|
||||
@Override
|
||||
public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
|
||||
|
||||
final LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
|
||||
|
||||
return new LeafSearchScript() {
|
||||
@Override
|
||||
public void setNextVar(String name, Object value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
String fieldName = (String) compiledScript.compiled();
|
||||
List<Long> values = new ArrayList<>();
|
||||
for (Object v : (List<?>) leafLookup.doc().get(fieldName)) {
|
||||
values.add(((Number) v).longValue() + inc);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScorer(Scorer scorer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(Map<String, Object> source) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocument(int doc) {
|
||||
if (leafLookup != null) {
|
||||
leafLookup.setDocument(doc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long runAsLong() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double runAsDouble() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsScores() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock plugin for the {@link FieldValueScriptEngine}
|
||||
*/
|
||||
public static class FieldValueScriptPlugin extends Plugin implements ScriptPlugin {
|
||||
@Override
|
||||
public ScriptEngine getScriptEngine(Settings settings) {
|
||||
return new FieldValueScriptEngine();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This mock script returns the field value and adds one month to the returned date
|
||||
*/
|
||||
public static class FieldValueScriptEngine implements ScriptEngine {
|
||||
|
||||
public static final String NAME = "field_value";
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
|
||||
return scriptSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@Override
|
||||
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
|
||||
final long inc;
|
||||
if (vars == null || vars.containsKey("inc") == false) {
|
||||
inc = 0;
|
||||
} else {
|
||||
inc = ((Number) vars.get("inc")).longValue();
|
||||
}
|
||||
return new SearchScript() {
|
||||
|
||||
private Map<String, Object> vars = new HashMap<>(2);
|
||||
|
||||
@Override
|
||||
public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
|
||||
|
||||
final LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
|
||||
|
||||
return new LeafSearchScript() {
|
||||
@Override
|
||||
public void setNextVar(String name, Object value) {
|
||||
vars.put(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScorer(Scorer scorer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(Map<String, Object> source) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocument(int doc) {
|
||||
if (leafLookup != null) {
|
||||
leafLookup.setDocument(doc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long runAsLong() {
|
||||
return ((Number) vars.get("_value")).longValue() + inc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double runAsDouble() {
|
||||
return ((Number) vars.get("_value")).doubleValue() + inc;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsScores() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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.metrics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.elasticsearch.script.MockScriptPlugin;
|
||||
import org.elasticsearch.search.lookup.LeafDocLookup;
|
||||
|
||||
/**
|
||||
* Provides a number of dummy scripts for tests.
|
||||
*
|
||||
* Each script provided allows for an {@code inc} parameter which will
|
||||
* be added to each value read from a document.
|
||||
*/
|
||||
public class MetricAggScriptPlugin extends MockScriptPlugin {
|
||||
|
||||
/** The name of the script engine type this plugin provides. */
|
||||
public static final String METRIC_SCRIPT_ENGINE = "metric_scripts";
|
||||
|
||||
/** Script to take a field name in params and sum the values of the field. */
|
||||
public static final String SUM_FIELD_PARAMS_SCRIPT = "sum_field_params";
|
||||
|
||||
/** Script to sum the values of a field named {@code values}. */
|
||||
public static final String SUM_VALUES_FIELD_SCRIPT = "sum_values_field";
|
||||
|
||||
/** Script to return the value of a field named {@code value}. */
|
||||
public static final String VALUE_FIELD_SCRIPT = "value_field";
|
||||
|
||||
/** Script to return the {@code _value} provided by aggs framework. */
|
||||
public static final String VALUE_SCRIPT = "_value";
|
||||
|
||||
@Override
|
||||
public String pluginScriptLang() {
|
||||
return METRIC_SCRIPT_ENGINE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
|
||||
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
|
||||
Function<Map<String, Object>, Integer> getInc = vars -> {
|
||||
if (vars == null || vars.containsKey("inc") == false) {
|
||||
return 0;
|
||||
} else {
|
||||
return ((Number) vars.get("inc")).intValue();
|
||||
}
|
||||
};
|
||||
BiFunction<Map<String, Object>, String, Object> sum = (vars, fieldname) -> {
|
||||
int inc = getInc.apply(vars);
|
||||
LeafDocLookup docLookup = (LeafDocLookup) vars.get("doc");
|
||||
List<Long> values = new ArrayList<>();
|
||||
for (Object v : docLookup.get(fieldname)) {
|
||||
values.add(((Number) v).longValue() + inc);
|
||||
}
|
||||
return values;
|
||||
};
|
||||
scripts.put(SUM_FIELD_PARAMS_SCRIPT, vars -> {
|
||||
String fieldname = (String) vars.get("field");
|
||||
return sum.apply(vars, fieldname);
|
||||
});
|
||||
scripts.put(SUM_VALUES_FIELD_SCRIPT, vars -> sum.apply(vars, "values"));
|
||||
scripts.put(VALUE_FIELD_SCRIPT, vars -> sum.apply(vars, "value"));
|
||||
scripts.put(VALUE_SCRIPT, vars -> {
|
||||
int inc = getInc.apply(vars);
|
||||
return ((Number) vars.get("_value")).doubleValue() + inc;
|
||||
});
|
||||
return scripts;
|
||||
}
|
||||
}
|
|
@ -18,37 +18,24 @@
|
|||
*/
|
||||
package org.elasticsearch.search.aggregations.metrics;
|
||||
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.search.Scorer;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.plugins.ScriptPlugin;
|
||||
import org.elasticsearch.script.CompiledScript;
|
||||
import org.elasticsearch.script.ExecutableScript;
|
||||
import org.elasticsearch.script.LeafSearchScript;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptEngine;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
import org.elasticsearch.search.aggregations.BucketOrder;
|
||||
import org.elasticsearch.search.aggregations.InternalAggregation;
|
||||
import org.elasticsearch.search.aggregations.bucket.filter.Filter;
|
||||
import org.elasticsearch.search.aggregations.bucket.global.Global;
|
||||
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
|
||||
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
|
||||
import org.elasticsearch.search.aggregations.metrics.sum.Sum;
|
||||
import org.elasticsearch.search.aggregations.BucketOrder;
|
||||
import org.elasticsearch.search.lookup.LeafSearchLookup;
|
||||
import org.elasticsearch.search.lookup.SearchLookup;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
|
||||
|
@ -57,6 +44,10 @@ import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
|
|||
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
|
||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
|
||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
|
||||
import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.METRIC_SCRIPT_ENGINE;
|
||||
import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.SUM_VALUES_FIELD_SCRIPT;
|
||||
import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.VALUE_FIELD_SCRIPT;
|
||||
import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.VALUE_SCRIPT;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
|
||||
|
@ -67,7 +58,7 @@ public class SumIT extends AbstractNumericTestCase {
|
|||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> nodePlugins() {
|
||||
return Arrays.asList(ExtractFieldScriptPlugin.class, FieldValueScriptPlugin.class);
|
||||
return Collections.singleton(MetricAggScriptPlugin.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -178,7 +169,7 @@ public class SumIT extends AbstractNumericTestCase {
|
|||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(sum("sum").field("value").script(
|
||||
new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", Collections.emptyMap())))
|
||||
new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, Collections.emptyMap())))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -195,7 +186,7 @@ public class SumIT extends AbstractNumericTestCase {
|
|||
params.put("increment", 1);
|
||||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(sum("sum").field("value").script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", params)))
|
||||
.addAggregation(sum("sum").field("value").script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, params)))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -211,7 +202,7 @@ public class SumIT extends AbstractNumericTestCase {
|
|||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(sum("sum").script(
|
||||
new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "value", Collections.emptyMap())))
|
||||
new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_FIELD_SCRIPT, Collections.singletonMap("field", "value"))))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -228,7 +219,7 @@ public class SumIT extends AbstractNumericTestCase {
|
|||
params.put("inc", 1);
|
||||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(sum("sum").script(new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "value", params)))
|
||||
.addAggregation(sum("sum").script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_FIELD_SCRIPT, params)))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -244,7 +235,7 @@ public class SumIT extends AbstractNumericTestCase {
|
|||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(sum("sum").script(
|
||||
new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "values", Collections.emptyMap())))
|
||||
new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_VALUES_FIELD_SCRIPT, Collections.emptyMap())))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -262,7 +253,7 @@ public class SumIT extends AbstractNumericTestCase {
|
|||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(
|
||||
sum("sum").script(new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "values", params)))
|
||||
sum("sum").script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_VALUES_FIELD_SCRIPT, params)))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -295,7 +286,7 @@ public class SumIT extends AbstractNumericTestCase {
|
|||
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||
.setQuery(matchAllQuery())
|
||||
.addAggregation(sum("sum").field("values").script(
|
||||
new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", Collections.emptyMap())))
|
||||
new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, Collections.emptyMap())))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -311,7 +302,8 @@ public class SumIT extends AbstractNumericTestCase {
|
|||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("increment", 1);
|
||||
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
|
||||
.addAggregation(sum("sum").field("values").script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", params)))
|
||||
.addAggregation(sum("sum").field("values")
|
||||
.script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, params)))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
@ -372,7 +364,7 @@ public class SumIT extends AbstractNumericTestCase {
|
|||
// Test that a request using a script does not get cached
|
||||
SearchResponse r = client().prepareSearch("cache_test_idx").setSize(0)
|
||||
.addAggregation(sum("foo").field("d").script(
|
||||
new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", Collections.emptyMap()))).get();
|
||||
new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, Collections.emptyMap()))).get();
|
||||
assertSearchResponse(r);
|
||||
|
||||
assertThat(client().admin().indices().prepareStats("cache_test_idx").setRequestCache(true).get().getTotal().getRequestCache()
|
||||
|
@ -390,207 +382,4 @@ public class SumIT extends AbstractNumericTestCase {
|
|||
assertThat(client().admin().indices().prepareStats("cache_test_idx").setRequestCache(true).get().getTotal().getRequestCache()
|
||||
.getMissCount(), equalTo(1L));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock plugin for the {@link ExtractFieldScriptEngine}
|
||||
*/
|
||||
public static class ExtractFieldScriptPlugin extends Plugin implements ScriptPlugin {
|
||||
@Override
|
||||
public ScriptEngine getScriptEngine(Settings settings) {
|
||||
return new ExtractFieldScriptEngine();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This mock script returns the field that is specified by name in the
|
||||
* script body
|
||||
*/
|
||||
public static class ExtractFieldScriptEngine implements ScriptEngine {
|
||||
|
||||
public static final String NAME = "extract_field";
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
|
||||
return scriptSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
|
||||
final long inc;
|
||||
if (vars == null || vars.containsKey("inc") == false) {
|
||||
inc = 0;
|
||||
} else {
|
||||
inc = ((Number) vars.get("inc")).longValue();
|
||||
}
|
||||
return new SearchScript() {
|
||||
|
||||
@Override
|
||||
public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
|
||||
|
||||
final LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
|
||||
|
||||
return new LeafSearchScript() {
|
||||
@Override
|
||||
public void setNextVar(String name, Object value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
String fieldName = (String) compiledScript.compiled();
|
||||
List<Long> values = new ArrayList<>();
|
||||
for (Object v : (List<?>) leafLookup.doc().get(fieldName)) {
|
||||
values.add(((Number) v).longValue() + inc);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScorer(Scorer scorer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(Map<String, Object> source) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocument(int doc) {
|
||||
if (leafLookup != null) {
|
||||
leafLookup.setDocument(doc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long runAsLong() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double runAsDouble() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsScores() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock plugin for the {@link FieldValueScriptEngine}
|
||||
*/
|
||||
public static class FieldValueScriptPlugin extends Plugin implements ScriptPlugin {
|
||||
@Override
|
||||
public ScriptEngine getScriptEngine(Settings settings) {
|
||||
return new FieldValueScriptEngine();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This mock script returns the field value and adds one to the returned
|
||||
* value
|
||||
*/
|
||||
public static class FieldValueScriptEngine implements ScriptEngine {
|
||||
|
||||
public static final String NAME = "field_value";
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
|
||||
return scriptSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
|
||||
final long inc;
|
||||
if (vars == null || vars.containsKey("inc") == false) {
|
||||
inc = 0;
|
||||
} else {
|
||||
inc = ((Number) vars.get("inc")).longValue();
|
||||
}
|
||||
return new SearchScript() {
|
||||
|
||||
private Map<String, Object> vars = new HashMap<>(2);
|
||||
|
||||
@Override
|
||||
public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
|
||||
|
||||
final LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
|
||||
|
||||
return new LeafSearchScript() {
|
||||
|
||||
@Override
|
||||
public void setNextVar(String name, Object value) {
|
||||
vars.put(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScorer(Scorer scorer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(Map<String, Object> source) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocument(int doc) {
|
||||
if (leafLookup != null) {
|
||||
leafLookup.setDocument(doc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long runAsLong() {
|
||||
return ((Number) vars.get("_value")).longValue() + inc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double runAsDouble() {
|
||||
return ((Number) vars.get("_value")).doubleValue() + inc;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsScores() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,36 +18,28 @@
|
|||
*/
|
||||
package org.elasticsearch.search.aggregations.metrics;
|
||||
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.search.Scorer;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.plugins.ScriptPlugin;
|
||||
import org.elasticsearch.script.CompiledScript;
|
||||
import org.elasticsearch.script.ExecutableScript;
|
||||
import org.elasticsearch.script.LeafSearchScript;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptEngine;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
import org.elasticsearch.search.aggregations.InternalAggregation;
|
||||
import org.elasticsearch.search.aggregations.bucket.global.Global;
|
||||
import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCount;
|
||||
import org.elasticsearch.search.lookup.LeafSearchLookup;
|
||||
import org.elasticsearch.search.lookup.SearchLookup;
|
||||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
|
||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.count;
|
||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
|
||||
import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.METRIC_SCRIPT_ENGINE;
|
||||
import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.SUM_FIELD_PARAMS_SCRIPT;
|
||||
import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.SUM_VALUES_FIELD_SCRIPT;
|
||||
import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.VALUE_FIELD_SCRIPT;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
|
||||
|
@ -75,7 +67,7 @@ public class ValueCountIT extends ESIntegTestCase {
|
|||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> nodePlugins() {
|
||||
return Collections.singletonList(FieldValueScriptPlugin.class);
|
||||
return Collections.singletonList(MetricAggScriptPlugin.class);
|
||||
}
|
||||
|
||||
public void testUnmapped() throws Exception {
|
||||
|
@ -158,7 +150,9 @@ public class ValueCountIT extends ESIntegTestCase {
|
|||
|
||||
public void testSingleValuedScript() throws Exception {
|
||||
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
|
||||
.addAggregation(count("count").script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "value", Collections.emptyMap()))).execute().actionGet();
|
||||
.addAggregation(count("count").script(
|
||||
new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_FIELD_SCRIPT, Collections.emptyMap())))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
||||
|
@ -170,7 +164,9 @@ public class ValueCountIT extends ESIntegTestCase {
|
|||
|
||||
public void testMultiValuedScript() throws Exception {
|
||||
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
|
||||
.addAggregation(count("count").script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "values", Collections.emptyMap()))).execute().actionGet();
|
||||
.addAggregation(count("count").script(
|
||||
new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_VALUES_FIELD_SCRIPT, Collections.emptyMap())))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
||||
|
@ -181,9 +177,10 @@ public class ValueCountIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void testSingleValuedScriptWithParams() throws Exception {
|
||||
Map<String, Object> params = Collections.singletonMap("s", "value");
|
||||
Map<String, Object> params = Collections.singletonMap("field", "value");
|
||||
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
|
||||
.addAggregation(count("count").script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", params))).execute().actionGet();
|
||||
.addAggregation(count("count").script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_FIELD_PARAMS_SCRIPT, params)))
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
||||
|
@ -194,9 +191,10 @@ public class ValueCountIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void testMultiValuedScriptWithParams() throws Exception {
|
||||
Map<String, Object> params = Collections.singletonMap("s", "values");
|
||||
Map<String, Object> params = Collections.singletonMap("field", "values");
|
||||
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
|
||||
.addAggregation(count("count").script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", params))).execute().actionGet();
|
||||
.addAggregation(count("count").script(
|
||||
new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_FIELD_PARAMS_SCRIPT, params))).execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 10);
|
||||
|
||||
|
@ -226,7 +224,7 @@ public class ValueCountIT extends ESIntegTestCase {
|
|||
// Test that a request using a script does not get cached
|
||||
SearchResponse r = client().prepareSearch("cache_test_idx").setSize(0)
|
||||
.addAggregation(count("foo").field("d").script(
|
||||
new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "value", Collections.emptyMap())))
|
||||
new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_FIELD_SCRIPT, Collections.emptyMap())))
|
||||
.get();
|
||||
assertSearchResponse(r);
|
||||
|
||||
|
@ -245,104 +243,4 @@ public class ValueCountIT extends ESIntegTestCase {
|
|||
assertThat(client().admin().indices().prepareStats("cache_test_idx").setRequestCache(true).get().getTotal().getRequestCache()
|
||||
.getMissCount(), equalTo(1L));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock plugin for the {@link FieldValueScriptEngine}
|
||||
*/
|
||||
public static class FieldValueScriptPlugin extends Plugin implements ScriptPlugin {
|
||||
@Override
|
||||
public ScriptEngine getScriptEngine(Settings settings) {
|
||||
return new FieldValueScriptEngine();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This mock script returns the field value. If the parameter map contains a parameter "s", the corresponding is used as field name.
|
||||
*/
|
||||
public static class FieldValueScriptEngine implements ScriptEngine {
|
||||
|
||||
public static final String NAME = "field_value";
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
|
||||
return scriptSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@Override
|
||||
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
|
||||
final String fieldNameParam;
|
||||
if (vars == null || vars.containsKey("s") == false) {
|
||||
fieldNameParam = null;
|
||||
} else {
|
||||
fieldNameParam = (String) vars.get("s");
|
||||
}
|
||||
|
||||
return new SearchScript() {
|
||||
private Map<String, Object> vars = new HashMap<>(2);
|
||||
|
||||
@Override
|
||||
public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
|
||||
|
||||
final LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
|
||||
|
||||
return new LeafSearchScript() {
|
||||
|
||||
@Override
|
||||
public void setNextVar(String name, Object value) {
|
||||
vars.put(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
String fieldName = (fieldNameParam != null) ? fieldNameParam : (String) compiledScript.compiled();
|
||||
return leafLookup.doc().get(fieldName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScorer(Scorer scorer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(Map<String, Object> source) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocument(int doc) {
|
||||
if (leafLookup != null) {
|
||||
leafLookup.setDocument(doc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long runAsLong() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double runAsDouble() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsScores() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,13 +50,10 @@ import org.elasticsearch.index.query.QueryShardContext;
|
|||
import org.elasticsearch.index.query.TermQueryBuilder;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
|
||||
import org.elasticsearch.script.CompiledScript;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.MockScriptEngine;
|
||||
import org.elasticsearch.script.ScriptContext;
|
||||
import org.elasticsearch.script.ScriptEngine;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.ScriptServiceTests.TestEngine;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
import org.elasticsearch.search.DocValueFormat;
|
||||
import org.elasticsearch.search.SearchModule;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
@ -67,6 +64,8 @@ import org.junit.BeforeClass;
|
|||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode;
|
||||
|
@ -86,13 +85,9 @@ public abstract class AbstractSortTestCase<T extends SortBuilder<T>> extends EST
|
|||
.put(Environment.PATH_HOME_SETTING.getKey(), createTempDir().toString())
|
||||
.put(Environment.PATH_CONF_SETTING.getKey(), genericConfigFolder)
|
||||
.build();
|
||||
ScriptEngine engine = new TestEngine();
|
||||
scriptService = new ScriptService(baseSettings, Collections.singletonMap(engine.getType(), engine), ScriptContext.BUILTINS) {
|
||||
@Override
|
||||
public CompiledScript compile(Script script, ScriptContext scriptContext) {
|
||||
return new CompiledScript(ScriptType.INLINE, "mockName", "test", script);
|
||||
}
|
||||
};
|
||||
Map<String, Function<Map<String, Object>, Object>> scripts = Collections.singletonMap("dummy", p -> null);
|
||||
ScriptEngine engine = new MockScriptEngine(MockScriptEngine.NAME, scripts);
|
||||
scriptService = new ScriptService(baseSettings, Collections.singletonMap(engine.getType(), engine), ScriptContext.BUILTINS);
|
||||
|
||||
SearchModule searchModule = new SearchModule(Settings.EMPTY, false, emptyList());
|
||||
namedWriteableRegistry = new NamedWriteableRegistry(searchModule.getNamedWriteables());
|
||||
|
|
|
@ -43,7 +43,7 @@ public class ScriptSortBuilderTests extends AbstractSortTestCase<ScriptSortBuild
|
|||
|
||||
public static ScriptSortBuilder randomScriptSortBuilder() {
|
||||
ScriptSortType type = randomBoolean() ? ScriptSortType.NUMBER : ScriptSortType.STRING;
|
||||
ScriptSortBuilder builder = new ScriptSortBuilder(mockScript(randomAlphaOfLengthBetween(5, 10)),
|
||||
ScriptSortBuilder builder = new ScriptSortBuilder(mockScript("dummy"),
|
||||
type);
|
||||
if (randomBoolean()) {
|
||||
builder.order(randomFrom(SortOrder.values()));
|
||||
|
|
|
@ -19,6 +19,19 @@
|
|||
|
||||
package org.elasticsearch.update;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.elasticsearch.ElasticsearchTimeoutException;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.ActionRequestValidationException;
|
||||
|
@ -37,30 +50,12 @@ import org.elasticsearch.common.xcontent.XContentFactory;
|
|||
import org.elasticsearch.index.MergePolicyConfig;
|
||||
import org.elasticsearch.index.engine.DocumentMissingException;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.plugins.ScriptPlugin;
|
||||
import org.elasticsearch.script.CompiledScript;
|
||||
import org.elasticsearch.script.ExecutableScript;
|
||||
import org.elasticsearch.script.MockScriptPlugin;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptEngine;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
import org.elasticsearch.search.lookup.SearchLookup;
|
||||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
import org.elasticsearch.test.InternalSettingsPlugin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertThrows;
|
||||
|
@ -71,247 +66,76 @@ import static org.hamcrest.Matchers.nullValue;
|
|||
|
||||
public class UpdateIT extends ESIntegTestCase {
|
||||
|
||||
public static class PutFieldValuesScriptPlugin extends Plugin implements ScriptPlugin {
|
||||
private static final String UPDATE_SCRIPTS = "update_scripts";
|
||||
private static final String PUT_VALUES_SCRIPT = "put_values";
|
||||
private static final String FIELD_INC_SCRIPT = "field_inc";
|
||||
private static final String UPSERT_SCRIPT = "scripted_upsert";
|
||||
private static final String EXTRACT_CTX_SCRIPT = "extract_ctx";
|
||||
|
||||
public static class UpdateScriptsPlugin extends MockScriptPlugin {
|
||||
@Override
|
||||
public ScriptEngine getScriptEngine(Settings settings) {
|
||||
return new PutFieldValuesScriptEngine();
|
||||
public String pluginScriptLang() {
|
||||
return UPDATE_SCRIPTS;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PutFieldValuesScriptEngine implements ScriptEngine {
|
||||
|
||||
public static final String NAME = "put_values";
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
|
||||
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
|
||||
scripts.put(PUT_VALUES_SCRIPT, vars -> {
|
||||
Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
|
||||
assertNotNull(ctx);
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return NAME;
|
||||
}
|
||||
Map<String, Object> params = new HashMap<>((Map<String, Object>) vars.get("params"));
|
||||
|
||||
@Override
|
||||
public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
|
||||
return new Object(); // unused
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> originalParams) {
|
||||
return new ExecutableScript() {
|
||||
|
||||
Map<String, Object> vars = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void setNextVar(String name, Object value) {
|
||||
vars.put(name, value);
|
||||
Map<String, Object> newCtx = (Map<String, Object>) params.remove("_ctx");
|
||||
if (newCtx != null) {
|
||||
assertFalse(newCtx.containsKey("_source"));
|
||||
ctx.putAll(newCtx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
|
||||
assertNotNull(ctx);
|
||||
Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
|
||||
source.putAll(params);
|
||||
|
||||
Map<String, Object> params = new HashMap<>(originalParams);
|
||||
return ctx;
|
||||
});
|
||||
scripts.put(FIELD_INC_SCRIPT, vars -> {
|
||||
Map<String, Object> params = (Map<String, Object>) vars.get("params");
|
||||
String fieldname = (String) vars.get("field");
|
||||
Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
|
||||
assertNotNull(ctx);
|
||||
Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
|
||||
Number currentValue = (Number) source.get(fieldname);
|
||||
Number inc = (Number) params.getOrDefault("inc", 1);
|
||||
source.put(fieldname, currentValue.longValue() + inc.longValue());
|
||||
return ctx;
|
||||
});
|
||||
scripts.put(UPSERT_SCRIPT, vars -> {
|
||||
Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
|
||||
assertNotNull(ctx);
|
||||
Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
|
||||
Number payment = (Number) vars.get("payment");
|
||||
Number oldBalance = (Number) source.get("balance");
|
||||
int deduction = "create".equals(ctx.get("op")) ? payment.intValue() / 2 : payment.intValue();
|
||||
source.put("balance", oldBalance.intValue() - deduction);
|
||||
return ctx;
|
||||
});
|
||||
scripts.put(EXTRACT_CTX_SCRIPT, vars -> {
|
||||
Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
|
||||
assertNotNull(ctx);
|
||||
|
||||
Map<String, Object> newCtx = (Map<String, Object>) params.remove("_ctx");
|
||||
if (newCtx != null) {
|
||||
assertFalse(newCtx.containsKey("_source"));
|
||||
ctx.putAll(newCtx);
|
||||
}
|
||||
Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
|
||||
Map<String, Object> ctxWithoutSource = new HashMap<>(ctx);
|
||||
ctxWithoutSource.remove("_source");
|
||||
source.put("update_context", ctxWithoutSource);
|
||||
|
||||
Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
|
||||
source.putAll(params);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
public static class FieldIncrementScriptPlugin extends Plugin implements ScriptPlugin {
|
||||
@Override
|
||||
public ScriptEngine getScriptEngine(Settings settings) {
|
||||
return new FieldIncrementScriptEngine();
|
||||
}
|
||||
}
|
||||
|
||||
public static class FieldIncrementScriptEngine implements ScriptEngine {
|
||||
|
||||
public static final String NAME = "field_inc";
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
|
||||
return scriptSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
|
||||
final String field = (String) compiledScript.compiled();
|
||||
return new ExecutableScript() {
|
||||
|
||||
Map<String, Object> vars = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void setNextVar(String name, Object value) {
|
||||
vars.put(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
|
||||
assertNotNull(ctx);
|
||||
Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
|
||||
Number currentValue = (Number) source.get(field);
|
||||
Number inc = params == null ? 1L : (Number) params.getOrDefault("inc", 1);
|
||||
source.put(field, currentValue.longValue() + inc.longValue());
|
||||
return ctx;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ScriptedUpsertScriptPlugin extends Plugin implements ScriptPlugin {
|
||||
@Override
|
||||
public ScriptEngine getScriptEngine(Settings settings) {
|
||||
return new ScriptedUpsertScriptEngine();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ScriptedUpsertScriptEngine implements ScriptEngine {
|
||||
|
||||
public static final String NAME = "scripted_upsert";
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
|
||||
return new Object(); // unused
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
|
||||
return new ExecutableScript() {
|
||||
|
||||
Map<String, Object> vars = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void setNextVar(String name, Object value) {
|
||||
vars.put(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
|
||||
assertNotNull(ctx);
|
||||
Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
|
||||
Number payment = (Number) params.get("payment");
|
||||
Number oldBalance = (Number) source.get("balance");
|
||||
int deduction = "create".equals(ctx.get("op")) ? payment.intValue() / 2 : payment.intValue();
|
||||
source.put("balance", oldBalance.intValue() - deduction);
|
||||
return ctx;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExtractContextInSourceScriptPlugin extends Plugin implements ScriptPlugin {
|
||||
@Override
|
||||
public ScriptEngine getScriptEngine(Settings settings) {
|
||||
return new ExtractContextInSourceScriptEngine();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExtractContextInSourceScriptEngine implements ScriptEngine {
|
||||
|
||||
public static final String NAME = "extract_ctx";
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
|
||||
return new Object(); // unused
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
|
||||
return new ExecutableScript() {
|
||||
|
||||
Map<String, Object> vars = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void setNextVar(String name, Object value) {
|
||||
vars.put(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
|
||||
assertNotNull(ctx);
|
||||
|
||||
Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
|
||||
Map<String, Object> ctxWithoutSource = new HashMap<>(ctx);
|
||||
ctxWithoutSource.remove("_source");
|
||||
source.put("update_context", ctxWithoutSource);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
|
||||
throw new UnsupportedOperationException();
|
||||
return ctx;
|
||||
});
|
||||
return scripts;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> nodePlugins() {
|
||||
return Arrays.asList(
|
||||
PutFieldValuesScriptPlugin.class,
|
||||
FieldIncrementScriptPlugin.class,
|
||||
ScriptedUpsertScriptPlugin.class,
|
||||
ExtractContextInSourceScriptPlugin.class,
|
||||
InternalSettingsPlugin.class
|
||||
);
|
||||
return Arrays.asList(UpdateScriptsPlugin.class, InternalSettingsPlugin.class);
|
||||
}
|
||||
|
||||
private void createTestIndex() throws Exception {
|
||||
|
@ -323,10 +147,11 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
public void testUpsert() throws Exception {
|
||||
createTestIndex();
|
||||
ensureGreen();
|
||||
Script fieldIncScript = new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field"));
|
||||
|
||||
UpdateResponse updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setUpsert(XContentFactory.jsonBuilder().startObject().field("field", 1).endObject())
|
||||
.setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
|
||||
.setScript(fieldIncScript)
|
||||
.execute().actionGet();
|
||||
assertEquals(DocWriteResponse.Result.CREATED, updateResponse.getResult());
|
||||
assertThat(updateResponse.getIndex(), equalTo("test"));
|
||||
|
@ -338,7 +163,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
|
||||
updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setUpsert(XContentFactory.jsonBuilder().startObject().field("field", 1).endObject())
|
||||
.setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
|
||||
.setScript(fieldIncScript)
|
||||
.execute().actionGet();
|
||||
assertEquals(DocWriteResponse.Result.UPDATED, updateResponse.getResult());
|
||||
assertThat(updateResponse.getIndex(), equalTo("test"));
|
||||
|
@ -367,7 +192,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
UpdateResponse updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setUpsert(XContentFactory.jsonBuilder().startObject().field("balance", openingBalance).endObject())
|
||||
.setScriptedUpsert(true)
|
||||
.setScript(new Script(ScriptType.INLINE, "scripted_upsert", "", params))
|
||||
.setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, UPSERT_SCRIPT, params))
|
||||
.execute().actionGet();
|
||||
assertEquals(DocWriteResponse.Result.CREATED, updateResponse.getResult());
|
||||
assertThat(updateResponse.getIndex(), equalTo("test"));
|
||||
|
@ -381,7 +206,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setUpsert(XContentFactory.jsonBuilder().startObject().field("balance", openingBalance).endObject())
|
||||
.setScriptedUpsert(true)
|
||||
.setScript(new Script(ScriptType.INLINE, "scripted_upsert", "", params))
|
||||
.setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, UPSERT_SCRIPT, params))
|
||||
.execute().actionGet();
|
||||
assertEquals(DocWriteResponse.Result.UPDATED, updateResponse.getResult());
|
||||
assertThat(updateResponse.getIndex(), equalTo("test"));
|
||||
|
@ -425,7 +250,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
|
||||
UpdateResponse updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setUpsert(XContentFactory.jsonBuilder().startObject().field("bar", "baz").endObject())
|
||||
.setScript(new Script(ScriptType.INLINE, "put_values", "", Collections.singletonMap("extra", "foo")))
|
||||
.setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, PUT_VALUES_SCRIPT, Collections.singletonMap("extra", "foo")))
|
||||
.setFetchSource(true)
|
||||
.execute().actionGet();
|
||||
|
||||
|
@ -437,7 +262,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
|
||||
updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setUpsert(XContentFactory.jsonBuilder().startObject().field("bar", "baz").endObject())
|
||||
.setScript(new Script(ScriptType.INLINE, "put_values", "", Collections.singletonMap("extra", "foo")))
|
||||
.setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, PUT_VALUES_SCRIPT, Collections.singletonMap("extra", "foo")))
|
||||
.setFields("_source")
|
||||
.execute().actionGet();
|
||||
|
||||
|
@ -451,7 +276,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
public void testIndexAutoCreation() throws Exception {
|
||||
UpdateResponse updateResponse = client().prepareUpdate("test", "type1", "1")
|
||||
.setUpsert(XContentFactory.jsonBuilder().startObject().field("bar", "baz").endObject())
|
||||
.setScript(new Script(ScriptType.INLINE, "put_values", "", Collections.singletonMap("extra", "foo")))
|
||||
.setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, PUT_VALUES_SCRIPT, Collections.singletonMap("extra", "foo")))
|
||||
.setFetchSource(true)
|
||||
.execute().actionGet();
|
||||
|
||||
|
@ -466,9 +291,9 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
createTestIndex();
|
||||
ensureGreen();
|
||||
|
||||
Script fieldIncScript = new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field"));
|
||||
try {
|
||||
client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap())).execute().actionGet();
|
||||
client().prepareUpdate(indexOrAlias(), "type1", "1").setScript(fieldIncScript).execute().actionGet();
|
||||
fail();
|
||||
} catch (DocumentMissingException e) {
|
||||
// all is well
|
||||
|
@ -477,7 +302,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
client().prepareIndex("test", "type1", "1").setSource("field", 1).execute().actionGet();
|
||||
|
||||
UpdateResponse updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap())).execute().actionGet();
|
||||
.setScript(fieldIncScript).execute().actionGet();
|
||||
assertThat(updateResponse.getVersion(), equalTo(2L));
|
||||
assertEquals(DocWriteResponse.Result.UPDATED, updateResponse.getResult());
|
||||
assertThat(updateResponse.getIndex(), equalTo("test"));
|
||||
|
@ -489,8 +314,9 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("inc", 3);
|
||||
params.put("field", "field");
|
||||
updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setScript(new Script(ScriptType.INLINE, "field_inc", "field", params)).execute().actionGet();
|
||||
.setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, params)).execute().actionGet();
|
||||
assertThat(updateResponse.getVersion(), equalTo(3L));
|
||||
assertEquals(DocWriteResponse.Result.UPDATED, updateResponse.getResult());
|
||||
assertThat(updateResponse.getIndex(), equalTo("test"));
|
||||
|
@ -502,7 +328,8 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
|
||||
// check noop
|
||||
updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setScript(new Script(ScriptType.INLINE, "put_values", "", Collections.singletonMap("_ctx", Collections.singletonMap("op", "none")))).execute().actionGet();
|
||||
.setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, PUT_VALUES_SCRIPT,
|
||||
Collections.singletonMap("_ctx", Collections.singletonMap("op", "none")))).execute().actionGet();
|
||||
assertThat(updateResponse.getVersion(), equalTo(3L));
|
||||
assertEquals(DocWriteResponse.Result.NOOP, updateResponse.getResult());
|
||||
assertThat(updateResponse.getIndex(), equalTo("test"));
|
||||
|
@ -514,7 +341,8 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
|
||||
// check delete
|
||||
updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setScript(new Script(ScriptType.INLINE, "put_values", "", Collections.singletonMap("_ctx", Collections.singletonMap("op", "delete")))).execute().actionGet();
|
||||
.setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, PUT_VALUES_SCRIPT,
|
||||
Collections.singletonMap("_ctx", Collections.singletonMap("op", "delete")))).execute().actionGet();
|
||||
assertThat(updateResponse.getVersion(), equalTo(4L));
|
||||
assertEquals(DocWriteResponse.Result.DELETED, updateResponse.getResult());
|
||||
assertThat(updateResponse.getIndex(), equalTo("test"));
|
||||
|
@ -527,7 +355,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
// check fields parameter
|
||||
client().prepareIndex("test", "type1", "1").setSource("field", 1).execute().actionGet();
|
||||
updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
|
||||
.setScript(fieldIncScript)
|
||||
.setFields("field")
|
||||
.setFetchSource(true)
|
||||
.execute().actionGet();
|
||||
|
@ -540,7 +368,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
// check _source parameter
|
||||
client().prepareIndex("test", "type1", "1").setSource("field1", 1, "field2", 2).execute().actionGet();
|
||||
updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setScript(new Script(ScriptType.INLINE, "field_inc", "field1", Collections.emptyMap()))
|
||||
.setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field1")))
|
||||
.setFetchSource("field1", "field2")
|
||||
.get();
|
||||
assertThat(updateResponse.getIndex(), equalTo("test"));
|
||||
|
@ -600,10 +428,11 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
createTestIndex();
|
||||
ensureGreen();
|
||||
|
||||
Script fieldIncScript = new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field"));
|
||||
try {
|
||||
client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setDoc(XContentFactory.jsonBuilder().startObject().field("field", 1).endObject())
|
||||
.setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
|
||||
.setScript(fieldIncScript)
|
||||
.execute().actionGet();
|
||||
fail("Should have thrown ActionRequestValidationException");
|
||||
} catch (ActionRequestValidationException e) {
|
||||
|
@ -616,9 +445,10 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
public void testUpdateRequestWithScriptAndShouldUpsertDoc() throws Exception {
|
||||
createTestIndex();
|
||||
ensureGreen();
|
||||
Script fieldIncScript = new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field"));
|
||||
try {
|
||||
client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
|
||||
.setScript(fieldIncScript)
|
||||
.setDocAsUpsert(true)
|
||||
.execute().actionGet();
|
||||
fail("Should have thrown ActionRequestValidationException");
|
||||
|
@ -667,7 +497,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
// Update the first object and note context variables values
|
||||
UpdateResponse updateResponse = client().prepareUpdate("test", "subtype1", "id1")
|
||||
.setRouting("routing1")
|
||||
.setScript(new Script(ScriptType.INLINE, "extract_ctx", "", Collections.emptyMap()))
|
||||
.setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, EXTRACT_CTX_SCRIPT, Collections.emptyMap()))
|
||||
.execute().actionGet();
|
||||
|
||||
assertEquals(2, updateResponse.getVersion());
|
||||
|
@ -683,7 +513,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
|
||||
// Idem with the second object
|
||||
updateResponse = client().prepareUpdate("test", "type1", "parentId1")
|
||||
.setScript(new Script(ScriptType.INLINE, "extract_ctx", "", Collections.emptyMap()))
|
||||
.setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, EXTRACT_CTX_SCRIPT, Collections.emptyMap()))
|
||||
.execute().actionGet();
|
||||
|
||||
assertEquals(2, updateResponse.getVersion());
|
||||
|
@ -710,6 +540,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
final int numberOfUpdatesPerThread = scaledRandomIntBetween(100, 500);
|
||||
final List<Exception> failures = new CopyOnWriteArrayList<>();
|
||||
|
||||
Script fieldIncScript = new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field"));
|
||||
for (int i = 0; i < numberOfThreads; i++) {
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
|
@ -722,13 +553,13 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
}
|
||||
if (useBulkApi) {
|
||||
UpdateRequestBuilder updateRequestBuilder = client().prepareUpdate(indexOrAlias(), "type1", Integer.toString(i))
|
||||
.setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
|
||||
.setScript(fieldIncScript)
|
||||
.setRetryOnConflict(Integer.MAX_VALUE)
|
||||
.setUpsert(jsonBuilder().startObject().field("field", 1).endObject());
|
||||
client().prepareBulk().add(updateRequestBuilder).execute().actionGet();
|
||||
} else {
|
||||
client().prepareUpdate(indexOrAlias(), "type1", Integer.toString(i))
|
||||
.setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
|
||||
.setScript(fieldIncScript)
|
||||
.setRetryOnConflict(Integer.MAX_VALUE)
|
||||
.setUpsert(jsonBuilder().startObject().field("field", 1).endObject())
|
||||
.execute().actionGet();
|
||||
|
@ -773,6 +604,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
.setSettings(Settings.builder().put(MergePolicyConfig.INDEX_MERGE_ENABLED, false)));
|
||||
ensureGreen();
|
||||
|
||||
Script fieldIncScript = new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field"));
|
||||
final int numberOfThreads = scaledRandomIntBetween(3,5);
|
||||
final int numberOfIdsPerThread = scaledRandomIntBetween(3,10);
|
||||
final int numberOfUpdatesPerId = scaledRandomIntBetween(10,100);
|
||||
|
@ -848,7 +680,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
updateRequestsOutstanding.acquire();
|
||||
try {
|
||||
UpdateRequest ur = client().prepareUpdate("test", "type1", Integer.toString(j))
|
||||
.setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
|
||||
.setScript(fieldIncScript)
|
||||
.setRetryOnConflict(retryOnConflict)
|
||||
.setUpsert(jsonBuilder().startObject().field("field", 1).endObject())
|
||||
.request();
|
||||
|
@ -948,7 +780,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
//All the previous operations should be complete or failed at this point
|
||||
for (int i = 0; i < numberOfIdsPerThread; ++i) {
|
||||
UpdateResponse ur = client().prepareUpdate("test", "type1", Integer.toString(i))
|
||||
.setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
|
||||
.setScript(fieldIncScript)
|
||||
.setRetryOnConflict(Integer.MAX_VALUE)
|
||||
.setUpsert(jsonBuilder().startObject().field("field", 1).endObject())
|
||||
.execute().actionGet();
|
||||
|
|
|
@ -98,13 +98,13 @@ public class MockScriptEngine implements ScriptEngine {
|
|||
|
||||
private final String name;
|
||||
private final String source;
|
||||
private final Map<String, String> params;
|
||||
private final Map<String, String> options;
|
||||
private final Function<Map<String, Object>, Object> script;
|
||||
|
||||
public MockCompiledScript(String name, Map<String, String> params, String source, Function<Map<String, Object>, Object> script) {
|
||||
public MockCompiledScript(String name, Map<String, String> options, String source, Function<Map<String, Object>, Object> script) {
|
||||
this.name = name;
|
||||
this.source = source;
|
||||
this.params = params;
|
||||
this.options = options;
|
||||
this.script = script;
|
||||
}
|
||||
|
||||
|
@ -112,24 +112,28 @@ public class MockScriptEngine implements ScriptEngine {
|
|||
return name;
|
||||
}
|
||||
|
||||
public ExecutableScript createExecutableScript(Map<String, Object> vars) {
|
||||
public ExecutableScript createExecutableScript(Map<String, Object> params) {
|
||||
Map<String, Object> context = new HashMap<>();
|
||||
if (params != null) {
|
||||
context.putAll(params);
|
||||
if (options != null) {
|
||||
context.putAll(options); // TODO: remove this once scripts know to look for options under options key
|
||||
context.put("options", options);
|
||||
}
|
||||
if (vars != null) {
|
||||
context.putAll(vars);
|
||||
if (params != null) {
|
||||
context.putAll(params); // TODO: remove this once scripts know to look for params under params key
|
||||
context.put("params", params);
|
||||
}
|
||||
return new MockExecutableScript(context, script != null ? script : ctx -> source);
|
||||
}
|
||||
|
||||
public SearchScript createSearchScript(Map<String, Object> vars, SearchLookup lookup) {
|
||||
public SearchScript createSearchScript(Map<String, Object> params, SearchLookup lookup) {
|
||||
Map<String, Object> context = new HashMap<>();
|
||||
if (params != null) {
|
||||
context.putAll(params);
|
||||
if (options != null) {
|
||||
context.putAll(options); // TODO: remove this once scripts know to look for options under options key
|
||||
context.put("options", options);
|
||||
}
|
||||
if (vars != null) {
|
||||
context.putAll(vars);
|
||||
if (params != null) {
|
||||
context.putAll(params); // TODO: remove this once scripts know to look for params under params key
|
||||
context.put("params", params);
|
||||
}
|
||||
return new MockSearchScript(lookup, context, script != null ? script : ctx -> source);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue