diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptRequest.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptRequest.java index c30eae12a82ea..ec6f68dd37f58 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptRequest.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptRequest.java @@ -19,6 +19,7 @@ package org.elasticsearch.action.admin.cluster.storedscripts; +import org.elasticsearch.Version; import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.support.master.AcknowledgedRequest; import org.elasticsearch.common.io.stream.StreamInput; @@ -31,17 +32,15 @@ public class DeleteStoredScriptRequest extends AcknowledgedRequest { private String id; - private String lang; DeleteStoredScriptRequest() { super(); } - public DeleteStoredScriptRequest(String id, String lang) { + public DeleteStoredScriptRequest(String id) { super(); this.id = id; - this.lang = lang; } @Override @@ -54,10 +53,6 @@ public ActionRequestValidationException validate() { validationException = addValidationError("id cannot contain '#' for stored script", validationException); } - if (lang != null && lang.contains("#")) { - validationException = addValidationError("lang cannot contain '#' for stored script", validationException); - } - return validationException; } @@ -71,24 +66,12 @@ public DeleteStoredScriptRequest id(String id) { return this; } - public String lang() { - return lang; - } - - public DeleteStoredScriptRequest lang(String lang) { - this.lang = lang; - - return this; - } - @Override public void readFrom(StreamInput in) throws IOException { super.readFrom(in); - lang = in.readString(); - - if (lang.isEmpty()) { - lang = null; + if (in.getVersion().before(Version.V_6_0_0_alpha2)) { + in.readString(); // read lang from previous versions } id = in.readString(); @@ -98,12 +81,15 @@ public void readFrom(StreamInput in) throws IOException { public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); - out.writeString(lang == null ? "" : lang); + if (out.getVersion().before(Version.V_6_0_0_alpha2)) { + out.writeString(""); // write an empty lang to previous versions + } + out.writeString(id); } @Override public String toString() { - return "delete stored script {id [" + id + "]" + (lang != null ? ", lang [" + lang + "]" : "") + "}"; + return "delete stored script {id [" + id + "]}"; } } diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptRequestBuilder.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptRequestBuilder.java index 8a65506dabd34..1b48a45be3c69 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptRequestBuilder.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptRequestBuilder.java @@ -29,12 +29,6 @@ public DeleteStoredScriptRequestBuilder(ElasticsearchClient client, DeleteStored super(client, action, new DeleteStoredScriptRequest()); } - public DeleteStoredScriptRequestBuilder setLang(String lang) { - request.lang(lang); - - return this; - } - public DeleteStoredScriptRequestBuilder setId(String id) { request.id(id); diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptRequest.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptRequest.java index 2bfd547362c80..b961dc82dc6c2 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptRequest.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptRequest.java @@ -19,10 +19,9 @@ package org.elasticsearch.action.admin.cluster.storedscripts; +import org.elasticsearch.Version; import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.action.ValidateActions; import org.elasticsearch.action.support.master.MasterNodeReadRequest; -import org.elasticsearch.common.Nullable; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -33,17 +32,15 @@ public class GetStoredScriptRequest extends MasterNodeReadRequest { protected String id; - protected String lang; GetStoredScriptRequest() { super(); } - public GetStoredScriptRequest(String id, String lang) { + public GetStoredScriptRequest(String id) { super(); this.id = id; - this.lang = lang; } @Override @@ -56,10 +53,6 @@ public ActionRequestValidationException validate() { validationException = addValidationError("id cannot contain '#' for stored script", validationException); } - if (lang != null && lang.contains("#")) { - validationException = addValidationError("lang cannot contain '#' for stored script", validationException); - } - return validationException; } @@ -73,24 +66,12 @@ public GetStoredScriptRequest id(String id) { return this; } - public String lang() { - return lang; - } - - public GetStoredScriptRequest lang(String lang) { - this.lang = lang; - - return this; - } - @Override public void readFrom(StreamInput in) throws IOException { super.readFrom(in); - lang = in.readString(); - - if (lang.isEmpty()) { - lang = null; + if (in.getVersion().before(Version.V_6_0_0_alpha2)) { + in.readString(); // read lang from previous versions } id = in.readString(); @@ -100,12 +81,15 @@ public void readFrom(StreamInput in) throws IOException { public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); - out.writeString(lang == null ? "" : lang); + if (out.getVersion().before(Version.V_6_0_0_alpha2)) { + out.writeString(""); // write an empty lang to previous versions + } + out.writeString(id); } @Override public String toString() { - return "get script [" + lang + "][" + id + "]"; + return "get script [" + id + "]"; } } diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptRequestBuilder.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptRequestBuilder.java index c62a080830442..75708c929f584 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptRequestBuilder.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptRequestBuilder.java @@ -21,7 +21,6 @@ import org.elasticsearch.action.support.master.MasterNodeReadOperationRequestBuilder; import org.elasticsearch.client.ElasticsearchClient; -import org.elasticsearch.common.Nullable; public class GetStoredScriptRequestBuilder extends MasterNodeReadOperationRequestBuilder { @@ -31,11 +30,6 @@ public GetStoredScriptRequestBuilder(ElasticsearchClient client, GetStoredScript super(client, action, new GetStoredScriptRequest()); } - public GetStoredScriptRequestBuilder setLang(@Nullable String lang) { - request.lang(lang); - return this; - } - public GetStoredScriptRequestBuilder setId(String id) { request.id(id); return this; diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptRequest.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptRequest.java index d35a26d9c3242..e3392df885075 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptRequest.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptRequest.java @@ -28,6 +28,7 @@ import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.script.StoredScriptSource; import java.io.IOException; import java.util.Objects; @@ -37,22 +38,22 @@ public class PutStoredScriptRequest extends AcknowledgedRequest { private String id; - private String lang; private String context; private BytesReference content; private XContentType xContentType; + private StoredScriptSource source; public PutStoredScriptRequest() { super(); } - public PutStoredScriptRequest(String id, String lang, String context, BytesReference content, XContentType xContentType) { + public PutStoredScriptRequest(String id, String context, BytesReference content, XContentType xContentType, StoredScriptSource source) { super(); this.id = id; - this.lang = lang; this.context = context; this.content = content; this.xContentType = Objects.requireNonNull(xContentType); + this.source = source; } @Override @@ -65,10 +66,6 @@ public ActionRequestValidationException validate() { validationException = addValidationError("id cannot contain '#' for stored script", validationException); } - if (lang != null && lang.contains("#")) { - validationException = addValidationError("lang cannot contain '#' for stored script", validationException); - } - if (content == null) { validationException = addValidationError("must specify code for stored script", validationException); } @@ -82,17 +79,6 @@ public String id() { public PutStoredScriptRequest id(String id) { this.id = id; - - return this; - } - - public String lang() { - return lang; - } - - public PutStoredScriptRequest lang(String lang) { - this.lang = lang; - return this; } @@ -113,12 +99,17 @@ public XContentType xContentType() { return xContentType; } + public StoredScriptSource source() { + return source; + } + /** * Set the script source and the content type of the bytes. */ public PutStoredScriptRequest content(BytesReference content, XContentType xContentType) { this.content = content; this.xContentType = Objects.requireNonNull(xContentType); + this.source = StoredScriptSource.parse(content, xContentType); return this; } @@ -126,12 +117,9 @@ public PutStoredScriptRequest content(BytesReference content, XContentType xCont public void readFrom(StreamInput in) throws IOException { super.readFrom(in); - lang = in.readString(); - - if (lang.isEmpty()) { - lang = null; + if (in.getVersion().before(Version.V_6_0_0_alpha2)) { + in.readString(); // read lang from previous versions } - id = in.readOptionalString(); content = in.readBytesReference(); if (in.getVersion().onOrAfter(Version.V_5_3_0)) { @@ -141,6 +129,9 @@ public void readFrom(StreamInput in) throws IOException { } if (in.getVersion().onOrAfter(Version.V_6_0_0_alpha2)) { context = in.readOptionalString(); + source = new StoredScriptSource(in); + } else { + source = StoredScriptSource.parse(content, xContentType == null ? XContentType.JSON : xContentType); } } @@ -148,7 +139,9 @@ public void readFrom(StreamInput in) throws IOException { public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); - out.writeString(lang == null ? "" : lang); + if (out.getVersion().before(Version.V_6_0_0_alpha2)) { + out.writeString(source == null ? "" : source.getLang()); + } out.writeOptionalString(id); out.writeBytesReference(content); if (out.getVersion().onOrAfter(Version.V_5_3_0)) { @@ -156,6 +149,7 @@ public void writeTo(StreamOutput out) throws IOException { } if (out.getVersion().onOrAfter(Version.V_6_0_0_alpha2)) { out.writeOptionalString(context); + source.writeTo(out); } } @@ -169,6 +163,8 @@ public String toString() { // ignore } - return "put stored script {id [" + id + "]" + (lang != null ? ", lang [" + lang + "]" : "") + ", content [" + source + "]}"; + return "put stored script {id [" + id + "]" + + (context != null ? ", context [" + context + "]" : "") + + ", content [" + source + "]}"; } } diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptRequestBuilder.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptRequestBuilder.java index 9985a3394e311..e98f7c7e3e6de 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptRequestBuilder.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptRequestBuilder.java @@ -43,9 +43,4 @@ public PutStoredScriptRequestBuilder setContent(BytesReference source, XContentT request.content(source, xContentType); return this; } - - public PutStoredScriptRequestBuilder setLang(String lang) { - request.lang(lang); - return this; - } } diff --git a/core/src/main/java/org/elasticsearch/client/ClusterAdminClient.java b/core/src/main/java/org/elasticsearch/client/ClusterAdminClient.java index 942d9e50560e2..ccb3296a5d593 100644 --- a/core/src/main/java/org/elasticsearch/client/ClusterAdminClient.java +++ b/core/src/main/java/org/elasticsearch/client/ClusterAdminClient.java @@ -298,7 +298,7 @@ public interface ClusterAdminClient extends ElasticsearchClient { /** * Returns top N hot-threads samples per node. The hot-threads are only * sampled for the node ids specified in the request. - * + * */ ActionFuture nodesHotThreads(NodesHotThreadsRequest request); @@ -682,7 +682,7 @@ public interface ClusterAdminClient extends ElasticsearchClient { /** * Delete a script from the cluster state */ - DeleteStoredScriptRequestBuilder prepareDeleteStoredScript(String scriptLang, String id); + DeleteStoredScriptRequestBuilder prepareDeleteStoredScript(String id); /** * Store a script in the cluster state @@ -702,7 +702,7 @@ public interface ClusterAdminClient extends ElasticsearchClient { /** * Get a script from the cluster state */ - GetStoredScriptRequestBuilder prepareGetStoredScript(@Nullable String scriptLang, String id); + GetStoredScriptRequestBuilder prepareGetStoredScript(String id); /** * Get a script from the cluster state diff --git a/core/src/main/java/org/elasticsearch/client/support/AbstractClient.java b/core/src/main/java/org/elasticsearch/client/support/AbstractClient.java index 0e606fc8b74cd..c2b813d3d659e 100644 --- a/core/src/main/java/org/elasticsearch/client/support/AbstractClient.java +++ b/core/src/main/java/org/elasticsearch/client/support/AbstractClient.java @@ -1192,8 +1192,8 @@ public GetStoredScriptRequestBuilder prepareGetStoredScript() { } @Override - public GetStoredScriptRequestBuilder prepareGetStoredScript(String scriptLang, String id) { - return prepareGetStoredScript().setLang(scriptLang).setId(id); + public GetStoredScriptRequestBuilder prepareGetStoredScript(String id) { + return prepareGetStoredScript().setId(id); } @Override @@ -1228,8 +1228,8 @@ public DeleteStoredScriptRequestBuilder prepareDeleteStoredScript(){ } @Override - public DeleteStoredScriptRequestBuilder prepareDeleteStoredScript(@Nullable String scriptLang, String id){ - return prepareDeleteStoredScript().setLang(scriptLang).setId(id); + public DeleteStoredScriptRequestBuilder prepareDeleteStoredScript(String id){ + return prepareDeleteStoredScript().setId(id); } } diff --git a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteStoredScriptAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteStoredScriptAction.java index 8aadba3adf43c..72932709799c6 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteStoredScriptAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteStoredScriptAction.java @@ -35,11 +35,7 @@ public class RestDeleteStoredScriptAction extends BaseRestHandler { public RestDeleteStoredScriptAction(Settings settings, RestController controller) { super(settings); - // Note {lang} is actually {id} in the first handler. It appears - // parameters as part of the path must be of the same ordering relative - // to name or they will not work as expected. - controller.registerHandler(DELETE, "/_scripts/{lang}", this); - controller.registerHandler(DELETE, "/_scripts/{lang}/{id}", this); + controller.registerHandler(DELETE, "/_scripts/{id}", this); } @Override @@ -50,21 +46,7 @@ public String getName() { @Override public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { String id = request.param("id"); - String lang = request.param("lang"); - - // In the case where only {lang} is not null, we make it {id} because of - // name ordering issues in the handlers' paths. - if (id == null) { - id = lang; - lang = null; - } - - if (lang != null) { - deprecationLogger.deprecated( - "specifying lang [" + lang + "] as part of the url path is deprecated"); - } - - DeleteStoredScriptRequest deleteStoredScriptRequest = new DeleteStoredScriptRequest(id, lang); + DeleteStoredScriptRequest deleteStoredScriptRequest = new DeleteStoredScriptRequest(id); return channel -> client.admin().cluster().deleteStoredScript(deleteStoredScriptRequest, new AcknowledgedRestListener<>(channel)); } } diff --git a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetStoredScriptAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetStoredScriptAction.java index f6299fcac58ce..10050dda88235 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetStoredScriptAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetStoredScriptAction.java @@ -40,17 +40,12 @@ public class RestGetStoredScriptAction extends BaseRestHandler { public static final ParseField _ID_PARSE_FIELD = new ParseField("_id"); - public static final ParseField FOUND_PARSE_FIELD = new ParseField("found"); public RestGetStoredScriptAction(Settings settings, RestController controller) { super(settings); - // Note {lang} is actually {id} in the first handler. It appears - // parameters as part of the path must be of the same ordering relative - // to name or they will not work as expected. - controller.registerHandler(GET, "/_scripts/{lang}", this); - controller.registerHandler(GET, "/_scripts/{lang}/{id}", this); + controller.registerHandler(GET, "/_scripts/{id}", this); } @Override @@ -60,25 +55,8 @@ public String getName() { @Override public RestChannelConsumer prepareRequest(final RestRequest request, NodeClient client) throws IOException { - String id; - String lang; - - // In the case where only {lang} is not null, we make it {id} because of - // name ordering issues in the handlers' paths. - if (request.param("id") == null) { - id = request.param("lang");; - lang = null; - } else { - id = request.param("id"); - lang = request.param("lang"); - } - - if (lang != null) { - deprecationLogger.deprecated( - "specifying lang [" + lang + "] as part of the url path is deprecated"); - } - - GetStoredScriptRequest getRequest = new GetStoredScriptRequest(id, lang); + String id = request.param("id"); + GetStoredScriptRequest getRequest = new GetStoredScriptRequest(id); return channel -> client.admin().cluster().getStoredScript(getRequest, new RestBuilderListener(channel) { @Override @@ -86,28 +64,20 @@ public RestResponse buildResponse(GetStoredScriptResponse response, XContentBuil builder.startObject(); builder.field(_ID_PARSE_FIELD.getPreferredName(), id); - if (lang != null) { - builder.field(StoredScriptSource.LANG_PARSE_FIELD.getPreferredName(), lang); - } - StoredScriptSource source = response.getSource(); boolean found = source != null; builder.field(FOUND_PARSE_FIELD.getPreferredName(), found); if (found) { - if (lang == null) { - builder.startObject(StoredScriptSource.SCRIPT_PARSE_FIELD.getPreferredName()); - builder.field(StoredScriptSource.LANG_PARSE_FIELD.getPreferredName(), source.getLang()); - builder.field(StoredScriptSource.SOURCE_PARSE_FIELD.getPreferredName(), source.getSource()); - - if (source.getOptions().isEmpty() == false) { - builder.field(StoredScriptSource.OPTIONS_PARSE_FIELD.getPreferredName(), source.getOptions()); - } - - builder.endObject(); - } else { - builder.field(StoredScriptSource.SCRIPT_PARSE_FIELD.getPreferredName(), source.getSource()); + builder.startObject(StoredScriptSource.SCRIPT_PARSE_FIELD.getPreferredName()); + builder.field(StoredScriptSource.LANG_PARSE_FIELD.getPreferredName(), source.getLang()); + builder.field(StoredScriptSource.SOURCE_PARSE_FIELD.getPreferredName(), source.getSource()); + + if (source.getOptions().isEmpty() == false) { + builder.field(StoredScriptSource.OPTIONS_PARSE_FIELD.getPreferredName(), source.getOptions()); } + + builder.endObject(); } builder.endObject(); diff --git a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestPutStoredScriptAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestPutStoredScriptAction.java index 84c2aa0a9e2f9..564cb84bf44e2 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestPutStoredScriptAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestPutStoredScriptAction.java @@ -22,10 +22,12 @@ import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.action.AcknowledgedRestListener; +import org.elasticsearch.script.StoredScriptSource; import java.io.IOException; @@ -37,13 +39,9 @@ public class RestPutStoredScriptAction extends BaseRestHandler { public RestPutStoredScriptAction(Settings settings, RestController controller) { super(settings); - // Note {lang} is actually {id} in the first two handlers. It appears - // parameters as part of the path must be of the same ordering relative - // to name or they will not work as expected. - controller.registerHandler(POST, "/_scripts/{lang}", this); - controller.registerHandler(PUT, "/_scripts/{lang}", this); - controller.registerHandler(POST, "/_scripts/{lang}/{id}", this); - controller.registerHandler(PUT, "/_scripts/{lang}/{id}", this); + controller.registerHandler(POST, "/_scripts/{id}", this); + controller.registerHandler(PUT, "/_scripts/{id}", this); + controller.registerHandler(PUT, "/_scripts/{id}/{context}", this); } @Override @@ -54,24 +52,12 @@ public String getName() { @Override public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { String id = request.param("id"); - String lang = request.param("lang"); String context = request.param("context"); - - // In the case where only {lang} is not null, we make it {id} because of - // name ordering issues in the handlers' paths. - if (id == null) { - id = lang; - lang = null; - } - BytesReference content = request.requiredContent(); + XContentType xContentType = request.getXContentType(); + StoredScriptSource source = StoredScriptSource.parse(content, xContentType); - if (lang != null) { - deprecationLogger.deprecated( - "specifying lang [" + lang + "] as part of the url path is deprecated, use request content instead"); - } - - PutStoredScriptRequest putRequest = new PutStoredScriptRequest(id, lang, context, content, request.getXContentType()); + PutStoredScriptRequest putRequest = new PutStoredScriptRequest(id, context, content, request.getXContentType(), source); return channel -> client.admin().cluster().putStoredScript(putRequest, new AcknowledgedRestListener<>(channel)); } } diff --git a/core/src/main/java/org/elasticsearch/script/ScriptMetaData.java b/core/src/main/java/org/elasticsearch/script/ScriptMetaData.java index 63b5e2e46ab8d..a6e55dbb898b8 100644 --- a/core/src/main/java/org/elasticsearch/script/ScriptMetaData.java +++ b/core/src/main/java/org/elasticsearch/script/ScriptMetaData.java @@ -45,10 +45,7 @@ /** * {@link ScriptMetaData} is used to store user-defined scripts - * as part of the {@link ClusterState}. Currently scripts can - * be stored as part of the new namespace for a stored script where - * only an id is used or as part of the deprecated namespace where - * both a language and an id are used. + * as part of the {@link ClusterState} using only an id as the key. */ public final class ScriptMetaData implements MetaData.Custom, Writeable, ToXContent { @@ -71,73 +68,28 @@ public Builder(ScriptMetaData previous) { } /** - * Add a new script to the existing stored scripts. The script will be added under - * both the new namespace and the deprecated namespace, so that look ups under - * the deprecated namespace will continue to work. Should a script already exist under - * the new namespace using a different language, it will be replaced and a deprecation - * warning will be issued. The replaced script will still exist under the deprecated - * namespace and can continue to be looked up this way until it is deleted. - *

- * Take for example script 'A' with lang 'L0' and data 'D0'. If we add script 'A' to the - * empty set, the scripts {@link Map} will be ["A" -- D0, "A#L0" -- D0]. If a script - * 'A' with lang 'L1' and data 'D1' is then added, the scripts {@link Map} will be - * ["A" -- D1, "A#L1" -- D1, "A#L0" -- D0]. + * Add a new script to the existing stored scripts based on a user-specified id. If + * a script with the same id already exists it will be overwritten. * @param id The user-specified id to use for the look up. * @param source The user-specified stored script data held in {@link StoredScriptSource}. */ public Builder storeScript(String id, StoredScriptSource source) { - StoredScriptSource previous = scripts.put(id, source); - scripts.put(source.getLang() + "#" + id, source); - - if (previous != null && previous.getLang().equals(source.getLang()) == false) { - DEPRECATION_LOGGER.deprecated("stored script [" + id + "] already exists using a different lang " + - "[" + previous.getLang() + "], the new namespace for stored scripts will only use (id) instead of (lang, id)"); - } + scripts.put(id, source); return this; } /** - * Delete a script from the existing stored scripts. The script will be removed from the - * new namespace if the script language matches the current script under the same id or - * if the script language is {@code null}. The script will be removed from the deprecated - * namespace on any delete either using using the specified lang parameter or the language - * found from looking up the script in the new namespace. - *

- * Take for example a scripts {@link Map} with {"A" -- D1, "A#L1" -- D1, "A#L0" -- D0}. - * If a script is removed specified by an id 'A' and lang {@code null} then the scripts - * {@link Map} will be {"A#L0" -- D0}. To remove the final script, the deprecated - * namespace must be used, so an id 'A' and lang 'L0' would need to be specified. + * Delete a script from the existing stored scripts based on a user-specified id. * @param id The user-specified id to use for the look up. - * @param lang The user-specified language to use for the look up if using the deprecated - * namespace, otherwise {@code null}. */ - public Builder deleteScript(String id, String lang) { - StoredScriptSource source = scripts.get(id); - - if (lang == null) { - if (source == null) { - throw new ResourceNotFoundException("stored script [" + id + "] does not exist and cannot be deleted"); - } + public Builder deleteScript(String id) { + StoredScriptSource deleted = scripts.remove(id); - lang = source.getLang(); + if (deleted == null) { + throw new ResourceNotFoundException("stored script [" + id + "] does not exist and cannot be deleted"); } - if (source != null) { - if (lang.equals(source.getLang())) { - scripts.remove(id); - } - } - - source = scripts.get(lang + "#" + id); - - if (source == null) { - throw new ResourceNotFoundException( - "stored script [" + id + "] using lang [" + lang + "] does not exist and cannot be deleted"); - } - - scripts.remove(lang + "#" + id); - return this; } @@ -193,23 +145,13 @@ static ScriptMetaData putStoredScript(ScriptMetaData previous, String id, Stored * Convenience method to build and return a new * {@link ScriptMetaData} deleting the specified stored script. */ - static ScriptMetaData deleteStoredScript(ScriptMetaData previous, String id, String lang) { + static ScriptMetaData deleteStoredScript(ScriptMetaData previous, String id) { Builder builder = new ScriptMetaData.Builder(previous); - builder.deleteScript(id, lang); + builder.deleteScript(id); return builder.build(); } - /** - * Standard logger necessary for allocation of the deprecation logger. - */ - private static final Logger LOGGER = ESLoggerFactory.getLogger(ScriptMetaData.class); - - /** - * Deprecation logger necessary for namespace changes related to stored scripts. - */ - private static final DeprecationLogger DEPRECATION_LOGGER = new DeprecationLogger(LOGGER); - /** * The type of {@link ClusterState} data. */ @@ -218,7 +160,7 @@ static ScriptMetaData deleteStoredScript(ScriptMetaData previous, String id, Str /** * This will parse XContent into {@link ScriptMetaData}. * - * The following format will be parsed for the new namespace: + * The following format will be parsed: * * {@code * { @@ -228,23 +170,15 @@ static ScriptMetaData deleteStoredScript(ScriptMetaData previous, String id, Str * } * } * - * The following format will be parsed for the deprecated namespace: - * - * {@code - * { - * "" : "", - * "" : "", - * ... - * } - * } - * - * Note when using the deprecated namespace, the language will be pulled from - * the id and options will be set to an empty {@link Map}. + * When loading from a source prior to 6.0, if multiple scripts + * using the old namespace id format of [lang#id] are found to have the + * same id but different languages an error will occur. */ public static ScriptMetaData fromXContent(XContentParser parser) throws IOException { Map scripts = new HashMap<>(); String id = null; StoredScriptSource source; + StoredScriptSource exists; Token token = parser.currentToken(); @@ -270,13 +204,25 @@ public static ScriptMetaData fromXContent(XContentParser parser) throws IOExcept } int split = id.indexOf('#'); + String lang; if (split == -1) { throw new IllegalArgumentException("illegal stored script id [" + id + "], does not contain lang"); } else { - source = new StoredScriptSource(id.substring(0, split), parser.text(), Collections.emptyMap()); + lang = id.substring(0, split); + id = id.substring(split + 1); + source = new StoredScriptSource(lang, parser.text(), Collections.emptyMap()); + } + + exists = scripts.get(id); + + if (exists == null) { + scripts.put(id, source); + } else if (exists.getLang().equals(lang) == false) { + throw new IllegalArgumentException("illegal stored script, id [" + id + "] used for multiple scripts with " + + "different languages [" + exists.getLang() + "] and [" + lang + "]; scripts using the old namespace " + + "of [lang#id] as a stored script id will have to be updated to use only the new namespace of [id]"); } - scripts.put(id, source); id = null; @@ -287,8 +233,18 @@ public static ScriptMetaData fromXContent(XContentParser parser) throws IOExcept "unexpected token [" + token + "], expected [, , {]"); } + exists = scripts.get(id); source = StoredScriptSource.fromXContent(parser); - scripts.put(id, source); + + if (exists == null) { + scripts.put(id, source); + } else if (exists.getLang().equals(source.getLang()) == false) { + throw new IllegalArgumentException("illegal stored script, id [" + id + "] used for multiple scripts with " + + "different languages [" + exists.getLang() + "] and [" + source.getLang() + "]; scripts using the old " + + "namespace of [lang#id] as a stored script id will have to be updated to use only the new namespace of [id]"); + } + + id = null; break; default: @@ -421,16 +377,10 @@ public EnumSet context() { } /** - * Retrieves a stored script from the new namespace if lang is {@code null}. - * Otherwise, returns a stored script from the deprecated namespace. Either - * way an id is required. + * Retrieves a stored script based on a user-specified id. */ - StoredScriptSource getStoredScript(String id, String lang) { - if (lang == null) { - return scripts.get(id); - } else { - return scripts.get(lang + "#" + id); - } + StoredScriptSource getStoredScript(String id) { + return scripts.get(id); } @Override diff --git a/core/src/main/java/org/elasticsearch/script/ScriptService.java b/core/src/main/java/org/elasticsearch/script/ScriptService.java index 8673980b76df8..17b9fbb57359f 100644 --- a/core/src/main/java/org/elasticsearch/script/ScriptService.java +++ b/core/src/main/java/org/elasticsearch/script/ScriptService.java @@ -237,7 +237,7 @@ public FactoryType compile(Script script, ScriptContext listener) { - if (request.lang() != null && isLangSupported(request.lang()) == false) { - throw new IllegalArgumentException("unable to delete stored script with unsupported lang [" + request.lang() +"]"); - } - clusterService.submitStateUpdateTask("delete-script-" + request.id(), new AckedClusterStateUpdateTask(request, listener) { @@ -449,7 +445,7 @@ protected DeleteStoredScriptResponse newResponse(boolean acknowledged) { @Override public ClusterState execute(ClusterState currentState) throws Exception { ScriptMetaData smd = currentState.metaData().custom(ScriptMetaData.TYPE); - smd = ScriptMetaData.deleteStoredScript(smd, request.id(), request.lang()); + smd = ScriptMetaData.deleteStoredScript(smd, request.id()); MetaData.Builder mdb = MetaData.builder(currentState.getMetaData()).putCustom(ScriptMetaData.TYPE, smd); return ClusterState.builder(currentState).metaData(mdb).build(); @@ -461,7 +457,7 @@ public StoredScriptSource getStoredScript(ClusterState state, GetStoredScriptReq ScriptMetaData scriptMetadata = state.metaData().custom(ScriptMetaData.TYPE); if (scriptMetadata != null) { - return scriptMetadata.getStoredScript(request.id(), request.lang()); + return scriptMetadata.getStoredScript(request.id()); } else { return null; } diff --git a/core/src/main/java/org/elasticsearch/script/StoredScriptSource.java b/core/src/main/java/org/elasticsearch/script/StoredScriptSource.java index 4c71b05a5082c..52ab99cc5cbb5 100644 --- a/core/src/main/java/org/elasticsearch/script/StoredScriptSource.java +++ b/core/src/main/java/org/elasticsearch/script/StoredScriptSource.java @@ -238,13 +238,10 @@ private StoredScriptSource build() { * Also templates may be part of the 'source' parameter in a script. The Parser * can handle this case as well. * - * @param lang An optional parameter to allow for use of the deprecated stored - * script namespace. This will be used to specify the language - * coming in as a url parameter from a request or for stored templates. * @param content The content from the request to be parsed as described above. * @return The parsed {@link StoredScriptSource}. */ - public static StoredScriptSource parse(String lang, BytesReference content, XContentType xContentType) { + public static StoredScriptSource parse(BytesReference content, XContentType xContentType) { try (XContentParser parser = xContentType.xContent().createParser(NamedXContentRegistry.EMPTY, content)) { Token token = parser.nextToken(); @@ -254,6 +251,10 @@ public static StoredScriptSource parse(String lang, BytesReference content, XCon token = parser.nextToken(); + if (token == Token.END_OBJECT) { + return new StoredScriptSource(Script.DEFAULT_TEMPLATE_LANG, "", Collections.emptyMap()); + } + if (token != Token.FIELD_NAME) { throw new ParsingException(parser.getTokenLocation(), "unexpected token [" + token + ", expected [" + SCRIPT_PARSE_FIELD.getPreferredName() + ", " + TEMPLATE_PARSE_FIELD.getPreferredName()); @@ -264,37 +265,17 @@ public static StoredScriptSource parse(String lang, BytesReference content, XCon if (SCRIPT_PARSE_FIELD.getPreferredName().equals(name)) { token = parser.nextToken(); - if (token == Token.VALUE_STRING) { - if (lang == null) { - throw new IllegalArgumentException( - "must specify lang as a url parameter when using the deprecated stored script namespace"); - } - - return new StoredScriptSource(lang, parser.text(), Collections.emptyMap()); - } else if (token == Token.START_OBJECT) { - if (lang == null) { - return PARSER.apply(parser, null).build(); - } else { - //this is really for search templates, that need to be converted to json format - try (XContentBuilder builder = XContentFactory.jsonBuilder()) { - builder.copyCurrentStructure(parser); - return new StoredScriptSource(lang, builder.string(), Collections.emptyMap()); - } - } - + if (token == Token.START_OBJECT) { + return PARSER.apply(parser, null).build(); } else { throw new ParsingException(parser.getTokenLocation(), "unexpected token [" + token + "], expected [{, ]"); } } else { - if (lang == null) { - throw new IllegalArgumentException("unexpected stored script format"); - } - if (TEMPLATE_PARSE_FIELD.getPreferredName().equals(name)) { token = parser.nextToken(); if (token == Token.VALUE_STRING) { - return new StoredScriptSource(lang, parser.text(), Collections.emptyMap()); + return new StoredScriptSource(Script.DEFAULT_TEMPLATE_LANG, parser.text(), Collections.emptyMap()); } } @@ -307,7 +288,7 @@ public static StoredScriptSource parse(String lang, BytesReference content, XCon builder.copyCurrentStructure(parser); } - return new StoredScriptSource(lang, builder.string(), Collections.emptyMap()); + return new StoredScriptSource(Script.DEFAULT_TEMPLATE_LANG, builder.string(), Collections.emptyMap()); } } } catch (IOException ioe) { @@ -365,7 +346,7 @@ public StoredScriptSource(String source) { /** * Standard StoredScriptSource constructor. * @param lang The language to compile the script with. Must not be {@code null}. - * @param source The source source to compile with. Must not be {@code null}. + * @param source The source source to compile with. Must not be {@code null}. * @param options Compiler options to be compiled with. Must not be {@code null}, * use an empty {@link Map} to represent no options. */ diff --git a/core/src/test/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptRequestTests.java b/core/src/test/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptRequestTests.java index 2e9239a2c3b2f..bd12d58b1cbcd 100644 --- a/core/src/test/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptRequestTests.java +++ b/core/src/test/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptRequestTests.java @@ -19,7 +19,6 @@ package org.elasticsearch.action.admin.cluster.storedscripts; -import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.test.ESTestCase; @@ -31,7 +30,7 @@ public class GetStoredScriptRequestTests extends ESTestCase { public void testGetIndexedScriptRequestSerialization() throws IOException { - GetStoredScriptRequest request = new GetStoredScriptRequest("lang", "id"); + GetStoredScriptRequest request = new GetStoredScriptRequest("id"); BytesStreamOutput out = new BytesStreamOutput(); out.setVersion(randomVersion(random())); @@ -43,6 +42,5 @@ public void testGetIndexedScriptRequestSerialization() throws IOException { request2.readFrom(in); assertThat(request2.id(), equalTo(request.id())); - assertThat(request2.lang(), equalTo(request.lang())); } } diff --git a/core/src/test/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptRequestTests.java b/core/src/test/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptRequestTests.java index a60722d3f42a3..8562b5cabd8b6 100644 --- a/core/src/test/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptRequestTests.java +++ b/core/src/test/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptRequestTests.java @@ -24,16 +24,18 @@ import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.script.StoredScriptSource; import org.elasticsearch.test.ESTestCase; import java.io.IOException; import java.util.Base64; +import java.util.Collections; public class PutStoredScriptRequestTests extends ESTestCase { public void testSerialization() throws IOException { - PutStoredScriptRequest storedScriptRequest = - new PutStoredScriptRequest("foo", "bar", "context", new BytesArray("{}"), XContentType.JSON); + PutStoredScriptRequest storedScriptRequest = new PutStoredScriptRequest("bar", "context", new BytesArray("{}"), XContentType.JSON, + new StoredScriptSource("foo", "bar", Collections.emptyMap())); assertEquals(XContentType.JSON, storedScriptRequest.xContentType()); try (BytesStreamOutput output = new BytesStreamOutput()) { @@ -43,7 +45,6 @@ public void testSerialization() throws IOException { PutStoredScriptRequest serialized = new PutStoredScriptRequest(); serialized.readFrom(in); assertEquals(XContentType.JSON, serialized.xContentType()); - assertEquals(storedScriptRequest.lang(), serialized.lang()); assertEquals(storedScriptRequest.id(), serialized.id()); assertEquals(storedScriptRequest.context(), serialized.context()); } @@ -59,7 +60,6 @@ public void testSerializationBwc() throws IOException { PutStoredScriptRequest serialized = new PutStoredScriptRequest(); serialized.readFrom(in); assertEquals(XContentType.JSON, serialized.xContentType()); - assertEquals("mustache", serialized.lang()); assertEquals("script", serialized.id()); assertEquals(new BytesArray("{}"), serialized.content()); diff --git a/core/src/test/java/org/elasticsearch/client/AbstractClientHeadersTestCase.java b/core/src/test/java/org/elasticsearch/client/AbstractClientHeadersTestCase.java index 67318b7b21f80..8d9c3ee2d6f44 100644 --- a/core/src/test/java/org/elasticsearch/client/AbstractClientHeadersTestCase.java +++ b/core/src/test/java/org/elasticsearch/client/AbstractClientHeadersTestCase.java @@ -104,7 +104,7 @@ public void testActions() { client.prepareGet("idx", "type", "id").execute(new AssertingActionListener<>(GetAction.NAME, client.threadPool())); client.prepareSearch().execute(new AssertingActionListener<>(SearchAction.NAME, client.threadPool())); client.prepareDelete("idx", "type", "id").execute(new AssertingActionListener<>(DeleteAction.NAME, client.threadPool())); - client.admin().cluster().prepareDeleteStoredScript("lang", "id").execute(new AssertingActionListener<>(DeleteStoredScriptAction.NAME, client.threadPool())); + client.admin().cluster().prepareDeleteStoredScript("id").execute(new AssertingActionListener<>(DeleteStoredScriptAction.NAME, client.threadPool())); client.prepareIndex("idx", "type", "id").setSource("source", XContentType.JSON).execute(new AssertingActionListener<>(IndexAction.NAME, client.threadPool())); // choosing arbitrary cluster admin actions to test diff --git a/core/src/test/java/org/elasticsearch/script/ScriptMetaDataTests.java b/core/src/test/java/org/elasticsearch/script/ScriptMetaDataTests.java index f1315b9cdc49a..1c7ef2de07572 100644 --- a/core/src/test/java/org/elasticsearch/script/ScriptMetaDataTests.java +++ b/core/src/test/java/org/elasticsearch/script/ScriptMetaDataTests.java @@ -21,6 +21,7 @@ import org.elasticsearch.cluster.DiffableUtils; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; @@ -32,81 +33,103 @@ public class ScriptMetaDataTests extends AbstractSerializingTestCase { + public void testFromXContentLoading() throws Exception { + // failure to load to old namespace scripts with the same id but different langs + XContentBuilder builder = XContentFactory.jsonBuilder(); + builder.startObject().field("lang0#id0", "script0").field("lang1#id0", "script1").endObject(); + XContentParser parser0 = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, builder.bytes()); + expectThrows(IllegalArgumentException.class, () -> ScriptMetaData.fromXContent(parser0)); + + // failure to load a new namespace script and old namespace script with the same id but different langs + builder = XContentFactory.jsonBuilder(); + builder.startObject().field("lang0#id0", "script0") + .startObject("id0").field("lang", "lang1").field("source", "script1").endObject().endObject(); + XContentParser parser1 = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, builder.bytes()); + expectThrows(IllegalArgumentException.class, () -> ScriptMetaData.fromXContent(parser1)); + + // failure to load a new namespace script and old namespace script with the same id but different langs with additional scripts + builder = XContentFactory.jsonBuilder(); + builder.startObject().field("lang0#id0", "script0").field("lang0#id1", "script1") + .startObject("id1").field("lang", "lang0").field("source", "script0").endObject() + .startObject("id0").field("lang", "lang1").field("source", "script1").endObject().endObject(); + XContentParser parser2 = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, builder.bytes()); + expectThrows(IllegalArgumentException.class, () -> ScriptMetaData.fromXContent(parser2)); + + // okay to load the same script from the new and old namespace if the lang is the same + builder = XContentFactory.jsonBuilder(); + builder.startObject().field("lang0#id0", "script0") + .startObject("id0").field("lang", "lang0").field("source", "script1").endObject().endObject(); + XContentParser parser3 = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, builder.bytes()); + ScriptMetaData.fromXContent(parser3); + } + public void testGetScript() throws Exception { ScriptMetaData.Builder builder = new ScriptMetaData.Builder(null); XContentBuilder sourceBuilder = XContentFactory.jsonBuilder(); sourceBuilder.startObject().startObject("template").field("field", "value").endObject().endObject(); - builder.storeScript("template", StoredScriptSource.parse("lang", sourceBuilder.bytes(), sourceBuilder.contentType())); + builder.storeScript("template", StoredScriptSource.parse(sourceBuilder.bytes(), sourceBuilder.contentType())); sourceBuilder = XContentFactory.jsonBuilder(); sourceBuilder.startObject().field("template", "value").endObject(); - builder.storeScript("template_field", StoredScriptSource.parse("lang", sourceBuilder.bytes(), sourceBuilder.contentType())); - - sourceBuilder = XContentFactory.jsonBuilder(); - sourceBuilder.startObject().startObject("script").field("field", "value").endObject().endObject(); - builder.storeScript("script", StoredScriptSource.parse("lang", sourceBuilder.bytes(), sourceBuilder.contentType())); - - sourceBuilder = XContentFactory.jsonBuilder(); - sourceBuilder.startObject().field("script", "value").endObject(); - builder.storeScript("script_field", StoredScriptSource.parse("lang", sourceBuilder.bytes(), sourceBuilder.contentType())); + builder.storeScript("template_field", StoredScriptSource.parse(sourceBuilder.bytes(), sourceBuilder.contentType())); sourceBuilder = XContentFactory.jsonBuilder(); - sourceBuilder.startObject().field("field", "value").endObject(); - builder.storeScript("any", StoredScriptSource.parse("lang", sourceBuilder.bytes(), sourceBuilder.contentType())); + sourceBuilder.startObject().startObject("script").field("lang", "_lang").field("source", "_source").endObject().endObject(); + builder.storeScript("script", StoredScriptSource.parse(sourceBuilder.bytes(), sourceBuilder.contentType())); ScriptMetaData scriptMetaData = builder.build(); - assertEquals("{\"field\":\"value\"}", scriptMetaData.getStoredScript("template", "lang").getSource()); - assertEquals("value", scriptMetaData.getStoredScript("template_field", "lang").getSource()); - assertEquals("{\"field\":\"value\"}", scriptMetaData.getStoredScript("script", "lang").getSource()); - assertEquals("value", scriptMetaData.getStoredScript("script_field", "lang").getSource()); - assertEquals("{\"field\":\"value\"}", scriptMetaData.getStoredScript("any", "lang").getSource()); + assertEquals("_source", scriptMetaData.getStoredScript("script").getSource()); + assertEquals("{\"field\":\"value\"}", scriptMetaData.getStoredScript("template").getSource()); + assertEquals("value", scriptMetaData.getStoredScript("template_field").getSource()); } public void testDiff() throws Exception { ScriptMetaData.Builder builder = new ScriptMetaData.Builder(null); - builder.storeScript("1", StoredScriptSource.parse("lang", new BytesArray("{\"foo\":\"abc\"}"), XContentType.JSON)); - builder.storeScript("2", StoredScriptSource.parse("lang", new BytesArray("{\"foo\":\"def\"}"), XContentType.JSON)); - builder.storeScript("3", StoredScriptSource.parse("lang", new BytesArray("{\"foo\":\"ghi\"}"), XContentType.JSON)); + builder.storeScript("1", StoredScriptSource.parse(new BytesArray("{\"foo\":\"abc\"}"), XContentType.JSON)); + builder.storeScript("2", StoredScriptSource.parse(new BytesArray("{\"foo\":\"def\"}"), XContentType.JSON)); + builder.storeScript("3", StoredScriptSource.parse(new BytesArray("{\"foo\":\"ghi\"}"), XContentType.JSON)); ScriptMetaData scriptMetaData1 = builder.build(); builder = new ScriptMetaData.Builder(scriptMetaData1); - builder.storeScript("2", StoredScriptSource.parse("lang", new BytesArray("{\"foo\":\"changed\"}"), XContentType.JSON)); - builder.deleteScript("3", "lang"); - builder.storeScript("4", StoredScriptSource.parse("lang", new BytesArray("{\"foo\":\"jkl\"}"), XContentType.JSON)); + builder.storeScript("2", StoredScriptSource.parse(new BytesArray("{\"foo\":\"changed\"}"), XContentType.JSON)); + builder.deleteScript("3"); + builder.storeScript("4", StoredScriptSource.parse(new BytesArray("{\"foo\":\"jkl\"}"), XContentType.JSON)); ScriptMetaData scriptMetaData2 = builder.build(); ScriptMetaData.ScriptMetadataDiff diff = (ScriptMetaData.ScriptMetadataDiff) scriptMetaData2.diff(scriptMetaData1); - assertEquals(2, ((DiffableUtils.MapDiff) diff.pipelines).getDeletes().size()); + assertEquals(1, ((DiffableUtils.MapDiff) diff.pipelines).getDeletes().size()); assertEquals("3", ((DiffableUtils.MapDiff) diff.pipelines).getDeletes().get(0)); - assertEquals(2, ((DiffableUtils.MapDiff) diff.pipelines).getDiffs().size()); + assertEquals(1, ((DiffableUtils.MapDiff) diff.pipelines).getDiffs().size()); assertNotNull(((DiffableUtils.MapDiff) diff.pipelines).getDiffs().get("2")); - assertEquals(2, ((DiffableUtils.MapDiff) diff.pipelines).getUpserts().size()); + assertEquals(1, ((DiffableUtils.MapDiff) diff.pipelines).getUpserts().size()); assertNotNull(((DiffableUtils.MapDiff) diff.pipelines).getUpserts().get("4")); ScriptMetaData result = (ScriptMetaData) diff.apply(scriptMetaData1); - assertEquals("{\"foo\":\"abc\"}", result.getStoredScript("1", "lang").getSource()); - assertEquals("{\"foo\":\"changed\"}", result.getStoredScript("2", "lang").getSource()); - assertEquals("{\"foo\":\"jkl\"}", result.getStoredScript("4", "lang").getSource()); + assertEquals("{\"foo\":\"abc\"}", result.getStoredScript("1").getSource()); + assertEquals("{\"foo\":\"changed\"}", result.getStoredScript("2").getSource()); + assertEquals("{\"foo\":\"jkl\"}", result.getStoredScript("4").getSource()); } public void testBuilder() { ScriptMetaData.Builder builder = new ScriptMetaData.Builder(null); - builder.storeScript("_id", StoredScriptSource.parse("_lang", new BytesArray("{\"script\":\"1 + 1\"}"), XContentType.JSON)); + builder.storeScript("_id", StoredScriptSource.parse( + new BytesArray("{\"script\": {\"lang\": \"painless\", \"source\": \"1 + 1\"} }"), XContentType.JSON)); ScriptMetaData result = builder.build(); - assertEquals("1 + 1", result.getStoredScript("_id", "_lang").getSource()); + assertEquals("1 + 1", result.getStoredScript("_id").getSource()); } private ScriptMetaData randomScriptMetaData(XContentType sourceContentType) throws IOException { ScriptMetaData.Builder builder = new ScriptMetaData.Builder(null); int numScripts = scaledRandomIntBetween(0, 32); for (int i = 0; i < numScripts; i++) { - String lang = randomAlphaOfLength(4); XContentBuilder sourceBuilder = XContentBuilder.builder(sourceContentType.xContent()); - sourceBuilder.startObject().field("script", randomAlphaOfLength(4)).endObject(); + sourceBuilder.startObject().field("script").startObject() + .field("lang", randomAlphaOfLength(4)).field("source", randomAlphaOfLength(10)) + .endObject().endObject(); builder.storeScript(randomAlphaOfLength(i + 1), - StoredScriptSource.parse(lang, sourceBuilder.bytes(), sourceBuilder.contentType())); + StoredScriptSource.parse(sourceBuilder.bytes(), sourceBuilder.contentType())); } return builder.build(); } diff --git a/core/src/test/java/org/elasticsearch/script/ScriptServiceTests.java b/core/src/test/java/org/elasticsearch/script/ScriptServiceTests.java index 3574060a5b905..206d0d6390a41 100644 --- a/core/src/test/java/org/elasticsearch/script/ScriptServiceTests.java +++ b/core/src/test/java/org/elasticsearch/script/ScriptServiceTests.java @@ -75,10 +75,7 @@ private void buildScriptService(Settings additionalSettings) throws IOException Settings finalSettings = Settings.builder().put(baseSettings).put(additionalSettings).build(); scriptService = new ScriptService(finalSettings, engines, contexts) { @Override - StoredScriptSource getScriptFromClusterState(String id, String lang) { - if (lang != null) { - throw new IllegalArgumentException("expected null lang in test"); - } + StoredScriptSource getScriptFromClusterState(String id) { //mock the script that gets retrieved from an index return new StoredScriptSource("test", "1+1", Collections.emptyMap()); } @@ -233,28 +230,31 @@ public void testCacheEvictionCountedInCacheEvictionsStats() throws IOException { } public void testStoreScript() throws Exception { - BytesReference script = XContentFactory.jsonBuilder().startObject() - .field("script", "abc") - .endObject().bytes(); - - ScriptMetaData scriptMetaData = ScriptMetaData.putStoredScript(null, "_id", - StoredScriptSource.parse("_lang", script, XContentType.JSON)); + BytesReference script = XContentFactory.jsonBuilder() + .startObject() + .field("script") + .startObject() + .field("lang", "_lang") + .field("source", "abc") + .endObject() + .endObject().bytes(); + ScriptMetaData scriptMetaData = ScriptMetaData.putStoredScript(null, "_id", StoredScriptSource.parse(script, XContentType.JSON)); assertNotNull(scriptMetaData); - assertEquals("abc", scriptMetaData.getStoredScript("_id", "_lang").getSource()); + assertEquals("abc", scriptMetaData.getStoredScript("_id").getSource()); } public void testDeleteScript() throws Exception { ScriptMetaData scriptMetaData = ScriptMetaData.putStoredScript(null, "_id", - StoredScriptSource.parse("_lang", new BytesArray("{\"script\":\"abc\"}"), XContentType.JSON)); - scriptMetaData = ScriptMetaData.deleteStoredScript(scriptMetaData, "_id", "_lang"); + StoredScriptSource.parse(new BytesArray("{\"script\": {\"lang\": \"_lang\", \"source\": \"abc\"} }"), XContentType.JSON)); + scriptMetaData = ScriptMetaData.deleteStoredScript(scriptMetaData, "_id"); assertNotNull(scriptMetaData); - assertNull(scriptMetaData.getStoredScript("_id", "_lang")); + assertNull(scriptMetaData.getStoredScript("_id")); ScriptMetaData errorMetaData = scriptMetaData; ResourceNotFoundException e = expectThrows(ResourceNotFoundException.class, () -> { - ScriptMetaData.deleteStoredScript(errorMetaData, "_id", "_lang"); + ScriptMetaData.deleteStoredScript(errorMetaData, "_id"); }); - assertEquals("stored script [_id] using lang [_lang] does not exist and cannot be deleted", e.getMessage()); + assertEquals("stored script [_id] does not exist and cannot be deleted", e.getMessage()); } public void testGetStoredScript() throws Exception { @@ -263,14 +263,14 @@ public void testGetStoredScript() throws Exception { .metaData(MetaData.builder() .putCustom(ScriptMetaData.TYPE, new ScriptMetaData.Builder(null).storeScript("_id", - StoredScriptSource.parse("_lang", new BytesArray("{\"script\":\"abc\"}"), XContentType.JSON)).build())) + StoredScriptSource.parse(new BytesArray("{\"script\": {\"lang\": \"_lang\", \"source\": \"abc\"} }"), + XContentType.JSON)).build())) .build(); - assertEquals("abc", scriptService.getStoredScript(cs, new GetStoredScriptRequest("_id", "_lang")).getSource()); - assertNull(scriptService.getStoredScript(cs, new GetStoredScriptRequest("_id2", "_lang"))); + assertEquals("abc", scriptService.getStoredScript(cs, new GetStoredScriptRequest("_id")).getSource()); cs = ClusterState.builder(new ClusterName("_name")).build(); - assertNull(scriptService.getStoredScript(cs, new GetStoredScriptRequest("_id", "_lang"))); + assertNull(scriptService.getStoredScript(cs, new GetStoredScriptRequest("_id"))); } private void assertCompileRejected(String lang, String script, ScriptType scriptType, ScriptContext scriptContext) { diff --git a/core/src/test/java/org/elasticsearch/script/StoredScriptSourceTests.java b/core/src/test/java/org/elasticsearch/script/StoredScriptSourceTests.java index a99c897ec3445..2784e47b470f3 100644 --- a/core/src/test/java/org/elasticsearch/script/StoredScriptSourceTests.java +++ b/core/src/test/java/org/elasticsearch/script/StoredScriptSourceTests.java @@ -48,7 +48,7 @@ protected StoredScriptSource createTestInstance() { if (randomBoolean()) { options.put(Script.CONTENT_TYPE_OPTION, xContentType.mediaType()); } - return StoredScriptSource.parse(lang, template.bytes(), xContentType); + return StoredScriptSource.parse(template.bytes(), xContentType); } catch (IOException e) { throw new AssertionError("Failed to create test instance", e); } diff --git a/core/src/test/java/org/elasticsearch/script/StoredScriptTests.java b/core/src/test/java/org/elasticsearch/script/StoredScriptTests.java index 6c2a0caf7208b..633e0454249da 100644 --- a/core/src/test/java/org/elasticsearch/script/StoredScriptTests.java +++ b/core/src/test/java/org/elasticsearch/script/StoredScriptTests.java @@ -32,7 +32,6 @@ import java.util.Collections; import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.nullValue; @@ -41,152 +40,24 @@ public class StoredScriptTests extends AbstractSerializingTestCase ScriptMetaData.deleteStoredScript(null, "test", "lang")); - assertThat(rnfe.getMessage(), equalTo("stored script [test] using lang [lang] does not exist and cannot be deleted")); - - rnfe = expectThrows(ResourceNotFoundException.class, () -> ScriptMetaData.deleteStoredScript(null, "test", null)); + expectThrows(ResourceNotFoundException.class, () -> ScriptMetaData.deleteStoredScript(null, "test")); assertThat(rnfe.getMessage(), equalTo("stored script [test] does not exist and cannot be deleted")); } public void testSourceParsing() throws Exception { // simple script value string try (XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON)) { - builder.startObject().field("script", "code").endObject(); + builder.startObject().startObject("script").field("lang", "lang").field("source", "code").endObject().endObject(); - StoredScriptSource parsed = StoredScriptSource.parse("lang", builder.bytes(), XContentType.JSON); + StoredScriptSource parsed = StoredScriptSource.parse(builder.bytes(), XContentType.JSON); StoredScriptSource source = new StoredScriptSource("lang", "code", Collections.emptyMap()); assertThat(parsed, equalTo(source)); @@ -196,8 +67,8 @@ public void testSourceParsing() throws Exception { try (XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON)) { builder.startObject().field("template", "code").endObject(); - StoredScriptSource parsed = StoredScriptSource.parse("lang", builder.bytes(), XContentType.JSON); - StoredScriptSource source = new StoredScriptSource("lang", "code", Collections.emptyMap()); + StoredScriptSource parsed = StoredScriptSource.parse(builder.bytes(), XContentType.JSON); + StoredScriptSource source = new StoredScriptSource("mustache", "code", Collections.emptyMap()); assertThat(parsed, equalTo(source)); } @@ -211,8 +82,8 @@ public void testSourceParsing() throws Exception { code = cb.startObject().field("query", "code").endObject().string(); } - StoredScriptSource parsed = StoredScriptSource.parse("lang", builder.bytes(), XContentType.JSON); - StoredScriptSource source = new StoredScriptSource("lang", code, Collections.emptyMap()); + StoredScriptSource parsed = StoredScriptSource.parse(builder.bytes(), XContentType.JSON); + StoredScriptSource source = new StoredScriptSource("mustache", code, Collections.emptyMap()); assertThat(parsed, equalTo(source)); } @@ -226,23 +97,26 @@ public void testSourceParsing() throws Exception { code = cb.startObject().field("query", "code").endObject().string(); } - StoredScriptSource parsed = StoredScriptSource.parse("lang", builder.bytes(), XContentType.JSON); - StoredScriptSource source = new StoredScriptSource("lang", code, Collections.emptyMap()); + StoredScriptSource parsed = StoredScriptSource.parse(builder.bytes(), XContentType.JSON); + StoredScriptSource source = new StoredScriptSource("mustache", code, Collections.emptyMap()); assertThat(parsed, equalTo(source)); } // complex template using script as the field name try (XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON)) { - builder.startObject().field("script").startObject().field("query", "code").endObject().endObject(); + builder.startObject().startObject("script").field("lang", "mustache") + .startObject("source").field("query", "code").endObject() + .endObject().endObject(); String code; try (XContentBuilder cb = XContentFactory.contentBuilder(builder.contentType())) { code = cb.startObject().field("query", "code").endObject().string(); } - StoredScriptSource parsed = StoredScriptSource.parse("lang", builder.bytes(), XContentType.JSON); - StoredScriptSource source = new StoredScriptSource("lang", code, Collections.emptyMap()); + StoredScriptSource parsed = StoredScriptSource.parse(builder.bytes(), XContentType.JSON); + StoredScriptSource source = new StoredScriptSource("mustache", code, + Collections.singletonMap("content_type", "application/json; charset=UTF-8")); assertThat(parsed, equalTo(source)); } @@ -251,7 +125,7 @@ public void testSourceParsing() throws Exception { try (XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON)) { builder.startObject().field("script").startObject().field("lang", "lang").field("source", "code").endObject().endObject(); - StoredScriptSource parsed = StoredScriptSource.parse(null, builder.bytes(), XContentType.JSON); + StoredScriptSource parsed = StoredScriptSource.parse(builder.bytes(), XContentType.JSON); StoredScriptSource source = new StoredScriptSource("lang", "code", Collections.emptyMap()); assertThat(parsed, equalTo(source)); @@ -261,7 +135,7 @@ public void testSourceParsing() throws Exception { try (XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON)) { builder.startObject().field("script").startObject().field("lang", "lang").field("code", "code").endObject().endObject(); - StoredScriptSource parsed = StoredScriptSource.parse(null, builder.bytes(), XContentType.JSON); + StoredScriptSource parsed = StoredScriptSource.parse(builder.bytes(), XContentType.JSON); StoredScriptSource source = new StoredScriptSource("lang", "code", Collections.emptyMap()); assertThat(parsed, equalTo(source)); @@ -273,7 +147,7 @@ public void testSourceParsing() throws Exception { builder.startObject().field("script").startObject().field("lang", "lang").field("source", "code") .field("options").startObject().endObject().endObject().endObject(); - StoredScriptSource parsed = StoredScriptSource.parse(null, builder.bytes(), XContentType.JSON); + StoredScriptSource parsed = StoredScriptSource.parse(builder.bytes(), XContentType.JSON); StoredScriptSource source = new StoredScriptSource("lang", "code", Collections.emptyMap()); assertThat(parsed, equalTo(source)); @@ -289,7 +163,7 @@ public void testSourceParsing() throws Exception { code = cb.startObject().field("query", "code").endObject().string(); } - StoredScriptSource parsed = StoredScriptSource.parse(null, builder.bytes(), XContentType.JSON); + StoredScriptSource parsed = StoredScriptSource.parse(builder.bytes(), XContentType.JSON); StoredScriptSource source = new StoredScriptSource("lang", code, Collections.singletonMap(Script.CONTENT_TYPE_OPTION, builder.contentType().mediaType())); @@ -298,21 +172,12 @@ public void testSourceParsing() throws Exception { } public void testSourceParsingErrors() throws Exception { - // check for missing lang parameter when parsing a template - try (XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON)) { - builder.startObject().field("template", "code").endObject(); - - IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> - StoredScriptSource.parse(null, builder.bytes(), XContentType.JSON)); - assertThat(iae.getMessage(), equalTo("unexpected stored script format")); - } - // check for missing lang parameter when parsing a script try (XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON)) { builder.startObject().field("script").startObject().field("source", "code").endObject().endObject(); IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> - StoredScriptSource.parse(null, builder.bytes(), XContentType.JSON)); + StoredScriptSource.parse(builder.bytes(), XContentType.JSON)); assertThat(iae.getMessage(), equalTo("must specify lang for stored script")); } @@ -321,7 +186,7 @@ public void testSourceParsingErrors() throws Exception { builder.startObject().field("script").startObject().field("lang", "lang").endObject().endObject(); IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> - StoredScriptSource.parse(null, builder.bytes(), XContentType.JSON)); + StoredScriptSource.parse(builder.bytes(), XContentType.JSON)); assertThat(iae.getMessage(), equalTo("must specify source for stored script")); } @@ -331,7 +196,7 @@ public void testSourceParsingErrors() throws Exception { .startObject("options").field("option", "option").endObject().endObject().endObject(); IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> - StoredScriptSource.parse(null, builder.bytes(), XContentType.JSON)); + StoredScriptSource.parse(builder.bytes(), XContentType.JSON)); assertThat(iae.getMessage(), equalTo("illegal compiler options [{option=option}] specified")); } } diff --git a/core/src/test/java/org/elasticsearch/script/StoredScriptsIT.java b/core/src/test/java/org/elasticsearch/script/StoredScriptsIT.java index 80a8f4deaa741..a1a82c88819a2 100644 --- a/core/src/test/java/org/elasticsearch/script/StoredScriptsIT.java +++ b/core/src/test/java/org/elasticsearch/script/StoredScriptsIT.java @@ -51,35 +51,31 @@ protected Collection> nodePlugins() { public void testBasics() { assertAcked(client().admin().cluster().preparePutStoredScript() - .setLang(LANG) .setId("foobar") - .setContent(new BytesArray("{\"script\":\"1\"}"), XContentType.JSON)); - String script = client().admin().cluster().prepareGetStoredScript(LANG, "foobar") + .setContent(new BytesArray("{\"script\": {\"lang\": \"" + LANG + "\", \"source\": \"1\"} }"), XContentType.JSON)); + String script = client().admin().cluster().prepareGetStoredScript("foobar") .get().getSource().getSource(); assertNotNull(script); assertEquals("1", script); assertAcked(client().admin().cluster().prepareDeleteStoredScript() - .setId("foobar") - .setLang(LANG)); - StoredScriptSource source = client().admin().cluster().prepareGetStoredScript(LANG, "foobar") + .setId("foobar")); + StoredScriptSource source = client().admin().cluster().prepareGetStoredScript("foobar") .get().getSource(); assertNull(source); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> client().admin().cluster().preparePutStoredScript() - .setLang("lang#") .setId("id#") .setContent(new BytesArray("{}"), XContentType.JSON) .get()); - assertEquals("Validation Failed: 1: id cannot contain '#' for stored script;" + - "2: lang cannot contain '#' for stored script;", e.getMessage()); + assertEquals("Validation Failed: 1: id cannot contain '#' for stored script;", e.getMessage()); } public void testMaxScriptSize() { IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> client().admin().cluster().preparePutStoredScript() - .setLang(LANG) .setId("foobar") - .setContent(new BytesArray(randomAlphaOfLength(SCRIPT_MAX_SIZE_IN_BYTES + 1)), XContentType.JSON) + .setContent(new BytesArray("{\"script\": { \"lang\": \"" + LANG + "\"," + + " \"source\":\"0123456789abcdef\"} }"), XContentType.JSON) .get() ); assertEquals("exceeded max allowed stored script size in bytes [64] with size [65] for script [foobar]", e.getMessage()); diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/ScriptedMetricIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/ScriptedMetricIT.java index d9efdefba7bab..dab523b7c348d 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/ScriptedMetricIT.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/ScriptedMetricIT.java @@ -26,6 +26,7 @@ import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.script.MockScriptEngine; import org.elasticsearch.script.MockScriptPlugin; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptType; @@ -230,24 +231,24 @@ public void setupSuiteScopeCluster() throws Exception { // the id of the stored script is used in test method while the source of the stored script // must match a predefined script from CustomScriptPlugin.pluginScripts() method assertAcked(client().admin().cluster().preparePutStoredScript() - .setLang(CustomScriptPlugin.NAME) .setId("initScript_stored") - .setContent(new BytesArray("{\"script\":\"vars.multiplier = 3\"}"), XContentType.JSON)); + .setContent(new BytesArray("{\"script\": {\"lang\": \"" + MockScriptPlugin.NAME + "\"," + + " \"source\": \"vars.multiplier = 3\"} }"), XContentType.JSON)); assertAcked(client().admin().cluster().preparePutStoredScript() - .setLang(CustomScriptPlugin.NAME) .setId("mapScript_stored") - .setContent(new BytesArray("{\"script\":\"_agg.add(vars.multiplier)\"}"), XContentType.JSON)); + .setContent(new BytesArray("{\"script\": {\"lang\": \"" + MockScriptPlugin.NAME + "\"," + + " \"source\": \"_agg.add(vars.multiplier)\"} }"), XContentType.JSON)); assertAcked(client().admin().cluster().preparePutStoredScript() - .setLang(CustomScriptPlugin.NAME) .setId("combineScript_stored") - .setContent(new BytesArray("{\"script\":\"sum agg values as a new aggregation\"}"), XContentType.JSON)); + .setContent(new BytesArray("{\"script\": {\"lang\": \"" + MockScriptPlugin.NAME + "\"," + + " \"source\": \"sum agg values as a new aggregation\"} }"), XContentType.JSON)); assertAcked(client().admin().cluster().preparePutStoredScript() - .setLang(CustomScriptPlugin.NAME) .setId("reduceScript_stored") - .setContent(new BytesArray("{\"script\":\"sum aggs of agg values as a new aggregation\"}"), XContentType.JSON)); + .setContent(new BytesArray("{\"script\": {\"lang\": \"" + MockScriptPlugin.NAME + "\"," + + " \"source\": \"sum aggs of agg values as a new aggregation\"} }"), XContentType.JSON)); indexRandom(true, builders); ensureSearchable(); diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/pipeline/BucketScriptIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/pipeline/BucketScriptIT.java index c216b632c9517..398044edcaf53 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/pipeline/BucketScriptIT.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/pipeline/BucketScriptIT.java @@ -481,9 +481,9 @@ public void testInlineScriptInsertZeros() { public void testStoredScript() { assertAcked(client().admin().cluster().preparePutStoredScript() .setId("my_script") - .setLang(CustomScriptPlugin.NAME) // Script source is not interpreted but it references a pre-defined script from CustomScriptPlugin - .setContent(new BytesArray("{ \"script\": \"my_script\" }"), XContentType.JSON)); + .setContent(new BytesArray("{ \"script\": {\"lang\": \"" + CustomScriptPlugin.NAME + "\"," + + " \"source\": \"my_script\" } }"), XContentType.JSON)); SearchResponse response = client() .prepareSearch("idx") diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/pipeline/BucketSelectorIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/pipeline/BucketSelectorIT.java index d700273dc2ad7..9ea4f813dff0f 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/pipeline/BucketSelectorIT.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/pipeline/BucketSelectorIT.java @@ -433,9 +433,9 @@ public void testInlineScriptInsertZeros() { public void testStoredScript() { assertAcked(client().admin().cluster().preparePutStoredScript() .setId("my_script") - .setLang(CustomScriptPlugin.NAME) // Source is not interpreted but my_script is defined in CustomScriptPlugin - .setContent(new BytesArray("{ \"script\": \"Double.isNaN(_value0) ? false : (_value0 + _value1 > 100)\" }"), + .setContent(new BytesArray("{ \"script\": { \"lang\": \"" + CustomScriptPlugin.NAME + "\", " + + "\"source\": \"Double.isNaN(_value0) ? false : (_value0 + _value1 > 100)\" } }"), XContentType.JSON)); Script script = new Script(ScriptType.STORED, null, "my_script", Collections.emptyMap()); diff --git a/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java index 4d00b1a91eaf9..6e778181590e5 100644 --- a/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java +++ b/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java @@ -541,9 +541,9 @@ public void testIncludeGlobalState() throws Exception { if(testScript) { logger.info("--> creating test script"); assertAcked(client().admin().cluster().preparePutStoredScript() - .setLang(MockScriptEngine.NAME) .setId("foobar") - .setContent(new BytesArray("{\"script\":\"1\"}"), XContentType.JSON)); + .setContent(new BytesArray( + "{\"script\": { \"lang\": \"" + MockScriptEngine.NAME + "\", \"source\": \"1\"} }"), XContentType.JSON)); } logger.info("--> snapshot without global state"); @@ -572,7 +572,7 @@ public void testIncludeGlobalState() throws Exception { if (testScript) { logger.info("--> delete test script"); - assertAcked(client().admin().cluster().prepareDeleteStoredScript(MockScriptEngine.NAME, "foobar").get()); + assertAcked(client().admin().cluster().prepareDeleteStoredScript("foobar").get()); } logger.info("--> try restoring cluster state from snapshot without global state"); @@ -601,7 +601,7 @@ public void testIncludeGlobalState() throws Exception { if (testScript) { logger.info("--> check that script is restored"); - GetStoredScriptResponse getStoredScriptResponse = client().admin().cluster().prepareGetStoredScript(MockScriptEngine.NAME, "foobar").get(); + GetStoredScriptResponse getStoredScriptResponse = client().admin().cluster().prepareGetStoredScript("foobar").get(); assertNotNull(getStoredScriptResponse.getSource()); } @@ -631,7 +631,7 @@ public void testIncludeGlobalState() throws Exception { } if (testScript) { - assertAcked(client().admin().cluster().prepareDeleteStoredScript(MockScriptEngine.NAME, "foobar").get()); + assertAcked(client().admin().cluster().prepareDeleteStoredScript("foobar").get()); } getIndexTemplatesResponse = client().admin().indices().prepareGetTemplates().get(); @@ -646,7 +646,7 @@ public void testIncludeGlobalState() throws Exception { getIndexTemplatesResponse = client().admin().indices().prepareGetTemplates().get(); assertIndexTemplateMissing(getIndexTemplatesResponse, "test-template"); assertFalse(client().admin().cluster().prepareGetPipeline("barbaz").get().isFound()); - assertNull(client().admin().cluster().prepareGetStoredScript(MockScriptEngine.NAME, "foobar").get().getSource()); + assertNull(client().admin().cluster().prepareGetStoredScript("foobar").get().getSource()); assertThat(client.prepareSearch("test-idx").setSize(0).get().getHits().getTotalHits(), equalTo(100L)); } diff --git a/docs/reference/migration/migrate_6_0/scripting.asciidoc b/docs/reference/migration/migrate_6_0/scripting.asciidoc index c964f290bc841..5a474927c1a89 100644 --- a/docs/reference/migration/migrate_6_0/scripting.asciidoc +++ b/docs/reference/migration/migrate_6_0/scripting.asciidoc @@ -35,6 +35,13 @@ different from a request that puts a stored script. The language of the script already been stored as part of the cluster state and an `id` is sufficient to access all of the information necessary to execute a stored script. +==== 'lang` can no longer be used when putting, getting, or deleting a stored script + +Stored scripts can no longer have the `lang` parameter specified as part of the url +when performing PUT, GET, and DELETE actions on the `_scripts/` path. All stored +scripts must have a unique `id` as the namespace is only `id` now and no longer `lang` +and `id`. + ==== Stored search template apis removed The PUT, GET and DELETE `_search/template` apis have been removed. Store search templates with the stored scripts apis instead. diff --git a/modules/lang-expression/src/test/java/org/elasticsearch/script/expression/StoredExpressionTests.java b/modules/lang-expression/src/test/java/org/elasticsearch/script/expression/StoredExpressionTests.java index 2fa2c17cc354e..c922392a05ab4 100644 --- a/modules/lang-expression/src/test/java/org/elasticsearch/script/expression/StoredExpressionTests.java +++ b/modules/lang-expression/src/test/java/org/elasticsearch/script/expression/StoredExpressionTests.java @@ -51,9 +51,8 @@ protected Collection> nodePlugins() { public void testAllOpsDisabledIndexedScripts() throws IOException { client().admin().cluster().preparePutStoredScript() - .setLang(ExpressionScriptEngine.NAME) .setId("script1") - .setContent(new BytesArray("{\"script\":\"2\"}"), XContentType.JSON) + .setContent(new BytesArray("{\"script\": {\"lang\": \"expression\", \"source\": \"2\"} }"), XContentType.JSON) .get(); client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}", XContentType.JSON).get(); try { diff --git a/modules/lang-mustache/src/test/java/org/elasticsearch/script/mustache/SearchTemplateIT.java b/modules/lang-mustache/src/test/java/org/elasticsearch/script/mustache/SearchTemplateIT.java index a9da6c187e070..39657bc177736 100644 --- a/modules/lang-mustache/src/test/java/org/elasticsearch/script/mustache/SearchTemplateIT.java +++ b/modules/lang-mustache/src/test/java/org/elasticsearch/script/mustache/SearchTemplateIT.java @@ -151,7 +151,6 @@ public void testTemplateQueryAsEscapedStringWithConditionalClauseAtEnd() throws public void testIndexedTemplateClient() throws Exception { assertAcked(client().admin().cluster().preparePutStoredScript() - .setLang(MustacheScriptEngine.NAME) .setId("testTemplate") .setContent(new BytesArray("{" + "\"template\":{" + @@ -164,7 +163,6 @@ public void testIndexedTemplateClient() throws Exception { assertAcked(client().admin().cluster().preparePutStoredScript() - .setLang(MustacheScriptEngine.NAME) .setId("testTemplate").setContent(new BytesArray("{" + "\"template\":{" + " \"query\":{" + @@ -175,7 +173,7 @@ public void testIndexedTemplateClient() throws Exception { "}"), XContentType.JSON)); GetStoredScriptResponse getResponse = client().admin().cluster() - .prepareGetStoredScript(MustacheScriptEngine.NAME, "testTemplate").get(); + .prepareGetStoredScript("testTemplate").get(); assertNotNull(getResponse.getSource()); BulkRequestBuilder bulkRequestBuilder = client().prepareBulk(); @@ -196,17 +194,14 @@ public void testIndexedTemplateClient() throws Exception { .get(); assertHitCount(searchResponse.getResponse(), 4); - assertAcked(client().admin().cluster() - .prepareDeleteStoredScript(MustacheScriptEngine.NAME, "testTemplate")); + assertAcked(client().admin().cluster().prepareDeleteStoredScript("testTemplate")); - getResponse = client().admin().cluster() - .prepareGetStoredScript(MustacheScriptEngine.NAME, "testTemplate").get(); + getResponse = client().admin().cluster().prepareGetStoredScript("testTemplate").get(); assertNull(getResponse.getSource()); } public void testIndexedTemplate() throws Exception { assertAcked(client().admin().cluster().preparePutStoredScript() - .setLang(MustacheScriptEngine.NAME) .setId("1a") .setContent(new BytesArray("{" + "\"template\":{" + @@ -219,7 +214,6 @@ public void testIndexedTemplate() throws Exception { ), XContentType.JSON) ); assertAcked(client().admin().cluster().preparePutStoredScript() - .setLang(MustacheScriptEngine.NAME) .setId("2") .setContent(new BytesArray("{" + "\"template\":{" + @@ -231,7 +225,6 @@ public void testIndexedTemplate() throws Exception { "}"), XContentType.JSON) ); assertAcked(client().admin().cluster().preparePutStoredScript() - .setLang(MustacheScriptEngine.NAME) .setId("3") .setContent(new BytesArray("{" + "\"template\":{" + @@ -289,13 +282,11 @@ public void testIndexedTemplateOverwrite() throws Exception { int iterations = randomIntBetween(2, 11); for (int i = 1; i < iterations; i++) { assertAcked(client().admin().cluster().preparePutStoredScript() - .setLang(MustacheScriptEngine.NAME) .setId("git01") .setContent(new BytesArray("{\"template\":{\"query\": {\"match\": {\"searchtext\": {\"query\": \"{{P_Keyword1}}\"," + "\"type\": \"ooophrase_prefix\"}}}}}"), XContentType.JSON)); - GetStoredScriptResponse getResponse = client().admin().cluster() - .prepareGetStoredScript(MustacheScriptEngine.NAME, "git01").get(); + GetStoredScriptResponse getResponse = client().admin().cluster().prepareGetStoredScript("git01").get(); assertNotNull(getResponse.getSource()); Map templateParams = new HashMap<>(); @@ -309,7 +300,6 @@ public void testIndexedTemplateOverwrite() throws Exception { assertWarnings("Deprecated field [type] used, replaced by [match_phrase and match_phrase_prefix query]"); assertAcked(client().admin().cluster().preparePutStoredScript() - .setLang(MustacheScriptEngine.NAME) .setId("git01") .setContent(new BytesArray("{\"query\": {\"match\": {\"searchtext\": {\"query\": \"{{P_Keyword1}}\"," + "\"type\": \"phrase_prefix\"}}}}"), XContentType.JSON)); @@ -327,7 +317,6 @@ public void testIndexedTemplateWithArray() throws Exception { String multiQuery = "{\"query\":{\"terms\":{\"theField\":[\"{{#fieldParam}}\",\"{{.}}\",\"{{/fieldParam}}\"]}}}"; assertAcked( client().admin().cluster().preparePutStoredScript() - .setLang(MustacheScriptEngine.NAME) .setId("4") .setContent(jsonBuilder().startObject().field("template", multiQuery).endObject().bytes(), XContentType.JSON) ); diff --git a/modules/lang-painless/src/test/resources/rest-api-spec/test/painless/16_update2.yml b/modules/lang-painless/src/test/resources/rest-api-spec/test/painless/16_update2.yml index c55876a6ae231..3d6f603d4d806 100644 --- a/modules/lang-painless/src/test/resources/rest-api-spec/test/painless/16_update2.yml +++ b/modules/lang-painless/src/test/resources/rest-api-spec/test/painless/16_update2.yml @@ -11,7 +11,7 @@ - do: get_script: - lang: "1" + id: "1" - match: { found: true } - match: { _id: "1" } - match: { "script": {"lang": "painless", "source": "_score * doc['myParent.weight'].value"} } @@ -19,20 +19,20 @@ - do: catch: missing get_script: - lang: "2" + id: "2" - match: { found: false } - match: { _id: "2" } - is_false: script - do: delete_script: - lang: "1" + id: "1" - match: { acknowledged: true } - do: catch: missing delete_script: - lang: "non_existing" + id: "non_existing" - do: catch: request diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/delete_script.json b/rest-api-spec/src/main/resources/rest-api-spec/api/delete_script.json index 7be743e8e78d9..0bc0fc94c85a0 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/delete_script.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/delete_script.json @@ -3,8 +3,8 @@ "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/master/modules-scripting.html", "methods": ["DELETE"], "url": { - "path": "/_scripts/{lang}", - "paths": [ "/_scripts/{lang}", "/_scripts/{lang}/{id}" ], + "path": "/_scripts/{id}", + "paths": [ "/_scripts/{id}" ], "parts": { "id": { "type" : "string", diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/get_script.json b/rest-api-spec/src/main/resources/rest-api-spec/api/get_script.json index c253c6e1fdba8..1bdc546ad03ac 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/get_script.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/get_script.json @@ -3,8 +3,8 @@ "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/master/modules-scripting.html", "methods": ["GET"], "url": { - "path": "/_scripts/{lang}", - "paths": [ "/_scripts/{lang}", "/_scripts/{lang}/{id}" ], + "path": "/_scripts/{id}", + "paths": [ "/_scripts/{id}" ], "parts": { "id": { "type" : "string", diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/put_script.json b/rest-api-spec/src/main/resources/rest-api-spec/api/put_script.json index dce52f787c98f..39b45057ecd8f 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/put_script.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/put_script.json @@ -4,7 +4,7 @@ "methods": ["PUT", "POST"], "url": { "path": "/_scripts/{id}", - "paths": [ "/_scripts/{id}", "/_scripts/{lang}/{id}" ], + "paths": [ "/_scripts/{id}", "/_scripts/{id}/{context}" ], "parts": { "id": { "type" : "string",