From 7400cbe5fdafeb20ef0cf3cefa9c47053b2055de Mon Sep 17 00:00:00 2001 From: Adrien Grand Date: Mon, 5 Oct 2015 18:49:53 +0200 Subject: [PATCH] Remove UpdateTests' dependency on groovy. This test had to be moved to lang-groovy when groovy has been made a plugin. I refactored it a bit to use mock plugins instead so that groovy is not necessary anymore and it can come back to core. --- .../org/elasticsearch/update/UpdateIT.java | 518 +++++++++++++++--- .../messy/tests/package-info.java | 1 - 2 files changed, 439 insertions(+), 80 deletions(-) rename plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/UpdateTests.java => core/src/test/java/org/elasticsearch/update/UpdateIT.java (69%) diff --git a/plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/UpdateTests.java b/core/src/test/java/org/elasticsearch/update/UpdateIT.java similarity index 69% rename from plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/UpdateTests.java rename to core/src/test/java/org/elasticsearch/update/UpdateIT.java index dc76eda92a9..8c62d97349a 100644 --- a/plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/UpdateTests.java +++ b/core/src/test/java/org/elasticsearch/update/UpdateIT.java @@ -17,7 +17,7 @@ * under the License. */ -package org.elasticsearch.messy.tests; +package org.elasticsearch.update; import org.elasticsearch.ElasticsearchTimeoutException; import org.elasticsearch.action.ActionListener; @@ -38,12 +38,18 @@ import org.elasticsearch.index.engine.DocumentMissingException; import org.elasticsearch.index.engine.VersionConflictEngineException; import org.elasticsearch.index.shard.MergePolicyConfig; import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.script.CompiledScript; +import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.Script; +import org.elasticsearch.script.ScriptEngineService; +import org.elasticsearch.script.ScriptModule; import org.elasticsearch.script.ScriptService; -import org.elasticsearch.script.groovy.GroovyPlugin; +import org.elasticsearch.script.SearchScript; +import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.test.ESIntegTestCase; import org.junit.Test; +import java.io.IOException; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; @@ -55,13 +61,389 @@ import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcke import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertThrows; import static org.hamcrest.Matchers.*; -public class UpdateTests extends ESIntegTestCase { +public class UpdateIT extends ESIntegTestCase { + + public static class PutFieldValuesScriptPlugin extends Plugin { + + public PutFieldValuesScriptPlugin() { + } + + @Override + public String name() { + return PutFieldValuesScriptEngine.NAME; + } + + @Override + public String description() { + return "Mock script engine for " + UpdateIT.class; + } + + public void onModule(ScriptModule module) { + module.addScriptEngine(PutFieldValuesScriptEngine.class); + } + + } + + public static class PutFieldValuesScriptEngine implements ScriptEngineService { + + public static final String NAME = "put_values"; + + @Override + public void close() throws IOException { + } + + @Override + public String[] types() { + return new String[] { NAME }; + } + + @Override + public String[] extensions() { + return types(); + } + + @Override + public boolean sandboxed() { + return true; + } + + @Override + public Object compile(String script) { + return new Object(); // unused + } + + @Override + public ExecutableScript executable(CompiledScript compiledScript, Map originalParams) { + return new ExecutableScript() { + + Map vars = new HashMap<>(); + + @Override + public void setNextVar(String name, Object value) { + vars.put(name, value); + } + + @Override + public Object run() { + Map ctx = (Map) vars.get("ctx"); + assertNotNull(ctx); + + Map params = new HashMap<>(originalParams); + + Map newCtx = (Map) params.remove("_ctx"); + if (newCtx != null) { + assertFalse(newCtx.containsKey("_source")); + ctx.putAll(newCtx); + } + + Map source = (Map) ctx.get("_source"); + source.putAll(params); + + return ctx; + } + + @Override + public Object unwrap(Object value) { + return value; + } + + }; + } + + @Override + public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map vars) { + throw new UnsupportedOperationException(); + } + + @Override + public void scriptRemoved(CompiledScript script) { + } + + } + + public static class FieldIncrementScriptPlugin extends Plugin { + + public FieldIncrementScriptPlugin() { + } + + @Override + public String name() { + return FieldIncrementScriptEngine.NAME; + } + + @Override + public String description() { + return "Mock script engine for " + UpdateIT.class; + } + + public void onModule(ScriptModule module) { + module.addScriptEngine(FieldIncrementScriptEngine.class); + } + + } + + public static class FieldIncrementScriptEngine implements ScriptEngineService { + + public static final String NAME = "field_inc"; + + @Override + public void close() throws IOException { + } + + @Override + public String[] types() { + return new String[] { NAME }; + } + + @Override + public String[] extensions() { + return types(); + } + + @Override + public boolean sandboxed() { + return true; + } + + @Override + public Object compile(String script) { + return script; + } + + @Override + public ExecutableScript executable(CompiledScript compiledScript, Map params) { + final String field = (String) compiledScript.compiled(); + return new ExecutableScript() { + + Map vars = new HashMap<>(); + + @Override + public void setNextVar(String name, Object value) { + vars.put(name, value); + } + + @Override + public Object run() { + Map ctx = (Map) vars.get("ctx"); + assertNotNull(ctx); + Map source = (Map) 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 Object unwrap(Object value) { + return value; + } + + }; + } + + @Override + public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map vars) { + throw new UnsupportedOperationException(); + } + + @Override + public void scriptRemoved(CompiledScript script) { + } + + } + + public static class ScriptedUpsertScriptPlugin extends Plugin { + + public ScriptedUpsertScriptPlugin() { + } + + @Override + public String name() { + return ScriptedUpsertScriptEngine.NAME; + } + + @Override + public String description() { + return "Mock script engine for " + UpdateIT.class + ".testScriptedUpsert"; + } + + public void onModule(ScriptModule module) { + module.addScriptEngine(ScriptedUpsertScriptEngine.class); + } + + } + + public static class ScriptedUpsertScriptEngine implements ScriptEngineService { + + public static final String NAME = "scripted_upsert"; + + @Override + public void close() throws IOException { + } + + @Override + public String[] types() { + return new String[] { NAME }; + } + + @Override + public String[] extensions() { + return types(); + } + + @Override + public boolean sandboxed() { + return true; + } + + @Override + public Object compile(String script) { + return new Object(); // unused + } + + @Override + public ExecutableScript executable(CompiledScript compiledScript, Map params) { + return new ExecutableScript() { + + Map vars = new HashMap<>(); + + @Override + public void setNextVar(String name, Object value) { + vars.put(name, value); + } + + @Override + public Object run() { + Map ctx = (Map) vars.get("ctx"); + assertNotNull(ctx); + Map source = (Map) 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 Object unwrap(Object value) { + return value; + } + + }; + } + + @Override + public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map vars) { + throw new UnsupportedOperationException(); + } + + @Override + public void scriptRemoved(CompiledScript script) { + } + + } + + public static class ExtractContextInSourceScriptPlugin extends Plugin { + + public ExtractContextInSourceScriptPlugin() { + } + + @Override + public String name() { + return ExtractContextInSourceScriptEngine.NAME; + } + + @Override + public String description() { + return "Mock script engine for " + UpdateIT.class; + } + + public void onModule(ScriptModule module) { + module.addScriptEngine(ExtractContextInSourceScriptEngine.class); + } + + } + + public static class ExtractContextInSourceScriptEngine implements ScriptEngineService { + + public static final String NAME = "extract_ctx"; + + @Override + public void close() throws IOException { + } + + @Override + public String[] types() { + return new String[] { NAME }; + } + + @Override + public String[] extensions() { + return types(); + } + + @Override + public boolean sandboxed() { + return true; + } + + @Override + public Object compile(String script) { + return new Object(); // unused + } + + @Override + public ExecutableScript executable(CompiledScript compiledScript, Map params) { + return new ExecutableScript() { + + Map vars = new HashMap<>(); + + @Override + public void setNextVar(String name, Object value) { + vars.put(name, value); + } + + @Override + public Object run() { + Map ctx = (Map) vars.get("ctx"); + assertNotNull(ctx); + + Map source = (Map) ctx.get("_source"); + Map ctxWithoutSource = new HashMap<>(ctx); + ctxWithoutSource.remove("_source"); + source.put("update_context", ctxWithoutSource); + + return ctx; + } + + @Override + public Object unwrap(Object value) { + return value; + } + + }; + } + + @Override + public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map vars) { + throw new UnsupportedOperationException(); + } + + @Override + public void scriptRemoved(CompiledScript script) { + } + + } @Override protected Collection> nodePlugins() { - return Collections.singleton(GroovyPlugin.class); + return Arrays.asList( + PutFieldValuesScriptPlugin.class, + FieldIncrementScriptPlugin.class, + ScriptedUpsertScriptPlugin.class, + ExtractContextInSourceScriptPlugin.class); } - + private void createTestIndex() throws Exception { logger.info("--> creating index test"); @@ -82,7 +464,7 @@ public class UpdateTests extends ESIntegTestCase { UpdateResponse updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1") .setUpsert(XContentFactory.jsonBuilder().startObject().field("field", 1).endObject()) - .setScript(new Script("ctx._source.field += 1", ScriptService.ScriptType.INLINE, null, null)) + .setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", null)) .execute().actionGet(); assertTrue(updateResponse.isCreated()); assertThat(updateResponse.getIndex(), equalTo("test")); @@ -94,7 +476,7 @@ public class UpdateTests extends ESIntegTestCase { updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1") .setUpsert(XContentFactory.jsonBuilder().startObject().field("field", 1).endObject()) - .setScript(new Script("ctx._source.field += 1", ScriptService.ScriptType.INLINE, null, null)) + .setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", null)) .execute().actionGet(); assertFalse(updateResponse.isCreated()); assertThat(updateResponse.getIndex(), equalTo("test")); @@ -109,14 +491,11 @@ public class UpdateTests extends ESIntegTestCase { public void testScriptedUpsert() throws Exception { createTestIndex(); ensureGreen(); - - // Script logic is + + // Script logic is // 1) New accounts take balance from "balance" in upsert doc and first payment is charged at 50% // 2) Existing accounts subtract full payment from balance stored in elasticsearch - - String script="int oldBalance=ctx._source.balance;"+ - "int deduction=ctx.op == \"create\" ? (payment/2) : payment;"+ - "ctx._source.balance=oldBalance-deduction;"; + int openingBalance=10; Map params = new HashMap<>(); @@ -127,7 +506,7 @@ public class UpdateTests extends ESIntegTestCase { UpdateResponse updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1") .setUpsert(XContentFactory.jsonBuilder().startObject().field("balance", openingBalance).endObject()) .setScriptedUpsert(true) -.setScript(new Script(script, ScriptService.ScriptType.INLINE, null, params)) + .setScript(new Script("", ScriptService.ScriptType.INLINE, "scripted_upsert", params)) .execute().actionGet(); assertTrue(updateResponse.isCreated()); assertThat(updateResponse.getIndex(), equalTo("test")); @@ -137,11 +516,11 @@ public class UpdateTests extends ESIntegTestCase { assertThat(getResponse.getSourceAsMap().get("balance").toString(), equalTo("9")); } - // Now pay money for an existing account where balance is stored in es + // Now pay money for an existing account where balance is stored in es updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1") .setUpsert(XContentFactory.jsonBuilder().startObject().field("balance", openingBalance).endObject()) .setScriptedUpsert(true) -.setScript(new Script(script, ScriptService.ScriptType.INLINE, null, params)) + .setScript(new Script("", ScriptService.ScriptType.INLINE, "scripted_upsert", params)) .execute().actionGet(); assertFalse(updateResponse.isCreated()); assertThat(updateResponse.getIndex(), equalTo("test")); @@ -188,7 +567,7 @@ public class UpdateTests extends ESIntegTestCase { UpdateResponse updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1") .setUpsert(XContentFactory.jsonBuilder().startObject().field("bar", "baz").endObject()) - .setScript(new Script("ctx._source.extra = \"foo\"", ScriptService.ScriptType.INLINE, null, null)) + .setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("extra", "foo"))) .setFields("_source") .execute().actionGet(); @@ -200,7 +579,7 @@ public class UpdateTests extends ESIntegTestCase { updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1") .setUpsert(XContentFactory.jsonBuilder().startObject().field("bar", "baz").endObject()) - .setScript(new Script("ctx._source.extra = \"foo\"", ScriptService.ScriptType.INLINE, null, null)) + .setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("extra", "foo"))) .setFields("_source") .execute().actionGet(); @@ -219,24 +598,24 @@ public class UpdateTests extends ESIntegTestCase { index("test", "type", "1", "text", "value"); // version is now 1 assertThrows(client().prepareUpdate(indexOrAlias(), "type", "1") - .setScript(new Script("ctx._source.text = 'v2'", ScriptService.ScriptType.INLINE, null, null)).setVersion(2) + .setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("text", "v2"))).setVersion(2) .execute(), VersionConflictEngineException.class); client().prepareUpdate(indexOrAlias(), "type", "1") - .setScript(new Script("ctx._source.text = 'v2'", ScriptService.ScriptType.INLINE, null, null)).setVersion(1).get(); + .setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("text", "v2"))).setVersion(1).get(); assertThat(client().prepareGet("test", "type", "1").get().getVersion(), equalTo(2l)); // and again with a higher version.. client().prepareUpdate(indexOrAlias(), "type", "1") - .setScript(new Script("ctx._source.text = 'v3'", ScriptService.ScriptType.INLINE, null, null)).setVersion(2).get(); + .setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("text", "v3"))).setVersion(2).get(); assertThat(client().prepareGet("test", "type", "1").get().getVersion(), equalTo(3l)); // after delete client().prepareDelete("test", "type", "1").get(); assertThrows(client().prepareUpdate("test", "type", "1") - .setScript(new Script("ctx._source.text = 'v2'", ScriptService.ScriptType.INLINE, null, null)).setVersion(3) + .setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("text", "v2"))).setVersion(3) .execute(), DocumentMissingException.class); @@ -244,14 +623,14 @@ public class UpdateTests extends ESIntegTestCase { client().prepareIndex("test", "type", "2").setSource("text", "value").setVersion(10).setVersionType(VersionType.EXTERNAL).get(); assertThrows(client().prepareUpdate(indexOrAlias(), "type", "2") - .setScript(new Script("ctx._source.text = 'v2'", ScriptService.ScriptType.INLINE, null, null)).setVersion(2) + .setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("text", "v2"))).setVersion(2) .setVersionType(VersionType.EXTERNAL).execute(), ActionRequestValidationException.class); // With force version client().prepareUpdate(indexOrAlias(), "type", "2") - .setScript(new Script("ctx._source.text = 'v10'", ScriptService.ScriptType.INLINE, null, null)) + .setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("text", "v10"))) .setVersion(10).setVersionType(VersionType.FORCE).get(); GetResponse get = get("test", "type", "2"); @@ -262,13 +641,12 @@ public class UpdateTests extends ESIntegTestCase { // With internal versions, tt means "if object is there with version X, update it or explode. If it is not there, index. client().prepareUpdate(indexOrAlias(), "type", "3") - .setScript(new Script("ctx._source.text = 'v2'", ScriptService.ScriptType.INLINE, null, null)) + .setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("text", "v2"))) .setVersion(10).setUpsert("{ \"text\": \"v0\" }").get(); get = get("test", "type", "3"); assertThat(get.getVersion(), equalTo(1l)); assertThat((String) get.getSource().get("text"), equalTo("v0")); - // retry on conflict is rejected: assertThrows(client().prepareUpdate(indexOrAlias(), "type", "1").setVersion(10).setRetryOnConflict(5), ActionRequestValidationException.class); } @@ -277,7 +655,7 @@ public class UpdateTests 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("ctx._source.extra = \"foo\"", ScriptService.ScriptType.INLINE, null, null)) + .setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("extra", "foo"))) .setFields("_source") .execute().actionGet(); @@ -295,7 +673,7 @@ public class UpdateTests extends ESIntegTestCase { try { client().prepareUpdate(indexOrAlias(), "type1", "1") - .setScript(new Script("ctx._source.field++", ScriptService.ScriptType.INLINE, null, null)).execute().actionGet(); + .setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", null)).execute().actionGet(); fail(); } catch (DocumentMissingException e) { // all is well @@ -304,7 +682,7 @@ public class UpdateTests extends ESIntegTestCase { client().prepareIndex("test", "type1", "1").setSource("field", 1).execute().actionGet(); UpdateResponse updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1") - .setScript(new Script("ctx._source.field += 1", ScriptService.ScriptType.INLINE, null, null)).execute().actionGet(); + .setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", null)).execute().actionGet(); assertThat(updateResponse.getVersion(), equalTo(2L)); assertFalse(updateResponse.isCreated()); assertThat(updateResponse.getIndex(), equalTo("test")); @@ -315,9 +693,9 @@ public class UpdateTests extends ESIntegTestCase { } Map params = new HashMap<>(); - params.put("count", 3); + params.put("inc", 3); updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1") - .setScript(new Script("ctx._source.field += count", ScriptService.ScriptType.INLINE, null, params)).execute().actionGet(); + .setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", params)).execute().actionGet(); assertThat(updateResponse.getVersion(), equalTo(3L)); assertFalse(updateResponse.isCreated()); assertThat(updateResponse.getIndex(), equalTo("test")); @@ -329,7 +707,7 @@ public class UpdateTests extends ESIntegTestCase { // check noop updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1") - .setScript(new Script("ctx.op = 'none'", ScriptService.ScriptType.INLINE, null, null)).execute().actionGet(); + .setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("_ctx", Collections.singletonMap("op", "none")))).execute().actionGet(); assertThat(updateResponse.getVersion(), equalTo(3L)); assertFalse(updateResponse.isCreated()); assertThat(updateResponse.getIndex(), equalTo("test")); @@ -341,7 +719,7 @@ public class UpdateTests extends ESIntegTestCase { // check delete updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1") - .setScript(new Script("ctx.op = 'delete'", ScriptService.ScriptType.INLINE, null, null)).execute().actionGet(); + .setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("_ctx", Collections.singletonMap("op", "delete")))).execute().actionGet(); assertThat(updateResponse.getVersion(), equalTo(4L)); assertFalse(updateResponse.isCreated()); assertThat(updateResponse.getIndex(), equalTo("test")); @@ -357,14 +735,14 @@ public class UpdateTests extends ESIntegTestCase { long ttl = ((Number) getResponse.getField("_ttl").getValue()).longValue(); assertThat(ttl, greaterThan(0L)); client().prepareUpdate(indexOrAlias(), "type1", "2") - .setScript(new Script("ctx._source.field += 1", ScriptService.ScriptType.INLINE, null, null)).execute().actionGet(); + .setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", null)).execute().actionGet(); getResponse = client().prepareGet("test", "type1", "2").setFields("_ttl").execute().actionGet(); ttl = ((Number) getResponse.getField("_ttl").getValue()).longValue(); assertThat(ttl, greaterThan(0L)); // check TTL update client().prepareUpdate(indexOrAlias(), "type1", "2") - .setScript(new Script("ctx._ttl = 3600000", ScriptService.ScriptType.INLINE, null, null)).execute().actionGet(); + .setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("_ctx", Collections.singletonMap("_ttl", 3600000)))).execute().actionGet(); getResponse = client().prepareGet("test", "type1", "2").setFields("_ttl").execute().actionGet(); ttl = ((Number) getResponse.getField("_ttl").getValue()).longValue(); assertThat(ttl, greaterThan(0L)); @@ -373,7 +751,7 @@ public class UpdateTests extends ESIntegTestCase { // check timestamp update client().prepareIndex("test", "type1", "3").setSource("field", 1).setRefresh(true).execute().actionGet(); client().prepareUpdate(indexOrAlias(), "type1", "3") - .setScript(new Script("ctx._timestamp = \"2009-11-15T14:12:12\"", ScriptService.ScriptType.INLINE, null, null)).execute() + .setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("_ctx", Collections.singletonMap("_timestamp", "2009-11-15T14:12:12")))).execute() .actionGet(); getResponse = client().prepareGet("test", "type1", "3").setFields("_timestamp").execute().actionGet(); long timestamp = ((Number) getResponse.getField("_timestamp").getValue()).longValue(); @@ -382,7 +760,7 @@ public class UpdateTests extends ESIntegTestCase { // check fields parameter client().prepareIndex("test", "type1", "1").setSource("field", 1).execute().actionGet(); updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1") - .setScript(new Script("ctx._source.field += 1", ScriptService.ScriptType.INLINE, null, null)).setFields("_source", "field") + .setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", null)).setFields("_source", "field") .execute().actionGet(); assertThat(updateResponse.getIndex(), equalTo("test")); assertThat(updateResponse.getGetResult(), notNullValue()); @@ -443,7 +821,7 @@ public class UpdateTests extends ESIntegTestCase { try { client().prepareUpdate(indexOrAlias(), "type1", "1") .setDoc(XContentFactory.jsonBuilder().startObject().field("field", 1).endObject()) - .setScript(new Script("ctx._source.field += 1", ScriptService.ScriptType.INLINE, null, null)) + .setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", null)) .execute().actionGet(); fail("Should have thrown ActionRequestValidationException"); } catch (ActionRequestValidationException e) { @@ -459,7 +837,7 @@ public class UpdateTests extends ESIntegTestCase { ensureGreen(); try { client().prepareUpdate(indexOrAlias(), "type1", "1") - .setScript(new Script("ctx._source.field += 1", ScriptService.ScriptType.INLINE, null, null)) + .setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", null)) .setDocAsUpsert(true) .execute().actionGet(); fail("Should have thrown ActionRequestValidationException"); @@ -514,57 +892,39 @@ public class UpdateTests extends ESIntegTestCase { .execute().actionGet(); // Update the first object and note context variables values - Map scriptParams = new HashMap<>(); - scriptParams.put("delim", "_"); UpdateResponse updateResponse = client().prepareUpdate("test", "subtype1", "id1") .setRouting("routing1") - .setScript( - new Script("assert ctx._index == \"test\" : \"index should be \\\"test\\\"\"\n" - + - "assert ctx._type == \"subtype1\" : \"type should be \\\"subtype1\\\"\"\n" + - "assert ctx._id == \"id1\" : \"id should be \\\"id1\\\"\"\n" + - "assert ctx._version == 1 : \"version should be 1\"\n" + - "assert ctx._parent == \"parentId1\" : \"parent should be \\\"parentId1\\\"\"\n" + - "assert ctx._routing == \"routing1\" : \"routing should be \\\"routing1\\\"\"\n" + - "assert ctx._timestamp == " + timestamp + " : \"timestamp should be " + timestamp + "\"\n" + - // ttl has a 3-second leeway, because it's always counting down - "assert ctx._ttl <= " + ttl + " : \"ttl should be <= " + ttl + " but was \" + ctx._ttl\n" + - "assert ctx._ttl >= " + (ttl-3000) + " : \"ttl should be <= " + (ttl-3000) + " but was \" + ctx._ttl\n" + - "ctx._source.content = ctx._source.content + delim + ctx._source.content;\n" + - "ctx._source.field1 += 1;\n", - ScriptService.ScriptType.INLINE, null, scriptParams)) + .setScript(new Script("", ScriptService.ScriptType.INLINE, "extract_ctx", null)) .execute().actionGet(); assertEquals(2, updateResponse.getVersion()); GetResponse getResponse = client().prepareGet("test", "subtype1", "id1").setRouting("routing1").execute().actionGet(); - assertEquals(2, getResponse.getSourceAsMap().get("field1")); - assertEquals("foo_foo", getResponse.getSourceAsMap().get("content")); + Map updateContext = (Map) getResponse.getSourceAsMap().get("update_context"); + assertEquals("test", updateContext.get("_index")); + assertEquals("subtype1", updateContext.get("_type")); + assertEquals("id1", updateContext.get("_id")); + assertEquals(1, updateContext.get("_version")); + assertEquals("parentId1", updateContext.get("_parent")); + assertEquals("routing1", updateContext.get("_routing")); + assertThat(((Integer) updateContext.get("_ttl")).longValue(), allOf(greaterThanOrEqualTo(ttl-3000), lessThanOrEqualTo(ttl))); // Idem with the second object - scriptParams = new HashMap<>(); - scriptParams.put("delim", "_"); updateResponse = client().prepareUpdate("test", "type1", "parentId1") - .setScript( - new Script( - "assert ctx._index == \"test\" : \"index should be \\\"test\\\"\"\n" + - "assert ctx._type == \"type1\" : \"type should be \\\"type1\\\"\"\n" + - "assert ctx._id == \"parentId1\" : \"id should be \\\"parentId1\\\"\"\n" + - "assert ctx._version == 1 : \"version should be 1\"\n" + - "assert ctx._parent == null : \"parent should be null\"\n" + - "assert ctx._routing == null : \"routing should be null\"\n" + - "assert ctx._timestamp == " + (timestamp - 1) + " : \"timestamp should be " + (timestamp - 1) + "\"\n" + - "assert ctx._ttl == null : \"ttl should be null\"\n" + - "ctx._source.content = ctx._source.content + delim + ctx._source.content;\n" + - "ctx._source.field1 += 1;\n", - ScriptService.ScriptType.INLINE, null, scriptParams)) + .setScript(new Script("", ScriptService.ScriptType.INLINE, "extract_ctx", null)) .execute().actionGet(); assertEquals(2, updateResponse.getVersion()); getResponse = client().prepareGet("test", "type1", "parentId1").execute().actionGet(); - assertEquals(1, getResponse.getSourceAsMap().get("field1")); - assertEquals("bar_bar", getResponse.getSourceAsMap().get("content")); + updateContext = (Map) getResponse.getSourceAsMap().get("update_context"); + assertEquals("test", updateContext.get("_index")); + assertEquals("type1", updateContext.get("_type")); + assertEquals("parentId1", updateContext.get("_id")); + assertEquals(1, updateContext.get("_version")); + assertNull(updateContext.get("_parent")); + assertNull(updateContext.get("_routing")); + assertNull(updateContext.get("_ttl")); } @Test @@ -588,13 +948,13 @@ public class UpdateTests extends ESIntegTestCase { for (int i = 0; i < numberOfUpdatesPerThread; i++) { if (useBulkApi) { UpdateRequestBuilder updateRequestBuilder = client().prepareUpdate(indexOrAlias(), "type1", Integer.toString(i)) - .setScript(new Script("ctx._source.field += 1", ScriptService.ScriptType.INLINE, null, null)) + .setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", null)) .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("ctx._source.field += 1", ScriptService.ScriptType.INLINE, null, null)) + .setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", null)) .setRetryOnConflict(Integer.MAX_VALUE) .setUpsert(jsonBuilder().startObject().field("field", 1).endObject()) .execute().actionGet(); @@ -714,7 +1074,7 @@ public class UpdateTests extends ESIntegTestCase { updateRequestsOutstanding.acquire(); try { UpdateRequest ur = client().prepareUpdate("test", "type1", Integer.toString(j)) - .setScript(new Script("ctx._source.field += 1", ScriptService.ScriptType.INLINE, null, null)) + .setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", null)) .setRetryOnConflict(retryOnConflict) .setUpsert(jsonBuilder().startObject().field("field", 1).endObject()) .request(); @@ -814,7 +1174,7 @@ public class UpdateTests 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("ctx._source.field += 1", ScriptService.ScriptType.INLINE, null, null)) + .setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", null)) .setRetryOnConflict(Integer.MAX_VALUE) .setUpsert(jsonBuilder().startObject().field("field", 1).endObject()) .execute().actionGet(); diff --git a/plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/package-info.java b/plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/package-info.java index c4d93668709..a0d2c785c5b 100644 --- a/plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/package-info.java +++ b/plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/package-info.java @@ -80,7 +80,6 @@ renamed: core/src/test/java/org/elasticsearch/search/aggregations/metrics/TDigestPercentilesIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/TDigestPercentilesTests.java renamed: core/src/test/java/org/elasticsearch/search/aggregations/bucket/TopHitsIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/TopHitsTests.java renamed: core/src/test/java/org/elasticsearch/index/mapper/TransformOnIndexMapperIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/TransformOnIndexMapperTests.java - renamed: core/src/test/java/org/elasticsearch/update/UpdateIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/UpdateTests.java renamed: core/src/test/java/org/elasticsearch/search/aggregations/metrics/ValueCountIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ValueCountTests.java renamed: core/src/main/java/org/elasticsearch/script/groovy/GroovyScriptCompilationException.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyRestIT.java renamed: core/src/test/java/org/elasticsearch/script/GroovyScriptIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyScriptTests.java