Change Namespace for Stored Script to Only Use Id (elastic/elasticsearch#4387)
Changes the behavior in x-pack necessary to support the elasticsearch change elastic/elasticsearch#22206. Original commit: elastic/x-pack-elasticsearch@916e72e263
This commit is contained in:
parent
81171bb6ff
commit
7f0ecc4b30
|
@ -37,9 +37,12 @@ public class TextTemplate implements ToXContent {
|
|||
|
||||
public TextTemplate(String template, @Nullable XContentType contentType, ScriptType type,
|
||||
@Nullable Map<String, Object> params) {
|
||||
Map<String, String> options = new HashMap<>();
|
||||
if (contentType != null) {
|
||||
options.put(Script.CONTENT_TYPE_OPTION, contentType.mediaType());
|
||||
Map<String, String> options = null;
|
||||
if (type == ScriptType.INLINE) {
|
||||
options = new HashMap<>();
|
||||
if (contentType != null) {
|
||||
options.put(Script.CONTENT_TYPE_OPTION, contentType.mediaType());
|
||||
}
|
||||
}
|
||||
if (params == null) {
|
||||
params = new HashMap<>();
|
||||
|
@ -62,7 +65,7 @@ public class TextTemplate implements ToXContent {
|
|||
}
|
||||
|
||||
public XContentType getContentType() {
|
||||
if (script == null) {
|
||||
if (script == null || script.getOptions() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -112,7 +115,15 @@ public class TextTemplate implements ToXContent {
|
|||
if (parser.currentToken() == XContentParser.Token.VALUE_STRING) {
|
||||
return new TextTemplate(parser.text());
|
||||
} else {
|
||||
return new TextTemplate(Script.parse(parser, Script.DEFAULT_TEMPLATE_LANG));
|
||||
Script template = Script.parse(parser, Script.DEFAULT_TEMPLATE_LANG);
|
||||
|
||||
// for deprecation of stored script namespaces the default lang is ignored,
|
||||
// so the template lang must be set for a stored script
|
||||
if (template.getType() == ScriptType.STORED) {
|
||||
template = new Script(ScriptType.STORED, Script.DEFAULT_TEMPLATE_LANG, template.getIdOrCode(), template.getParams());
|
||||
}
|
||||
|
||||
return new TextTemplate(template);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.elasticsearch.script.CompiledScript;
|
|||
import org.elasticsearch.script.ExecutableScript;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
import org.elasticsearch.xpack.watcher.Watcher;
|
||||
|
||||
import java.util.Collections;
|
||||
|
@ -34,8 +35,7 @@ public class TextTemplateEngine extends AbstractComponent {
|
|||
}
|
||||
|
||||
String template = textTemplate.getTemplate();
|
||||
XContentType contentType = detectContentType(template);
|
||||
Map<String, String> compileParams = compileParams(contentType);
|
||||
String mediaType = compileParams(detectContentType(template));
|
||||
template = trimContentType(textTemplate);
|
||||
|
||||
Map<String, Object> mergedModel = new HashMap<>();
|
||||
|
@ -44,12 +44,18 @@ public class TextTemplateEngine extends AbstractComponent {
|
|||
}
|
||||
mergedModel.putAll(model);
|
||||
|
||||
Map<String, String> options = new HashMap<>();
|
||||
if (textTemplate.getContentType() != null) {
|
||||
options.put(Script.CONTENT_TYPE_OPTION, textTemplate.getContentType().mediaType());
|
||||
Map<String, String> options = null;
|
||||
if (textTemplate.getType() == ScriptType.INLINE) {
|
||||
options = new HashMap<>();
|
||||
|
||||
if (textTemplate.getScript() != null && textTemplate.getScript().getOptions() != null) {
|
||||
options.putAll(textTemplate.getScript().getOptions());
|
||||
}
|
||||
|
||||
options.put(Script.CONTENT_TYPE_OPTION, mediaType);
|
||||
}
|
||||
Script script = new Script(textTemplate.getType(), "mustache", template, options, mergedModel);
|
||||
CompiledScript compiledScript = service.compile(script, Watcher.SCRIPT_CONTEXT, compileParams);
|
||||
CompiledScript compiledScript = service.compile(script, Watcher.SCRIPT_CONTEXT);
|
||||
ExecutableScript executable = service.executable(compiledScript, model);
|
||||
Object result = executable.run();
|
||||
if (result instanceof BytesReference) {
|
||||
|
@ -88,11 +94,11 @@ public class TextTemplateEngine extends AbstractComponent {
|
|||
return null;
|
||||
}
|
||||
|
||||
private Map<String, String> compileParams(XContentType contentType) {
|
||||
private String compileParams(XContentType contentType) {
|
||||
if (contentType == XContentType.JSON) {
|
||||
return Collections.singletonMap("content_type", "application/json");
|
||||
return "application/json";
|
||||
} else {
|
||||
return Collections.singletonMap("content_type", "text/plain");
|
||||
return "text/plain";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public final class ScriptCondition extends Condition {
|
|||
super(TYPE);
|
||||
this.scriptService = scriptService;
|
||||
this.script = script;
|
||||
compiledScript = scriptService.compile(script, Watcher.SCRIPT_CONTEXT, Collections.emptyMap());
|
||||
compiledScript = scriptService.compile(script, Watcher.SCRIPT_CONTEXT);
|
||||
}
|
||||
|
||||
public Script getScript() {
|
||||
|
|
|
@ -247,6 +247,13 @@ public class WatcherSearchTemplateRequest implements ToXContentObject {
|
|||
DEFAULT_INDICES_OPTIONS);
|
||||
} else if (TEMPLATE_FIELD.match(currentFieldName)) {
|
||||
template = Script.parse(parser, Script.DEFAULT_TEMPLATE_LANG);
|
||||
|
||||
// for deprecation of stored script namespaces the default lang is ignored,
|
||||
// so the template lang must be set for a stored script
|
||||
if (template.getType() == ScriptType.STORED) {
|
||||
template = new Script(
|
||||
ScriptType.STORED, Script.DEFAULT_TEMPLATE_LANG, template.getIdOrCode(), template.getParams());
|
||||
}
|
||||
} else {
|
||||
throw new ElasticsearchParseException("could not read search request. unexpected object field [" +
|
||||
currentFieldName + "]");
|
||||
|
|
|
@ -52,9 +52,8 @@ public class WatcherSearchTemplateService extends AbstractComponent {
|
|||
watcherContextParams.putAll(source.getParams());
|
||||
}
|
||||
// Templates are always of lang mustache:
|
||||
Script template = new Script(source.getType(), "mustache", source.getIdOrCode(), source.getOptions(), watcherContextParams
|
||||
);
|
||||
CompiledScript compiledScript = scriptService.compile(template, Watcher.SCRIPT_CONTEXT, Collections.emptyMap());
|
||||
Script template = new Script(source.getType(), "mustache", source.getIdOrCode(), source.getOptions(), watcherContextParams);
|
||||
CompiledScript compiledScript = scriptService.compile(template, Watcher.SCRIPT_CONTEXT);
|
||||
return (BytesReference) scriptService.executable(compiledScript, template.getParams()).run();
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ public class ExecutableScriptTransform extends ExecutableTransform<ScriptTransfo
|
|||
this.scriptService = scriptService;
|
||||
Script script = transform.getScript();
|
||||
// try to compile so we catch syntax errors early
|
||||
scriptService.compile(script, Watcher.SCRIPT_CONTEXT, Collections.emptyMap());
|
||||
scriptService.compile(script, Watcher.SCRIPT_CONTEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -54,7 +54,7 @@ public class ExecutableScriptTransform extends ExecutableTransform<ScriptTransfo
|
|||
model.putAll(script.getParams());
|
||||
}
|
||||
model.putAll(createCtxModel(ctx, payload));
|
||||
CompiledScript compiledScript = scriptService.compile(script, Watcher.SCRIPT_CONTEXT, Collections.emptyMap());
|
||||
CompiledScript compiledScript = scriptService.compile(script, Watcher.SCRIPT_CONTEXT);
|
||||
ExecutableScript executable = scriptService.executable(compiledScript, model);
|
||||
Object value = executable.run();
|
||||
if (value instanceof Map) {
|
||||
|
|
|
@ -58,8 +58,9 @@ public class TextTemplateTests extends ESTestCase {
|
|||
ScriptType type = randomFrom(ScriptType.values());
|
||||
|
||||
CompiledScript compiledScript = mock(CompiledScript.class);
|
||||
when(service.compile(new Script(type, lang, templateText, merged), Watcher.SCRIPT_CONTEXT,
|
||||
Collections.singletonMap("content_type", "text/plain"))).thenReturn(compiledScript);
|
||||
when(service.compile(new Script(type, lang, templateText,
|
||||
type == ScriptType.INLINE ? Collections.singletonMap("content_type", "text/plain") : null,
|
||||
merged), Watcher.SCRIPT_CONTEXT)).thenReturn(compiledScript);
|
||||
when(service.executable(compiledScript, model)).thenReturn(script);
|
||||
when(script.run()).thenReturn("rendered_text");
|
||||
|
||||
|
@ -71,15 +72,16 @@ public class TextTemplateTests extends ESTestCase {
|
|||
String templateText = "_template";
|
||||
Map<String, Object> params = singletonMap("key", "param_val");
|
||||
Map<String, Object> model = singletonMap("key", "model_val");
|
||||
ScriptType scriptType = randomFrom(ScriptType.values());
|
||||
ScriptType type = randomFrom(ScriptType.values());
|
||||
|
||||
CompiledScript compiledScript = mock(CompiledScript.class);
|
||||
when(service.compile(new Script(scriptType, lang, templateText, model), Watcher.SCRIPT_CONTEXT,
|
||||
Collections.singletonMap("content_type", "text/plain"))).thenReturn(compiledScript);
|
||||
when(service.compile(new Script(type, lang, templateText,
|
||||
type == ScriptType.INLINE ? Collections.singletonMap("content_type", "text/plain") : null,
|
||||
model), Watcher.SCRIPT_CONTEXT)).thenReturn(compiledScript);
|
||||
when(service.executable(compiledScript, model)).thenReturn(script);
|
||||
when(script.run()).thenReturn("rendered_text");
|
||||
|
||||
TextTemplate template = templateBuilder(scriptType, templateText, params);
|
||||
TextTemplate template = templateBuilder(type, templateText, params);
|
||||
assertThat(engine.render(template, model), is("rendered_text"));
|
||||
}
|
||||
|
||||
|
@ -88,8 +90,9 @@ public class TextTemplateTests extends ESTestCase {
|
|||
Map<String, Object> model = singletonMap("key", "model_val");
|
||||
|
||||
CompiledScript compiledScript = mock(CompiledScript.class);
|
||||
when(service.compile(new Script(ScriptType.INLINE, lang, templateText, model), Watcher.SCRIPT_CONTEXT,
|
||||
Collections.singletonMap("content_type", "text/plain"))).thenReturn(compiledScript);
|
||||
when(service.compile(new Script(ScriptType.INLINE, lang, templateText,
|
||||
Collections.singletonMap("content_type", "text/plain"), model), Watcher.SCRIPT_CONTEXT))
|
||||
.thenReturn(compiledScript);
|
||||
when(service.executable(compiledScript, model)).thenReturn(script);
|
||||
when(script.run()).thenReturn("rendered_text");
|
||||
|
||||
|
|
|
@ -240,7 +240,7 @@ public class ScriptConditionTests extends ESTestCase {
|
|||
default:
|
||||
throw illegalArgument("unsupported script type [{}]", scriptType);
|
||||
}
|
||||
if (scriptLang != null) {
|
||||
if (scriptLang != null && scriptType != ScriptType.STORED) {
|
||||
builder.field("lang", scriptLang);
|
||||
}
|
||||
return builder.endObject();
|
||||
|
|
|
@ -261,9 +261,9 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase {
|
|||
public void testConditionSearchWithIndexedTemplate() throws Exception {
|
||||
SearchSourceBuilder searchSourceBuilder = searchSource().query(matchQuery("level", "a"));
|
||||
assertAcked(client().admin().cluster().preparePutStoredScript()
|
||||
.setScriptLang("mustache")
|
||||
.setLang("mustache")
|
||||
.setId("my-template")
|
||||
.setSource(jsonBuilder().startObject().field("template").value(searchSourceBuilder).endObject().bytes())
|
||||
.setContent(jsonBuilder().startObject().field("template").value(searchSourceBuilder).endObject().bytes())
|
||||
.get());
|
||||
|
||||
Script template = new Script(ScriptType.STORED, "mustache", "my-template", Collections.emptyMap());
|
||||
|
|
|
@ -126,8 +126,8 @@ public class TransformIntegrationTests extends AbstractWatcherIntegrationTestCas
|
|||
logger.info("testing script transform with an indexed script");
|
||||
assertAcked(client().admin().cluster().preparePutStoredScript()
|
||||
.setId("my-script")
|
||||
.setScriptLang("painless")
|
||||
.setSource(new BytesArray("{\"script\" : \"['key3' : ctx.payload.key1 + ctx.payload.key2]\"}"))
|
||||
.setLang("painless")
|
||||
.setContent(new BytesArray("{\"script\" : \"['key3' : ctx.payload.key1 + ctx.payload.key2]\"}"))
|
||||
.get());
|
||||
script = new Script(ScriptType.STORED, "painless", "my-script", Collections.emptyMap());
|
||||
} else {
|
||||
|
|
|
@ -61,7 +61,7 @@ public class ScriptTransformTests extends ESTestCase {
|
|||
Map<String, Object> params = Collections.emptyMap();
|
||||
Script script = new Script(type, "_lang", "_script", params);
|
||||
CompiledScript compiledScript = mock(CompiledScript.class);
|
||||
when(service.compile(script, Watcher.SCRIPT_CONTEXT, Collections.emptyMap())).thenReturn(compiledScript);
|
||||
when(service.compile(script, Watcher.SCRIPT_CONTEXT)).thenReturn(compiledScript);
|
||||
ExecutableScriptTransform transform = new ExecutableScriptTransform(new ScriptTransform(script), logger, service);
|
||||
|
||||
WatchExecutionContext ctx = mockExecutionContext("_name", EMPTY_PAYLOAD);
|
||||
|
@ -89,7 +89,7 @@ public class ScriptTransformTests extends ESTestCase {
|
|||
Map<String, Object> params = Collections.emptyMap();
|
||||
Script script = new Script(type, "_lang", "_script", params);
|
||||
CompiledScript compiledScript = mock(CompiledScript.class);
|
||||
when(service.compile(script, Watcher.SCRIPT_CONTEXT, Collections.emptyMap())).thenReturn(compiledScript);
|
||||
when(service.compile(script, Watcher.SCRIPT_CONTEXT)).thenReturn(compiledScript);
|
||||
ExecutableScriptTransform transform = new ExecutableScriptTransform(new ScriptTransform(script), logger, service);
|
||||
|
||||
WatchExecutionContext ctx = mockExecutionContext("_name", EMPTY_PAYLOAD);
|
||||
|
@ -115,7 +115,7 @@ public class ScriptTransformTests extends ESTestCase {
|
|||
Map<String, Object> params = Collections.emptyMap();
|
||||
Script script = new Script(type, "_lang", "_script", params);
|
||||
CompiledScript compiledScript = mock(CompiledScript.class);
|
||||
when(service.compile(script, Watcher.SCRIPT_CONTEXT, Collections.emptyMap())).thenReturn(compiledScript);
|
||||
when(service.compile(script, Watcher.SCRIPT_CONTEXT)).thenReturn(compiledScript);
|
||||
ExecutableScriptTransform transform = new ExecutableScriptTransform(new ScriptTransform(script), logger, service);
|
||||
|
||||
WatchExecutionContext ctx = mockExecutionContext("_name", EMPTY_PAYLOAD);
|
||||
|
@ -141,14 +141,16 @@ public class ScriptTransformTests extends ESTestCase {
|
|||
ScriptType type = randomFrom(ScriptType.values());
|
||||
XContentBuilder builder = jsonBuilder().startObject();
|
||||
builder.field(scriptTypeField(type), "_script");
|
||||
builder.field("lang", "_lang");
|
||||
if (type != ScriptType.STORED) {
|
||||
builder.field("lang", "_lang");
|
||||
}
|
||||
builder.startObject("params").field("key", "value").endObject();
|
||||
builder.endObject();
|
||||
|
||||
XContentParser parser = createParser(builder);
|
||||
parser.nextToken();
|
||||
ExecutableScriptTransform transform = new ScriptTransformFactory(Settings.EMPTY, service).parseExecutable("_id", parser);
|
||||
Script script = new Script(type, "_lang", "_script", singletonMap("key", "value"));
|
||||
Script script = new Script(type, type == ScriptType.STORED ? null : "_lang", "_script", singletonMap("key", "value"));
|
||||
assertThat(transform.transform().getScript(), equalTo(script));
|
||||
}
|
||||
|
||||
|
@ -167,7 +169,7 @@ public class ScriptTransformTests extends ESTestCase {
|
|||
String errorMessage = "expected error message";
|
||||
ScriptException scriptException = new ScriptException(errorMessage, new RuntimeException("foo"),
|
||||
Collections.emptyList(), "whatever", "whatever");
|
||||
when(scriptService.compile(anyObject(), eq(Watcher.SCRIPT_CONTEXT), anyObject())).thenThrow(scriptException);
|
||||
when(scriptService.compile(anyObject(), eq(Watcher.SCRIPT_CONTEXT))).thenThrow(scriptException);
|
||||
|
||||
ScriptTransformFactory transformFactory = new ScriptTransformFactory(Settings.builder().build(), scriptService);
|
||||
|
||||
|
@ -198,7 +200,13 @@ public class ScriptTransformTests extends ESTestCase {
|
|||
parser.nextToken();
|
||||
ScriptTransform scriptCondition = transformFactory.parseTransform("_watch", parser);
|
||||
Exception e = expectThrows(IllegalArgumentException.class, () -> transformFactory.createExecutable(scriptCondition));
|
||||
assertThat(e.getMessage(), containsString("script_lang not supported [not_a_valid_lang]"));
|
||||
if (scriptType == ScriptType.STORED) {
|
||||
assertThat(e.getMessage(), containsString("unable to get stored script with unsupported lang [not_a_valid_lang]"));
|
||||
assertWarnings("specifying the field [lang] for executing stored scripts is deprecated;" +
|
||||
" use only the field [stored] to specify an <id>");
|
||||
} else {
|
||||
assertThat(e.getMessage(), containsString("script_lang not supported [not_a_valid_lang]"));
|
||||
}
|
||||
}
|
||||
|
||||
static String scriptTypeField(ScriptType type) {
|
||||
|
|
|
@ -2,17 +2,22 @@
|
|||
# See https://github.com/elastic/x-plugins/issues/4237
|
||||
---
|
||||
"Test transform scripts are updated on execution":
|
||||
- skip:
|
||||
features: warnings
|
||||
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
- do:
|
||||
put_script:
|
||||
id: transform-script
|
||||
lang: painless
|
||||
lang: transform-script
|
||||
body: >
|
||||
{
|
||||
"script":"return [ 'email': 'foo@bar.org' ]"
|
||||
"script":{
|
||||
"lang": "painless",
|
||||
"code":"return [ 'email': 'foo@bar.org' ]"
|
||||
}
|
||||
}
|
||||
|
||||
- do:
|
||||
|
@ -53,11 +58,14 @@
|
|||
|
||||
- do:
|
||||
put_script:
|
||||
id: transform-script
|
||||
lang: painless
|
||||
lang: transform-script
|
||||
body: >
|
||||
{
|
||||
"script":"return [ 'email': 'foo@example.org' ]"
|
||||
"script":
|
||||
{
|
||||
"lang": "painless",
|
||||
"code":"return [ 'email': 'foo@example.org' ]"
|
||||
}
|
||||
}
|
||||
|
||||
- do:
|
||||
|
@ -69,17 +77,23 @@
|
|||
|
||||
---
|
||||
"Test condition scripts are updated on execution":
|
||||
- skip:
|
||||
features: warnings
|
||||
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
- do:
|
||||
put_script:
|
||||
id: condition-script
|
||||
lang: painless
|
||||
lang: condition-script
|
||||
body: >
|
||||
{
|
||||
"script":"return false"
|
||||
"script":
|
||||
{
|
||||
"lang": "painless",
|
||||
"code": "return false"
|
||||
}
|
||||
}
|
||||
|
||||
- do:
|
||||
|
@ -120,11 +134,13 @@
|
|||
|
||||
- do:
|
||||
put_script:
|
||||
id: condition-script
|
||||
lang: painless
|
||||
lang: condition-script
|
||||
body: >
|
||||
{
|
||||
"script":"return true"
|
||||
"script": {
|
||||
"lang": "painless",
|
||||
"code": "return true"
|
||||
}
|
||||
}
|
||||
|
||||
- do:
|
||||
|
|
Loading…
Reference in New Issue