diff --git a/core/src/main/java/org/elasticsearch/action/ActionModule.java b/core/src/main/java/org/elasticsearch/action/ActionModule.java index b66dd060205..3e93f699645 100644 --- a/core/src/main/java/org/elasticsearch/action/ActionModule.java +++ b/core/src/main/java/org/elasticsearch/action/ActionModule.java @@ -147,12 +147,12 @@ import org.elasticsearch.action.get.TransportMultiGetAction; import org.elasticsearch.action.get.TransportShardMultiGetAction; import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.TransportIndexAction; -import org.elasticsearch.action.indexedscripts.delete.DeleteIndexedScriptAction; -import org.elasticsearch.action.indexedscripts.delete.TransportDeleteIndexedScriptAction; -import org.elasticsearch.action.indexedscripts.get.GetIndexedScriptAction; -import org.elasticsearch.action.indexedscripts.get.TransportGetIndexedScriptAction; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptAction; -import org.elasticsearch.action.indexedscripts.put.TransportPutIndexedScriptAction; +import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptAction; +import org.elasticsearch.action.admin.cluster.storedscripts.TransportDeleteStoredScriptAction; +import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptAction; +import org.elasticsearch.action.admin.cluster.storedscripts.TransportGetStoredScriptAction; +import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptAction; +import org.elasticsearch.action.admin.cluster.storedscripts.TransportPutStoredScriptAction; import org.elasticsearch.action.ingest.IngestActionFilter; import org.elasticsearch.action.ingest.IngestProxyActionFilter; import org.elasticsearch.action.ingest.DeletePipelineAction; @@ -340,9 +340,9 @@ public class ActionModule extends AbstractModule { registerAction(RenderSearchTemplateAction.INSTANCE, TransportRenderSearchTemplateAction.class); //Indexed scripts - registerAction(PutIndexedScriptAction.INSTANCE, TransportPutIndexedScriptAction.class); - registerAction(GetIndexedScriptAction.INSTANCE, TransportGetIndexedScriptAction.class); - registerAction(DeleteIndexedScriptAction.INSTANCE, TransportDeleteIndexedScriptAction.class); + registerAction(PutStoredScriptAction.INSTANCE, TransportPutStoredScriptAction.class); + registerAction(GetStoredScriptAction.INSTANCE, TransportGetStoredScriptAction.class); + registerAction(DeleteStoredScriptAction.INSTANCE, TransportDeleteStoredScriptAction.class); registerAction(FieldStatsAction.INSTANCE, TransportFieldStatsTransportAction.class); diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/DeleteIndexedScriptAction.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptAction.java similarity index 58% rename from core/src/main/java/org/elasticsearch/action/indexedscripts/delete/DeleteIndexedScriptAction.java rename to core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptAction.java index 4ccbdf7801d..e7686387061 100644 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/DeleteIndexedScriptAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptAction.java @@ -17,29 +17,30 @@ * under the License. */ -package org.elasticsearch.action.indexedscripts.delete; +package org.elasticsearch.action.admin.cluster.storedscripts; import org.elasticsearch.action.Action; import org.elasticsearch.client.ElasticsearchClient; /** */ -public class DeleteIndexedScriptAction extends Action { +public class DeleteStoredScriptAction extends Action { - public static final DeleteIndexedScriptAction INSTANCE = new DeleteIndexedScriptAction(); - public static final String NAME = "indices:data/write/script/delete"; + public static final DeleteStoredScriptAction INSTANCE = new DeleteStoredScriptAction(); + public static final String NAME = "cluster:admin/script/delete"; - private DeleteIndexedScriptAction() { + private DeleteStoredScriptAction() { super(NAME); } @Override - public DeleteIndexedScriptResponse newResponse() { - return new DeleteIndexedScriptResponse(); + public DeleteStoredScriptResponse newResponse() { + return new DeleteStoredScriptResponse(); } @Override - public DeleteIndexedScriptRequestBuilder newRequestBuilder(ElasticsearchClient client) { - return new DeleteIndexedScriptRequestBuilder(client, this); + public DeleteStoredScriptRequestBuilder newRequestBuilder(ElasticsearchClient client) { + return new DeleteStoredScriptRequestBuilder(client, this); } } 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 new file mode 100644 index 00000000000..d01c128cf36 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptRequest.java @@ -0,0 +1,96 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.action.admin.cluster.storedscripts; + +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.action.support.master.AcknowledgedRequest; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; + +import java.io.IOException; + +import static org.elasticsearch.action.ValidateActions.addValidationError; + +public class DeleteStoredScriptRequest extends AcknowledgedRequest { + + private String id; + private String scriptLang; + + DeleteStoredScriptRequest() { + } + + public DeleteStoredScriptRequest(String scriptLang, String id) { + this.scriptLang = scriptLang; + this.id = id; + } + + @Override + public ActionRequestValidationException validate() { + ActionRequestValidationException validationException = null; + if (id == null) { + validationException = addValidationError("id is missing", validationException); + } else if (id.contains("#")) { + validationException = addValidationError("id can't contain: '#'", validationException); + } + if (scriptLang == null) { + validationException = addValidationError("lang is missing", validationException); + } else if (scriptLang.contains("#")) { + validationException = addValidationError("lang can't contain: '#'", validationException); + } + return validationException; + } + + public String scriptLang() { + return scriptLang; + } + + public DeleteStoredScriptRequest scriptLang(String type) { + this.scriptLang = type; + return this; + } + + public String id() { + return id; + } + + public DeleteStoredScriptRequest id(String id) { + this.id = id; + return this; + } + + @Override + public void readFrom(StreamInput in) throws IOException { + super.readFrom(in); + scriptLang = in.readString(); + id = in.readString(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeString(scriptLang); + out.writeString(id); + } + + @Override + public String toString() { + return "delete script {[" + scriptLang + "][" + 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 new file mode 100644 index 00000000000..caf55a03f18 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptRequestBuilder.java @@ -0,0 +1,42 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.action.admin.cluster.storedscripts; + +import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder; +import org.elasticsearch.client.ElasticsearchClient; + +public class DeleteStoredScriptRequestBuilder extends AcknowledgedRequestBuilder { + + public DeleteStoredScriptRequestBuilder(ElasticsearchClient client, DeleteStoredScriptAction action) { + super(client, action, new DeleteStoredScriptRequest()); + } + + public DeleteStoredScriptRequestBuilder setScriptLang(String scriptLang) { + request.scriptLang(scriptLang); + return this; + } + + public DeleteStoredScriptRequestBuilder setId(String id) { + request.id(id); + return this; + } + +} diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptResponse.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptResponse.java new file mode 100644 index 00000000000..4fbb50a34d9 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/DeleteStoredScriptResponse.java @@ -0,0 +1,48 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.action.admin.cluster.storedscripts; + +import org.elasticsearch.action.support.master.AcknowledgedResponse; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; + +import java.io.IOException; + +public class DeleteStoredScriptResponse extends AcknowledgedResponse { + + DeleteStoredScriptResponse() { + } + + public DeleteStoredScriptResponse(boolean acknowledged) { + super(acknowledged); + } + + @Override + public void readFrom(StreamInput in) throws IOException { + super.readFrom(in); + readAcknowledged(in); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + writeAcknowledged(out); + } +} diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/get/GetIndexedScriptAction.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptAction.java similarity index 60% rename from core/src/main/java/org/elasticsearch/action/indexedscripts/get/GetIndexedScriptAction.java rename to core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptAction.java index 898d33691f6..178598fad8b 100644 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/get/GetIndexedScriptAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptAction.java @@ -17,30 +17,31 @@ * under the License. */ -package org.elasticsearch.action.indexedscripts.get; +package org.elasticsearch.action.admin.cluster.storedscripts; import org.elasticsearch.action.Action; import org.elasticsearch.client.ElasticsearchClient; /** */ -public class GetIndexedScriptAction extends Action { +public class GetStoredScriptAction extends Action { - public static final GetIndexedScriptAction INSTANCE = new GetIndexedScriptAction(); - public static final String NAME = "indices:data/read/script/get"; + public static final GetStoredScriptAction INSTANCE = new GetStoredScriptAction(); + public static final String NAME = "cluster:admin/script/get"; - private GetIndexedScriptAction() { + private GetStoredScriptAction() { super(NAME); } @Override - public GetIndexedScriptResponse newResponse() { - return new GetIndexedScriptResponse(); + public GetStoredScriptResponse newResponse() { + return new GetStoredScriptResponse(); } @Override - public GetIndexedScriptRequestBuilder newRequestBuilder(ElasticsearchClient client) { - return new GetIndexedScriptRequestBuilder(client, this); + public GetStoredScriptRequestBuilder newRequestBuilder(ElasticsearchClient client) { + return new GetStoredScriptRequestBuilder(client, this); } } 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 new file mode 100644 index 00000000000..bb7a9effd32 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptRequest.java @@ -0,0 +1,93 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.action.admin.cluster.storedscripts; + +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; + +import java.io.IOException; + +public class GetStoredScriptRequest extends MasterNodeReadRequest { + + protected String id; + protected String lang; + + GetStoredScriptRequest() { + } + + public GetStoredScriptRequest(String lang, String id) { + this.lang = lang; + this.id = id; + } + + @Override + public ActionRequestValidationException validate() { + ActionRequestValidationException validationException = null; + if (lang == null) { + validationException = ValidateActions.addValidationError("lang is missing", validationException); + } + if (id == null) { + validationException = ValidateActions.addValidationError("id is missing", validationException); + } + return validationException; + } + + public GetStoredScriptRequest lang(@Nullable String type) { + this.lang = type; + return this; + } + + public GetStoredScriptRequest id(String id) { + this.id = id; + return this; + } + + + public String lang() { + return lang; + } + + public String id() { + return id; + } + + @Override + public void readFrom(StreamInput in) throws IOException { + super.readFrom(in); + lang = in.readString(); + id = in.readString(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeString(lang); + out.writeString(id); + } + + @Override + public String toString() { + return "get script [" + lang + "][" + 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 new file mode 100644 index 00000000000..c62a0808304 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptRequestBuilder.java @@ -0,0 +1,44 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.action.admin.cluster.storedscripts; + +import org.elasticsearch.action.support.master.MasterNodeReadOperationRequestBuilder; +import org.elasticsearch.client.ElasticsearchClient; +import org.elasticsearch.common.Nullable; + +public class GetStoredScriptRequestBuilder extends MasterNodeReadOperationRequestBuilder { + + + public GetStoredScriptRequestBuilder(ElasticsearchClient client, GetStoredScriptAction action) { + 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/indexedscripts/get/GetIndexedScriptResponse.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptResponse.java similarity index 50% rename from core/src/main/java/org/elasticsearch/action/indexedscripts/get/GetIndexedScriptResponse.java rename to core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptResponse.java index 04470850030..36dd9beb38a 100644 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/get/GetIndexedScriptResponse.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/GetStoredScriptResponse.java @@ -17,90 +17,51 @@ * under the License. */ -package org.elasticsearch.action.indexedscripts.get; +package org.elasticsearch.action.admin.cluster.storedscripts; import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.index.get.GetField; -import org.elasticsearch.script.ScriptService; +import org.elasticsearch.script.Script; import java.io.IOException; -import java.util.Iterator; -/** - * The response of a get script action. - * - * @see GetIndexedScriptRequest - */ -public class GetIndexedScriptResponse extends ActionResponse implements Iterable, ToXContent { +public class GetStoredScriptResponse extends ActionResponse implements ToXContent { - private GetResponse getResponse; + private String storedScript; - GetIndexedScriptResponse() { + GetStoredScriptResponse() { } - GetIndexedScriptResponse(GetResponse getResult) { - this.getResponse = getResult; + GetStoredScriptResponse(String storedScript) { + this.storedScript = storedScript; } /** - * Does the document exists. + * @return if a stored script and if not found null */ - public boolean isExists() { - return getResponse.isExists(); - } - - /** - * The type of the document. - */ - public String getScriptLang() { - return getResponse.getType(); - } - - /** - * The id of the document. - */ - public String getId() { - return getResponse.getId(); - } - - /** - * The version of the doc. - */ - public long getVersion() { - return getResponse.getVersion(); - } - - /** - * The source of the document (as a string). - */ - public String getScript() { - return ScriptService.getScriptFromResponse(getResponse); - } - - @Override - public Iterator iterator() { - return getResponse.iterator(); + public String getStoredScript() { + return storedScript; } @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - return getResponse.toXContent(builder, params); + builder.value(storedScript); + return builder; } @Override public void readFrom(StreamInput in) throws IOException { super.readFrom(in); - getResponse = GetResponse.readGetResponse(in); + storedScript = in.readOptionalString(); } @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); - getResponse.writeTo(out); + out.writeOptionalString(storedScript); } } diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/put/PutIndexedScriptAction.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptAction.java similarity index 60% rename from core/src/main/java/org/elasticsearch/action/indexedscripts/put/PutIndexedScriptAction.java rename to core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptAction.java index e0f364b0ad1..264d37a42e0 100644 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/put/PutIndexedScriptAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptAction.java @@ -17,7 +17,7 @@ * under the License. */ -package org.elasticsearch.action.indexedscripts.put; +package org.elasticsearch.action.admin.cluster.storedscripts; import org.elasticsearch.action.Action; import org.elasticsearch.client.ElasticsearchClient; @@ -25,24 +25,25 @@ import org.elasticsearch.client.ElasticsearchClient; /** */ -public class PutIndexedScriptAction extends Action { +public class PutStoredScriptAction extends Action { - public static final PutIndexedScriptAction INSTANCE = new PutIndexedScriptAction(); - public static final String NAME = "indices:data/write/script/put"; + public static final PutStoredScriptAction INSTANCE = new PutStoredScriptAction(); + public static final String NAME = "cluster:admin/script/put"; - private PutIndexedScriptAction() { + private PutStoredScriptAction() { super(NAME); } @Override - public PutIndexedScriptResponse newResponse() { - return new PutIndexedScriptResponse(); + public PutStoredScriptResponse newResponse() { + return new PutStoredScriptResponse(); } @Override - public PutIndexedScriptRequestBuilder newRequestBuilder(ElasticsearchClient client) { - return new PutIndexedScriptRequestBuilder(client, this); + public PutStoredScriptRequestBuilder newRequestBuilder(ElasticsearchClient client) { + return new PutStoredScriptRequestBuilder(client, 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 new file mode 100644 index 00000000000..cfe153d7d96 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptRequest.java @@ -0,0 +1,126 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.action.admin.cluster.storedscripts; + +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.action.support.master.AcknowledgedRequest; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.xcontent.XContentHelper; + +import java.io.IOException; + +import static org.elasticsearch.action.ValidateActions.addValidationError; + +public class PutStoredScriptRequest extends AcknowledgedRequest { + + private String id; + private String scriptLang; + private BytesReference script; + + public PutStoredScriptRequest() { + super(); + } + + public PutStoredScriptRequest(String scriptLang) { + super(); + this.scriptLang = scriptLang; + } + + public PutStoredScriptRequest(String scriptLang, String id) { + super(); + this.scriptLang = scriptLang; + this.id = id; + } + + @Override + public ActionRequestValidationException validate() { + ActionRequestValidationException validationException = null; + if (id == null) { + validationException = addValidationError("id is missing", validationException); + } else if (id.contains("#")) { + validationException = addValidationError("id can't contain: '#'", validationException); + } + if (scriptLang == null) { + validationException = addValidationError("lang is missing", validationException); + } else if (scriptLang.contains("#")) { + validationException = addValidationError("lang can't contain: '#'", validationException); + } + if (script == null) { + validationException = addValidationError("script is missing", validationException); + } + return validationException; + } + + public String scriptLang() { + return scriptLang; + } + + public PutStoredScriptRequest scriptLang(String scriptLang) { + this.scriptLang = scriptLang; + return this; + } + + public String id() { + return id; + } + + public PutStoredScriptRequest id(String id) { + this.id = id; + return this; + } + + public BytesReference script() { + return script; + } + + public PutStoredScriptRequest script(BytesReference source) { + this.script = source; + return this; + } + + @Override + public void readFrom(StreamInput in) throws IOException { + super.readFrom(in); + scriptLang = in.readString(); + id = in.readOptionalString(); + script = in.readBytesReference(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeString(scriptLang); + out.writeOptionalString(id); + out.writeBytesReference(script); + } + + @Override + public String toString() { + String sSource = "_na_"; + try { + sSource = XContentHelper.convertToJson(script, false); + } catch (Exception e) { + // ignore + } + return "put script {[" + id + "][" + scriptLang + "], script[" + sSource + "]}"; + } +} 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 new file mode 100644 index 00000000000..15c51c2ccd7 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptRequestBuilder.java @@ -0,0 +1,48 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.action.admin.cluster.storedscripts; + +import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder; +import org.elasticsearch.client.ElasticsearchClient; +import org.elasticsearch.common.bytes.BytesReference; + +public class PutStoredScriptRequestBuilder extends AcknowledgedRequestBuilder { + + public PutStoredScriptRequestBuilder(ElasticsearchClient client, PutStoredScriptAction action) { + super(client, action, new PutStoredScriptRequest()); + } + + public PutStoredScriptRequestBuilder setScriptLang(String scriptLang) { + request.scriptLang(scriptLang); + return this; + } + + public PutStoredScriptRequestBuilder setId(String id) { + request.id(id); + return this; + } + + public PutStoredScriptRequestBuilder setSource(BytesReference source) { + request.script(source); + return this; + } + +} diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/package-info.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptResponse.java similarity index 50% rename from core/src/main/java/org/elasticsearch/action/indexedscripts/delete/package-info.java rename to core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptResponse.java index 485733853c5..44250f3809d 100644 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/package-info.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/PutStoredScriptResponse.java @@ -17,7 +17,33 @@ * under the License. */ -/** - * Delete action. - */ -package org.elasticsearch.action.indexedscripts.delete; \ No newline at end of file +package org.elasticsearch.action.admin.cluster.storedscripts; + +import org.elasticsearch.action.support.master.AcknowledgedResponse; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; + +import java.io.IOException; + +public class PutStoredScriptResponse extends AcknowledgedResponse { + + PutStoredScriptResponse() { + } + + public PutStoredScriptResponse(boolean acknowledged) { + super(acknowledged); + } + + @Override + public void readFrom(StreamInput in) throws IOException { + super.readFrom(in); + readAcknowledged(in); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + writeAcknowledged(out); + } + +} diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportDeleteStoredScriptAction.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportDeleteStoredScriptAction.java new file mode 100644 index 00000000000..b7ae06dbdbb --- /dev/null +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportDeleteStoredScriptAction.java @@ -0,0 +1,71 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.action.admin.cluster.storedscripts; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.action.support.master.TransportMasterNodeAction; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.block.ClusterBlockException; +import org.elasticsearch.cluster.block.ClusterBlockLevel; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.script.ScriptService; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.transport.TransportService; + +public class TransportDeleteStoredScriptAction extends TransportMasterNodeAction { + + private final ScriptService scriptService; + + @Inject + public TransportDeleteStoredScriptAction(Settings settings, TransportService transportService, ClusterService clusterService, + ThreadPool threadPool, ActionFilters actionFilters, + IndexNameExpressionResolver indexNameExpressionResolver, ScriptService scriptService) { + super(settings, DeleteStoredScriptAction.NAME, transportService, clusterService, threadPool, actionFilters, + indexNameExpressionResolver, DeleteStoredScriptRequest::new); + this.scriptService = scriptService; + } + + @Override + protected String executor() { + return ThreadPool.Names.SAME; + } + + @Override + protected DeleteStoredScriptResponse newResponse() { + return new DeleteStoredScriptResponse(); + } + + @Override + protected void masterOperation(DeleteStoredScriptRequest request, ClusterState state, + ActionListener listener) throws Exception { + scriptService.deleteStoredScript(clusterService, request, listener); + } + + @Override + protected ClusterBlockException checkBlock(DeleteStoredScriptRequest request, ClusterState state) { + return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE); + } + +} diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportGetStoredScriptAction.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportGetStoredScriptAction.java new file mode 100644 index 00000000000..ab5a3d9953a --- /dev/null +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportGetStoredScriptAction.java @@ -0,0 +1,71 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.action.admin.cluster.storedscripts; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.action.support.master.TransportMasterNodeReadAction; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.block.ClusterBlockException; +import org.elasticsearch.cluster.block.ClusterBlockLevel; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.script.ScriptService; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.transport.TransportService; + +public class TransportGetStoredScriptAction extends TransportMasterNodeReadAction { + + private final ScriptService scriptService; + + @Inject + public TransportGetStoredScriptAction(Settings settings, TransportService transportService, ClusterService clusterService, + ThreadPool threadPool, ActionFilters actionFilters, + IndexNameExpressionResolver indexNameExpressionResolver, ScriptService scriptService) { + super(settings, GetStoredScriptAction.NAME, transportService, clusterService, threadPool, actionFilters, + indexNameExpressionResolver, GetStoredScriptRequest::new); + this.scriptService = scriptService; + } + + @Override + protected String executor() { + return ThreadPool.Names.SAME; + } + + @Override + protected GetStoredScriptResponse newResponse() { + return new GetStoredScriptResponse(); + } + + @Override + protected void masterOperation(GetStoredScriptRequest request, ClusterState state, + ActionListener listener) throws Exception { + listener.onResponse(new GetStoredScriptResponse(scriptService.getStoredScript(state, request))); + } + + @Override + protected ClusterBlockException checkBlock(GetStoredScriptRequest request, ClusterState state) { + return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ); + } + +} diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportPutStoredScriptAction.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportPutStoredScriptAction.java new file mode 100644 index 00000000000..a91dec8d9b3 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/storedscripts/TransportPutStoredScriptAction.java @@ -0,0 +1,70 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.action.admin.cluster.storedscripts; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.action.support.master.TransportMasterNodeAction; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.block.ClusterBlockException; +import org.elasticsearch.cluster.block.ClusterBlockLevel; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.script.ScriptService; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.transport.TransportService; + +public class TransportPutStoredScriptAction extends TransportMasterNodeAction { + + private final ScriptService scriptService; + + @Inject + public TransportPutStoredScriptAction(Settings settings, TransportService transportService, ClusterService clusterService, + ThreadPool threadPool, ActionFilters actionFilters, + IndexNameExpressionResolver indexNameExpressionResolver, ScriptService scriptService) { + super(settings, PutStoredScriptAction.NAME, transportService, clusterService, threadPool, actionFilters, + indexNameExpressionResolver, PutStoredScriptRequest::new); + this.scriptService = scriptService; + } + + @Override + protected String executor() { + return ThreadPool.Names.SAME; + } + + @Override + protected PutStoredScriptResponse newResponse() { + return new PutStoredScriptResponse(); + } + + @Override + protected void masterOperation(PutStoredScriptRequest request, ClusterState state, + ActionListener listener) throws Exception { + scriptService.storeScript(clusterService, request, listener); + } + + @Override + protected ClusterBlockException checkBlock(PutStoredScriptRequest request, ClusterState state) { + return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE); + } + +} diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/validate/template/TransportRenderSearchTemplateAction.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/validate/template/TransportRenderSearchTemplateAction.java index 0b4250ef74d..ad573c4a074 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/validate/template/TransportRenderSearchTemplateAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/validate/template/TransportRenderSearchTemplateAction.java @@ -22,7 +22,9 @@ package org.elasticsearch.action.admin.cluster.validate.template; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.HandledTransportAction; +import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; @@ -38,12 +40,15 @@ import java.util.Collections; public class TransportRenderSearchTemplateAction extends HandledTransportAction { private final ScriptService scriptService; + private final ClusterService clusterService; @Inject public TransportRenderSearchTemplateAction(ScriptService scriptService, Settings settings, ThreadPool threadPool, - TransportService transportService, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) { + TransportService transportService, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver, + ClusterService clusterService) { super(settings, RenderSearchTemplateAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver, RenderSearchTemplateRequest::new); this.scriptService = scriptService; + this.clusterService = clusterService; } @Override @@ -57,7 +62,8 @@ public class TransportRenderSearchTemplateAction extends HandledTransportAction< @Override protected void doRun() throws Exception { - ExecutableScript executable = scriptService.executable(request.template(), ScriptContext.Standard.SEARCH, Collections.emptyMap()); + ExecutableScript executable = scriptService.executable(request.template(), ScriptContext.Standard.SEARCH, + Collections.emptyMap(), clusterService.state()); BytesReference processedTemplate = (BytesReference) executable.run(); RenderSearchTemplateResponse response = new RenderSearchTemplateResponse(); response.source(processedTemplate); diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/DeleteIndexedScriptRequest.java b/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/DeleteIndexedScriptRequest.java deleted file mode 100644 index 4e8019a3ae5..00000000000 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/DeleteIndexedScriptRequest.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.indexedscripts.delete; - -import org.elasticsearch.action.ActionRequest; -import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.action.IndicesRequest; -import org.elasticsearch.action.support.IndicesOptions; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.lucene.uid.Versions; -import org.elasticsearch.index.VersionType; -import org.elasticsearch.script.ScriptService; - -import java.io.IOException; - -import static org.elasticsearch.action.ValidateActions.addValidationError; - -/** - * A request to delete a script from the script index based on its scriptLang and id. Best created using - *

- * The operation requires the , {@link #scriptLang(String)} and {@link #id(String)} to - * be set. - * - * @see DeleteIndexedScriptResponse - * @see org.elasticsearch.client.Client#deleteIndexedScript(DeleteIndexedScriptRequest) - */ -public class DeleteIndexedScriptRequest extends ActionRequest implements IndicesRequest { - - private String scriptLang; - private String id; - private long version = Versions.MATCH_ANY; - private VersionType versionType = VersionType.INTERNAL; - - - public DeleteIndexedScriptRequest() { - } - - /** - * Constructs a new delete request against the specified index with the scriptLang and id. - * - * @param scriptLang The scriptLang of the document - * @param id The id of the document - */ - public DeleteIndexedScriptRequest(String scriptLang, String id) { - this.scriptLang = scriptLang; - this.id = id; - } - - @Override - public ActionRequestValidationException validate() { - ActionRequestValidationException validationException = null; - if (scriptLang == null) { - validationException = addValidationError("scriptLang is missing", validationException); - } - if (id == null) { - validationException = addValidationError("id is missing", validationException); - } - if (!versionType.validateVersionForWrites(version)) { - validationException = addValidationError("illegal version value [" + version + "] for version scriptLang [" + versionType.name() + "]", validationException); - } - return validationException; - } - - @Override - public String[] indices() { - return new String[]{ScriptService.SCRIPT_INDEX}; - } - - @Override - public IndicesOptions indicesOptions() { - return IndicesOptions.strictSingleIndexNoExpandForbidClosed(); - } - - /** - * The scriptLang of the document to delete. - */ - public String scriptLang() { - return scriptLang; - } - - /** - * Sets the scriptLang of the document to delete. - */ - public DeleteIndexedScriptRequest scriptLang(String type) { - this.scriptLang = type; - return this; - } - - /** - * The id of the document to delete. - */ - public String id() { - return id; - } - - /** - * Sets the id of the document to delete. - */ - public DeleteIndexedScriptRequest id(String id) { - this.id = id; - return this; - } - - /** - * Sets the version, which will cause the delete operation to only be performed if a matching - * version exists and no changes happened on the doc since then. - */ - public DeleteIndexedScriptRequest version(long version) { - this.version = version; - return this; - } - - public long version() { - return this.version; - } - - public DeleteIndexedScriptRequest versionType(VersionType versionType) { - this.versionType = versionType; - return this; - } - - public VersionType versionType() { - return this.versionType; - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - scriptLang = in.readString(); - id = in.readString(); - version = in.readLong(); - versionType = VersionType.fromValue(in.readByte()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(scriptLang); - out.writeString(id); - out.writeLong(version); - out.writeByte(versionType.getValue()); - } - - @Override - public String toString() { - return "delete {[" + ScriptService.SCRIPT_INDEX + "][" + scriptLang + "][" + id + "]}"; - } -} diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/DeleteIndexedScriptRequestBuilder.java b/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/DeleteIndexedScriptRequestBuilder.java deleted file mode 100644 index 37604500a3e..00000000000 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/DeleteIndexedScriptRequestBuilder.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.indexedscripts.delete; - -import org.elasticsearch.action.ActionRequestBuilder; -import org.elasticsearch.client.ElasticsearchClient; -import org.elasticsearch.index.VersionType; - -/** - * A delete document action request builder. - */ -public class DeleteIndexedScriptRequestBuilder extends ActionRequestBuilder { - - public DeleteIndexedScriptRequestBuilder(ElasticsearchClient client, DeleteIndexedScriptAction action) { - super(client, action, new DeleteIndexedScriptRequest()); - } - - /** - * Sets the language of the script to delete. - */ - public DeleteIndexedScriptRequestBuilder setScriptLang(String scriptLang) { - request.scriptLang(scriptLang); - return this; - } - - /** - * Sets the id of the document to delete. - */ - public DeleteIndexedScriptRequestBuilder setId(String id) { - request.id(id); - return this; - } - - /** - * Sets the type of versioning to use. Defaults to {@link org.elasticsearch.index.VersionType#INTERNAL}. - */ - public DeleteIndexedScriptRequestBuilder setVersionType(VersionType versionType) { - request.versionType(versionType); - return this; - } -} diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/DeleteIndexedScriptResponse.java b/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/DeleteIndexedScriptResponse.java deleted file mode 100644 index 2658ee014c8..00000000000 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/DeleteIndexedScriptResponse.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.indexedscripts.delete; - -import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; - -/** - * The response of the delete indexed script action. - * - * @see DeleteIndexedScriptRequest - * @see org.elasticsearch.client.Client#deleteIndexedScript(DeleteIndexedScriptRequest) - */ -public class DeleteIndexedScriptResponse extends ActionResponse { - - private String index; - private String id; - private String type; - private long version; - private boolean found; - - public DeleteIndexedScriptResponse() { - - } - - public DeleteIndexedScriptResponse(String index, String type, String id, long version, boolean found) { - this.index = index; - this.id = id; - this.type = type; - this.version = version; - this.found = found; - } - - /** - * The index the document was deleted from. - */ - public String getIndex() { - return this.index; - } - - /** - * The type of the document deleted. - */ - public String getType() { - return this.type; - } - - /** - * The id of the document deleted. - */ - public String getId() { - return this.id; - } - - /** - * The version of the delete operation. - */ - public long getVersion() { - return this.version; - } - - /** - * Returns true if a doc was found to delete. - */ - public boolean isFound() { - return found; - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - index = in.readString(); - type = in.readString(); - id = in.readString(); - version = in.readLong(); - found = in.readBoolean(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(index); - out.writeString(type); - out.writeString(id); - out.writeLong(version); - out.writeBoolean(found); - } -} diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/TransportDeleteIndexedScriptAction.java b/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/TransportDeleteIndexedScriptAction.java deleted file mode 100644 index dcd6c443504..00000000000 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/delete/TransportDeleteIndexedScriptAction.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.indexedscripts.delete; - -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.delete.DeleteResponse; -import org.elasticsearch.action.support.ActionFilters; -import org.elasticsearch.action.support.DelegatingActionListener; -import org.elasticsearch.action.support.HandledTransportAction; -import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.script.ScriptService; -import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.transport.TransportService; - -/** - * Performs the delete operation. - */ -public class TransportDeleteIndexedScriptAction extends HandledTransportAction { - - private final ScriptService scriptService; - - @Inject - public TransportDeleteIndexedScriptAction(Settings settings, ThreadPool threadPool, ScriptService scriptService, - TransportService transportService, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) { - super(settings, DeleteIndexedScriptAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver, DeleteIndexedScriptRequest::new); - this.scriptService = scriptService; - } - - @Override - protected void doExecute(final DeleteIndexedScriptRequest request, final ActionListener listener) { - scriptService.deleteScriptFromIndex(request, new DelegatingActionListener(listener) { - @Override - public DeleteIndexedScriptResponse getDelegatedFromInstigator(DeleteResponse deleteResponse){ - return new DeleteIndexedScriptResponse(deleteResponse.getIndex(), deleteResponse.getType(), deleteResponse.getId(), deleteResponse.getVersion(), deleteResponse.isFound()); - } - }); - } -} diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/get/GetIndexedScriptRequest.java b/core/src/main/java/org/elasticsearch/action/indexedscripts/get/GetIndexedScriptRequest.java deleted file mode 100644 index df7a8f95b84..00000000000 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/get/GetIndexedScriptRequest.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.indexedscripts.get; - -import org.elasticsearch.action.ActionRequest; -import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.action.IndicesRequest; -import org.elasticsearch.action.ValidateActions; -import org.elasticsearch.action.support.IndicesOptions; -import org.elasticsearch.common.Nullable; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.lucene.uid.Versions; -import org.elasticsearch.index.VersionType; -import org.elasticsearch.script.ScriptService; - -import java.io.IOException; - -/** - * A request to get an indexed script (its source) based on its language (optional) and id. - * The operation requires the {@link #scriptLang(String)} and {@link #id(String)} to be set. - * - * @see GetIndexedScriptResponse - */ -public class GetIndexedScriptRequest extends ActionRequest implements IndicesRequest { - - protected String scriptLang; - protected String id; - - private VersionType versionType = VersionType.INTERNAL; - private long version = Versions.MATCH_ANY; - - /** - * Constructs a new get request against the script index. The {@link #scriptLang(String)} and {@link #id(String)} - * must be set. - */ - public GetIndexedScriptRequest() { - - } - - /** - * Constructs a new get request against the script index with the type and id. - * - * @param scriptLang The language of the script - * @param id The id of the script - */ - public GetIndexedScriptRequest(String scriptLang, String id) { - this.scriptLang = scriptLang; - this.id = id; - } - - @Override - public ActionRequestValidationException validate() { - ActionRequestValidationException validationException = null; - if (scriptLang == null) { - validationException = ValidateActions.addValidationError("type is missing", validationException); - } - if (id == null) { - validationException = ValidateActions.addValidationError("id is missing", validationException); - } - if (!versionType.validateVersionForReads(version)) { - validationException = ValidateActions.addValidationError("illegal version value [" + version + "] for version type [" + versionType.name() + "]", - validationException); - } - return validationException; - } - - @Override - public String[] indices() { - return new String[]{ScriptService.SCRIPT_INDEX}; - } - - @Override - public IndicesOptions indicesOptions() { - return IndicesOptions.strictSingleIndexNoExpandForbidClosed(); - } - - /** - * Sets the language of the script to fetch. - */ - public GetIndexedScriptRequest scriptLang(@Nullable String type) { - this.scriptLang = type; - return this; - } - - /** - * Sets the id of the script to fetch. - */ - public GetIndexedScriptRequest id(String id) { - this.id = id; - return this; - } - - - public String scriptLang() { - return scriptLang; - } - - public String id() { - return id; - } - - /** - * Sets the version, which will cause the get operation to only be performed if a matching - * version exists and no changes happened on the doc since then. - */ - public long version() { - return version; - } - - public GetIndexedScriptRequest version(long version) { - this.version = version; - return this; - } - - /** - * Sets the versioning type. Defaults to {@link org.elasticsearch.index.VersionType#INTERNAL}. - */ - public GetIndexedScriptRequest versionType(VersionType versionType) { - this.versionType = versionType; - return this; - } - - public VersionType versionType() { - return this.versionType; - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - scriptLang = in.readString(); - id = in.readString(); - this.versionType = VersionType.fromValue(in.readByte()); - this.version = in.readLong(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(scriptLang); - out.writeString(id); - out.writeByte(versionType.getValue()); - out.writeLong(version); - } - - @Override - public String toString() { - return "[" + ScriptService.SCRIPT_INDEX + "][" + scriptLang + "][" + id + "]"; - } -} diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/get/GetIndexedScriptRequestBuilder.java b/core/src/main/java/org/elasticsearch/action/indexedscripts/get/GetIndexedScriptRequestBuilder.java deleted file mode 100644 index f01cd092cc1..00000000000 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/get/GetIndexedScriptRequestBuilder.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.indexedscripts.get; - -import org.elasticsearch.action.ActionRequestBuilder; -import org.elasticsearch.client.ElasticsearchClient; -import org.elasticsearch.common.Nullable; -import org.elasticsearch.index.VersionType; - -/** - * A get document action request builder. - */ -public class GetIndexedScriptRequestBuilder extends ActionRequestBuilder { - - - public GetIndexedScriptRequestBuilder(ElasticsearchClient client, GetIndexedScriptAction action) { - super(client, action, new GetIndexedScriptRequest()); - } - - /** - * Sets the type of the document to fetch. If set to null, will use just the id to fetch the - * first document matching it. - */ - public GetIndexedScriptRequestBuilder setScriptLang(@Nullable String type) { - request.scriptLang(type); - return this; - } - - /** - * Sets the id of the document to fetch. - */ - public GetIndexedScriptRequestBuilder setId(String id) { - request.id(id); - return this; - } - - /** - * Sets the version, which will cause the get operation to only be performed if a matching - * version exists and no changes happened on the doc since then. - */ - public GetIndexedScriptRequestBuilder setVersion(long version) { - request.version(version); - return this; - } - - /** - * Sets the versioning type. Defaults to {@link org.elasticsearch.index.VersionType#INTERNAL}. - */ - public GetIndexedScriptRequestBuilder setVersionType(VersionType versionType) { - request.versionType(versionType); - return this; - } -} diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/get/TransportGetIndexedScriptAction.java b/core/src/main/java/org/elasticsearch/action/indexedscripts/get/TransportGetIndexedScriptAction.java deleted file mode 100644 index 392d198b563..00000000000 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/get/TransportGetIndexedScriptAction.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.indexedscripts.get; - -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.get.GetResponse; -import org.elasticsearch.action.support.ActionFilters; -import org.elasticsearch.action.support.HandledTransportAction; -import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.script.ScriptService; -import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.transport.TransportService; - -/** - * Performs the get operation. - */ -public class TransportGetIndexedScriptAction extends HandledTransportAction { - - private final ScriptService scriptService; - - @Inject - public TransportGetIndexedScriptAction(Settings settings, ThreadPool threadPool, ScriptService scriptService, - TransportService transportService, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) { - super(settings, GetIndexedScriptAction.NAME, threadPool,transportService, actionFilters, indexNameExpressionResolver, GetIndexedScriptRequest::new); - this.scriptService = scriptService; - } - - @Override - public void doExecute(GetIndexedScriptRequest request, final ActionListener listener){ - // forward the handling to the script service we are running on a network thread here... - scriptService.queryScriptIndex(request, new ActionListener() { - @Override - public void onResponse(GetResponse getFields) { - listener.onResponse(new GetIndexedScriptResponse(getFields)); - } - - @Override - public void onFailure(Throwable e) { - listener.onFailure(e); - } - }); - } -} diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/get/package-info.java b/core/src/main/java/org/elasticsearch/action/indexedscripts/get/package-info.java deleted file mode 100644 index 65cb92f23b0..00000000000 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/get/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.elasticsearch.action.indexedscripts.get; \ No newline at end of file diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/put/PutIndexedScriptRequest.java b/core/src/main/java/org/elasticsearch/action/indexedscripts/put/PutIndexedScriptRequest.java deleted file mode 100644 index 765331fd1eb..00000000000 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/put/PutIndexedScriptRequest.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.indexedscripts.put; - -import org.elasticsearch.ElasticsearchGenerationException; -import org.elasticsearch.action.ActionRequest; -import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.action.IndicesRequest; -import org.elasticsearch.action.index.IndexRequest; -import org.elasticsearch.action.support.IndicesOptions; -import org.elasticsearch.client.Requests; -import org.elasticsearch.common.bytes.BytesArray; -import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.lucene.uid.Versions; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentFactory; -import org.elasticsearch.common.xcontent.XContentHelper; -import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.index.VersionType; -import org.elasticsearch.script.ScriptService; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Map; - -import static org.elasticsearch.action.ValidateActions.addValidationError; - -/** - * Index request to index a script to the script index and make it available at search time. - *

- * The request requires the {@link #scriptLang(String)}, {@link #id(String)} and - * {@link #source(byte[])} to be set. - *

- * The source (content to index) can be set in its bytes form using ({@link #source()} (byte[])}), - * its string form ({@link #source(String)}) or using a {@link org.elasticsearch.common.xcontent.XContentBuilder} - * ({@link #source(org.elasticsearch.common.xcontent.XContentBuilder)}). - *

- * If the {@link #id(String)} is not set, it will be automatically generated. - * - * @see PutIndexedScriptResponse - */ -public class PutIndexedScriptRequest extends ActionRequest implements IndicesRequest { - - private String scriptLang; - private String id; - - private BytesReference source; - - private IndexRequest.OpType opType = IndexRequest.OpType.INDEX; - - private long version = Versions.MATCH_ANY; - private VersionType versionType = VersionType.INTERNAL; - - private XContentType contentType = Requests.INDEX_CONTENT_TYPE; - - public PutIndexedScriptRequest() { - super(); - } - - /** - * Constructs a new index request against the specific index and type. The - * {@link #source(byte[])} must be set. - */ - public PutIndexedScriptRequest(String scriptLang) { - super(); - this.scriptLang = scriptLang; - } - - /** - * Constructs a new index request against the index, type, id and using the source. - * - * @param scriptLang The scriptLang to index into - * @param id The id of document - */ - public PutIndexedScriptRequest(String scriptLang, String id) { - super(); - this.scriptLang = scriptLang; - this.id = id; - } - - @Override - public ActionRequestValidationException validate() { - ActionRequestValidationException validationException = null; - if (scriptLang == null) { - validationException = addValidationError("scriptType is missing", validationException); - } - if (source == null) { - validationException = addValidationError("source is missing", validationException); - } - if (id == null) { - validationException = addValidationError("id is missing", validationException); - } - if (!versionType.validateVersionForWrites(version)) { - validationException = addValidationError("illegal version value [" + version + "] for version type [" + versionType.name() + "]", validationException); - } - return validationException; - } - - @Override - public String[] indices() { - return new String[]{ScriptService.SCRIPT_INDEX}; - } - - @Override - public IndicesOptions indicesOptions() { - return IndicesOptions.strictSingleIndexNoExpandForbidClosed(); - } - - /** - * Sets the content type that will be used when generating a document from user provided objects (like Map). - */ - public PutIndexedScriptRequest contentType(XContentType contentType) { - this.contentType = contentType; - return this; - } - - /** - * The type of the indexed document. - */ - public String scriptLang() { - return scriptLang; - } - - /** - * Sets the type of the indexed document. - */ - public PutIndexedScriptRequest scriptLang(String scriptLang) { - this.scriptLang = scriptLang; - return this; - } - - /** - * The id of the indexed document. If not set, will be automatically generated. - */ - public String id() { - return id; - } - - /** - * Sets the id of the indexed document. If not set, will be automatically generated. - */ - public PutIndexedScriptRequest id(String id) { - this.id = id; - return this; - } - - /** - * The source of the document to index, recopied to a new array if it is unsafe. - */ - public BytesReference source() { - return source; - } - - public Map sourceAsMap() { - return XContentHelper.convertToMap(source, false).v2(); - } - - /** - * Index the Map as a {@link org.elasticsearch.client.Requests#INDEX_CONTENT_TYPE}. - * - * @param source The map to index - */ - public PutIndexedScriptRequest source(Map source) throws ElasticsearchGenerationException { - return source(source, contentType); - } - - /** - * Index the Map as the provided content type. - * - * @param source The map to index - */ - public PutIndexedScriptRequest source(Map source, XContentType contentType) throws ElasticsearchGenerationException { - try { - XContentBuilder builder = XContentFactory.contentBuilder(contentType); - builder.map(source); - return source(builder); - } catch (IOException e) { - throw new ElasticsearchGenerationException("Failed to generate [" + source + "]", e); - } - } - - /** - * Sets the document source to index. - *

- * Note, its preferable to either set it using {@link #source(org.elasticsearch.common.xcontent.XContentBuilder)} - * or using the {@link #source(byte[])}. - */ - public PutIndexedScriptRequest source(String source) { - this.source = new BytesArray(source.getBytes(StandardCharsets.UTF_8)); - return this; - } - - /** - * Sets the content source to index. - */ - public PutIndexedScriptRequest source(XContentBuilder sourceBuilder) { - source = sourceBuilder.bytes(); - return this; - } - - public PutIndexedScriptRequest source(Object... source) { - if (source.length % 2 != 0) { - throw new IllegalArgumentException("The number of object passed must be even but was [" + source.length + "]"); - } - try { - XContentBuilder builder = XContentFactory.contentBuilder(contentType); - builder.startObject(); - for (int i = 0; i < source.length; i++) { - builder.field(source[i++].toString(), source[i]); - } - builder.endObject(); - return source(builder); - } catch (IOException e) { - throw new ElasticsearchGenerationException("Failed to generate", e); - } - } - - /** - * Sets the document to index in bytes form. - */ - public PutIndexedScriptRequest source(BytesReference source) { - this.source = source; - return this; - } - - /** - * Sets the document to index in bytes form. - */ - public PutIndexedScriptRequest source(byte[] source) { - return source(source, 0, source.length); - } - - /** - * Sets the document to index in bytes form (assumed to be safe to be used from different - * threads). - * - * @param source The source to index - * @param offset The offset in the byte array - * @param length The length of the data - */ - public PutIndexedScriptRequest source(byte[] source, int offset, int length) { - return source(new BytesArray(source, offset, length)); - } - - /** - * Sets the type of operation to perform. - */ - public PutIndexedScriptRequest opType(IndexRequest.OpType opType) { - this.opType = opType; - return this; - } - - /** - * Set to true to force this index to use {@link org.elasticsearch.action.index.IndexRequest.OpType#CREATE}. - */ - public PutIndexedScriptRequest create(boolean create) { - if (create) { - return opType(IndexRequest.OpType.CREATE); - } else { - return opType(IndexRequest.OpType.INDEX); - } - } - - /** - * The type of operation to perform. - */ - public IndexRequest.OpType opType() { - return this.opType; - } - - /** - * Sets the version, which will cause the index operation to only be performed if a matching - * version exists and no changes happened on the doc since then. - */ - public PutIndexedScriptRequest version(long version) { - this.version = version; - return this; - } - - public long version() { - return this.version; - } - - /** - * Sets the versioning type. Defaults to {@link org.elasticsearch.index.VersionType#INTERNAL}. - */ - public PutIndexedScriptRequest versionType(VersionType versionType) { - this.versionType = versionType; - return this; - } - - public VersionType versionType() { - return this.versionType; - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - scriptLang = in.readString(); - id = in.readOptionalString(); - source = in.readBytesReference(); - - opType = IndexRequest.OpType.fromId(in.readByte()); - version = in.readLong(); - versionType = VersionType.fromValue(in.readByte()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(scriptLang); - out.writeOptionalString(id); - out.writeBytesReference(source); - out.writeByte(opType.id()); - out.writeLong(version); - out.writeByte(versionType.getValue()); - } - - @Override - public String toString() { - String sSource = "_na_"; - try { - sSource = XContentHelper.convertToJson(source, false); - } catch (Exception e) { - // ignore - } - return "index {[" + ScriptService.SCRIPT_INDEX + "][" + scriptLang + "][" + id + "], source[" + sSource + "]}"; - } -} diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/put/PutIndexedScriptRequestBuilder.java b/core/src/main/java/org/elasticsearch/action/indexedscripts/put/PutIndexedScriptRequestBuilder.java deleted file mode 100644 index eb07941fc12..00000000000 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/put/PutIndexedScriptRequestBuilder.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.indexedscripts.put; - -import org.elasticsearch.action.ActionRequestBuilder; -import org.elasticsearch.action.index.IndexRequest; -import org.elasticsearch.client.ElasticsearchClient; -import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.index.VersionType; - -import java.util.Map; - -/** - * An index document action request builder. - */ -public class PutIndexedScriptRequestBuilder extends ActionRequestBuilder { - - public PutIndexedScriptRequestBuilder(ElasticsearchClient client, PutIndexedScriptAction action) { - super(client, action, new PutIndexedScriptRequest()); - } - - /** - * Sets the type to index the document to. - */ - public PutIndexedScriptRequestBuilder setScriptLang(String scriptLang) { - request.scriptLang(scriptLang); - return this; - } - - /** - * Sets the id to index the document under. Optional, and if not set, one will be automatically - * generated. - */ - public PutIndexedScriptRequestBuilder setId(String id) { - request.id(id); - return this; - } - - /** - * Sets the source. - */ - public PutIndexedScriptRequestBuilder setSource(BytesReference source) { - request.source(source); - return this; - } - - /** - * Index the Map as a JSON. - * - * @param source The map to index - */ - public PutIndexedScriptRequestBuilder setSource(Map source) { - request.source(source); - return this; - } - - /** - * Index the Map as the provided content type. - * - * @param source The map to index - */ - public PutIndexedScriptRequestBuilder setSource(Map source, XContentType contentType) { - request.source(source, contentType); - return this; - } - - /** - * Sets the document source to index. - *

- * Note, its preferable to either set it using {@link #setSource(org.elasticsearch.common.xcontent.XContentBuilder)} - * or using the {@link #setSource(byte[])}. - */ - public PutIndexedScriptRequestBuilder setSource(String source) { - request.source(source); - return this; - } - - /** - * Sets the content source to index. - */ - public PutIndexedScriptRequestBuilder setSource(XContentBuilder sourceBuilder) { - request.source(sourceBuilder); - return this; - } - - /** - * Sets the document to index in bytes form. - */ - public PutIndexedScriptRequestBuilder setSource(byte[] source) { - request.source(source); - return this; - } - - /** - * Sets the document to index in bytes form (assumed to be safe to be used from different - * threads). - * - * @param source The source to index - * @param offset The offset in the byte array - * @param length The length of the data - */ - public PutIndexedScriptRequestBuilder setSource(byte[] source, int offset, int length) { - request.source(source, offset, length); - return this; - } - - /** - * Constructs a simple document with a field name and value pairs. - * Note: the number of objects passed to this method must be an even number. - */ - public PutIndexedScriptRequestBuilder setSource(Object... source) { - request.source(source); - return this; - } - - /** - * The content type that will be used to generate a document from user provided objects (like Map). - */ - public PutIndexedScriptRequestBuilder setContentType(XContentType contentType) { - request.contentType(contentType); - return this; - } - - /** - * Sets the type of operation to perform. - */ - public PutIndexedScriptRequestBuilder setOpType(IndexRequest.OpType opType) { - request.opType(opType); - return this; - } - - /** - * Sets a string representation of the {@link #setOpType(org.elasticsearch.action.index.IndexRequest.OpType)}. Can - * be either "index" or "create". - */ - public PutIndexedScriptRequestBuilder setOpType(String opType) { - request.opType(IndexRequest.OpType.fromString(opType)); - return this; - } - - /** - * Set to true to force this index to use {@link org.elasticsearch.action.index.IndexRequest.OpType#CREATE}. - */ - public PutIndexedScriptRequestBuilder setCreate(boolean create) { - request.create(create); - return this; - } - - /** - * Sets the version, which will cause the index operation to only be performed if a matching - * version exists and no changes happened on the doc since then. - */ - public PutIndexedScriptRequestBuilder setVersion(long version) { - request.version(version); - return this; - } - - /** - * Sets the versioning type. Defaults to {@link org.elasticsearch.index.VersionType#INTERNAL}. - */ - public PutIndexedScriptRequestBuilder setVersionType(VersionType versionType) { - request.versionType(versionType); - return this; - } -} diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/put/PutIndexedScriptResponse.java b/core/src/main/java/org/elasticsearch/action/indexedscripts/put/PutIndexedScriptResponse.java deleted file mode 100644 index e42818f4393..00000000000 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/put/PutIndexedScriptResponse.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.indexedscripts.put; - -import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.script.ScriptService; - -import java.io.IOException; - -/** - * A response of an index operation, - * - * @see PutIndexedScriptRequest - * @see org.elasticsearch.client.Client#putIndexedScript(PutIndexedScriptRequest) - */ -public class PutIndexedScriptResponse extends ActionResponse { - - private String index; - private String id; - private String scriptLang; - private long version; - private boolean created; - - public PutIndexedScriptResponse() { - } - - public PutIndexedScriptResponse(String type, String id, long version, boolean created) { - this.index = ScriptService.SCRIPT_INDEX; - this.id = id; - this.scriptLang = type; - this.version = version; - this.created = created; - } - - /** - * The index the document was indexed into. - */ - public String getIndex() { - return this.index; - } - - /** - * The type of the document indexed. - */ - public String getScriptLang() { - return this.scriptLang; - } - - /** - * The id of the document indexed. - */ - public String getId() { - return this.id; - } - - /** - * Returns the current version of the doc indexed. - */ - public long getVersion() { - return this.version; - } - - /** - * Returns true if the document was created, false if updated. - */ - public boolean isCreated() { - return this.created; - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - index = ScriptService.SCRIPT_INDEX; - scriptLang = in.readString(); - id = in.readString(); - version = in.readLong(); - created = in.readBoolean(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(scriptLang); - out.writeString(id); - out.writeLong(version); - out.writeBoolean(created); - } -} diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/put/TransportPutIndexedScriptAction.java b/core/src/main/java/org/elasticsearch/action/indexedscripts/put/TransportPutIndexedScriptAction.java deleted file mode 100644 index ef1ee5367e0..00000000000 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/put/TransportPutIndexedScriptAction.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.action.indexedscripts.put; - -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.index.IndexResponse; -import org.elasticsearch.action.support.ActionFilters; -import org.elasticsearch.action.support.DelegatingActionListener; -import org.elasticsearch.action.support.HandledTransportAction; -import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.script.ScriptService; -import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.transport.TransportService; - -/** - * Performs the put indexed script operation. - */ -public class TransportPutIndexedScriptAction extends HandledTransportAction { - - private final ScriptService scriptService; - - @Inject - public TransportPutIndexedScriptAction(Settings settings, ThreadPool threadPool, ScriptService scriptService, - TransportService transportService, ActionFilters actionFilters, - IndexNameExpressionResolver indexNameExpressionResolver) { - super(settings, PutIndexedScriptAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver, PutIndexedScriptRequest::new); - this.scriptService = scriptService; - } - - @Override - protected void doExecute(final PutIndexedScriptRequest request, final ActionListener listener) { - scriptService.putScriptToIndex(request, new DelegatingActionListener(listener) { - @Override - public PutIndexedScriptResponse getDelegatedFromInstigator(IndexResponse indexResponse){ - return new PutIndexedScriptResponse(indexResponse.getType(),indexResponse.getId(),indexResponse.getVersion(),indexResponse.isCreated()); - } - }); - } -} diff --git a/core/src/main/java/org/elasticsearch/action/indexedscripts/put/package-info.java b/core/src/main/java/org/elasticsearch/action/indexedscripts/put/package-info.java deleted file mode 100644 index 71e88b727c2..00000000000 --- a/core/src/main/java/org/elasticsearch/action/indexedscripts/put/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/** - * Index action. - */ -package org.elasticsearch.action.indexedscripts.put; \ No newline at end of file diff --git a/core/src/main/java/org/elasticsearch/action/update/UpdateHelper.java b/core/src/main/java/org/elasticsearch/action/update/UpdateHelper.java index 34bc2b25187..9ac77050202 100644 --- a/core/src/main/java/org/elasticsearch/action/update/UpdateHelper.java +++ b/core/src/main/java/org/elasticsearch/action/update/UpdateHelper.java @@ -22,6 +22,8 @@ package org.elasticsearch.action.update; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.client.Requests; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.collect.Tuple; @@ -61,11 +63,13 @@ import java.util.Map; public class UpdateHelper extends AbstractComponent { private final ScriptService scriptService; + private final ClusterService clusterService; @Inject - public UpdateHelper(Settings settings, ScriptService scriptService) { + public UpdateHelper(Settings settings, ScriptService scriptService, ClusterService clusterService) { super(settings); this.scriptService = scriptService; + this.clusterService = clusterService; } /** @@ -246,7 +250,8 @@ public class UpdateHelper extends AbstractComponent { private Map executeScript(Script script, Map ctx) { try { if (scriptService != null) { - ExecutableScript executableScript = scriptService.executable(script, ScriptContext.Standard.UPDATE, Collections.emptyMap()); + ClusterState state = clusterService.state(); + ExecutableScript executableScript = scriptService.executable(script, ScriptContext.Standard.UPDATE, Collections.emptyMap(), state); executableScript.setNextVar("ctx", ctx); executableScript.run(); // we need to unwrap the ctx... diff --git a/core/src/main/java/org/elasticsearch/client/Client.java b/core/src/main/java/org/elasticsearch/client/Client.java index 1c7676bc91c..47e8e43f37b 100644 --- a/core/src/main/java/org/elasticsearch/client/Client.java +++ b/core/src/main/java/org/elasticsearch/client/Client.java @@ -42,15 +42,6 @@ import org.elasticsearch.action.get.MultiGetResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexResponse; -import org.elasticsearch.action.indexedscripts.delete.DeleteIndexedScriptRequest; -import org.elasticsearch.action.indexedscripts.delete.DeleteIndexedScriptRequestBuilder; -import org.elasticsearch.action.indexedscripts.delete.DeleteIndexedScriptResponse; -import org.elasticsearch.action.indexedscripts.get.GetIndexedScriptRequest; -import org.elasticsearch.action.indexedscripts.get.GetIndexedScriptRequestBuilder; -import org.elasticsearch.action.indexedscripts.get.GetIndexedScriptResponse; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptRequest; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptRequestBuilder; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptResponse; import org.elasticsearch.action.percolate.MultiPercolateRequest; import org.elasticsearch.action.percolate.MultiPercolateRequestBuilder; import org.elasticsearch.action.percolate.MultiPercolateResponse; @@ -275,80 +266,6 @@ public interface Client extends ElasticsearchClient, Releasable { */ GetRequestBuilder prepareGet(String index, @Nullable String type, String id); - - /** - * Put an indexed script - */ - PutIndexedScriptRequestBuilder preparePutIndexedScript(); - - /** - * Put the indexed script - */ - PutIndexedScriptRequestBuilder preparePutIndexedScript(@Nullable String scriptLang, String id, String source); - - /** - * delete an indexed script - */ - void deleteIndexedScript(DeleteIndexedScriptRequest request, ActionListener listener); - - /** - * Delete an indexed script - * - * @param request The put request - * @return The result future - */ - ActionFuture deleteIndexedScript(DeleteIndexedScriptRequest request); - - - /** - * Delete an indexed script - */ - DeleteIndexedScriptRequestBuilder prepareDeleteIndexedScript(); - - /** - * Delete an indexed script - */ - DeleteIndexedScriptRequestBuilder prepareDeleteIndexedScript(@Nullable String scriptLang, String id); - - /** - * Put an indexed script - */ - void putIndexedScript(PutIndexedScriptRequest request, ActionListener listener); - - /** - * Put an indexed script - * - * @param request The put request - * @return The result future - */ - ActionFuture putIndexedScript(PutIndexedScriptRequest request); - - - /** - * Get an indexed script - */ - GetIndexedScriptRequestBuilder prepareGetIndexedScript(); - - /** - * Get the indexed script - */ - GetIndexedScriptRequestBuilder prepareGetIndexedScript(@Nullable String scriptLang, String id); - - /** - * Get an indexed script - */ - void getIndexedScript(GetIndexedScriptRequest request, ActionListener listener); - - /** - * Gets the document that was indexed from an index with a type and id. - * - * @param request The get request - * @return The result future - * @see Requests#getRequest(String) - */ - ActionFuture getIndexedScript(GetIndexedScriptRequest request); - - /** * Multi get documents. */ diff --git a/core/src/main/java/org/elasticsearch/client/ClusterAdminClient.java b/core/src/main/java/org/elasticsearch/client/ClusterAdminClient.java index ecfe307e6c1..37886239195 100644 --- a/core/src/main/java/org/elasticsearch/client/ClusterAdminClient.java +++ b/core/src/main/java/org/elasticsearch/client/ClusterAdminClient.java @@ -84,6 +84,15 @@ import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse; import org.elasticsearch.action.admin.cluster.stats.ClusterStatsRequest; import org.elasticsearch.action.admin.cluster.stats.ClusterStatsRequestBuilder; import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse; +import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest; +import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequestBuilder; +import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptResponse; +import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest; +import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequestBuilder; +import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptResponse; +import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequest; +import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequestBuilder; +import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptResponse; import org.elasticsearch.action.admin.cluster.tasks.PendingClusterTasksRequest; import org.elasticsearch.action.admin.cluster.tasks.PendingClusterTasksRequestBuilder; import org.elasticsearch.action.admin.cluster.tasks.PendingClusterTasksResponse; @@ -101,6 +110,7 @@ import org.elasticsearch.action.ingest.SimulatePipelineRequest; import org.elasticsearch.action.ingest.SimulatePipelineRequestBuilder; import org.elasticsearch.action.ingest.SimulatePipelineResponse; import org.elasticsearch.action.ingest.WritePipelineResponse; +import org.elasticsearch.common.Nullable; import org.elasticsearch.common.bytes.BytesReference; /** @@ -590,4 +600,59 @@ public interface ClusterAdminClient extends ElasticsearchClient { * Explain the allocation of a shard */ ClusterAllocationExplainRequestBuilder prepareAllocationExplain(); + + /** + * Store a script in the cluster state + */ + PutStoredScriptRequestBuilder preparePutStoredScript(); + + /** + * Delete a script from the cluster state + */ + void deleteStoredScript(DeleteStoredScriptRequest request, ActionListener listener); + + /** + * Delete a script from the cluster state + */ + ActionFuture deleteStoredScript(DeleteStoredScriptRequest request); + + /** + * Delete a script from the cluster state + */ + DeleteStoredScriptRequestBuilder prepareDeleteStoredScript(); + + /** + * Delete a script from the cluster state + */ + DeleteStoredScriptRequestBuilder prepareDeleteStoredScript(String scriptLang, String id); + + /** + * Store a script in the cluster state + */ + void putStoredScript(PutStoredScriptRequest request, ActionListener listener); + + /** + * Store a script in the cluster state + */ + ActionFuture putStoredScript(PutStoredScriptRequest request); + + /** + * Get a script from the cluster state + */ + GetStoredScriptRequestBuilder prepareGetStoredScript(); + + /** + * Get a script from the cluster state + */ + GetStoredScriptRequestBuilder prepareGetStoredScript(@Nullable String scriptLang, String id); + + /** + * Get a script from the cluster state + */ + void getStoredScript(GetStoredScriptRequest request, ActionListener listener); + + /** + * Get a script from the cluster state + */ + ActionFuture getStoredScript(GetStoredScriptRequest request); } 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 cb1252dc465..6083422862c 100644 --- a/core/src/main/java/org/elasticsearch/client/support/AbstractClient.java +++ b/core/src/main/java/org/elasticsearch/client/support/AbstractClient.java @@ -268,18 +268,18 @@ import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexResponse; -import org.elasticsearch.action.indexedscripts.delete.DeleteIndexedScriptAction; -import org.elasticsearch.action.indexedscripts.delete.DeleteIndexedScriptRequest; -import org.elasticsearch.action.indexedscripts.delete.DeleteIndexedScriptRequestBuilder; -import org.elasticsearch.action.indexedscripts.delete.DeleteIndexedScriptResponse; -import org.elasticsearch.action.indexedscripts.get.GetIndexedScriptAction; -import org.elasticsearch.action.indexedscripts.get.GetIndexedScriptRequest; -import org.elasticsearch.action.indexedscripts.get.GetIndexedScriptRequestBuilder; -import org.elasticsearch.action.indexedscripts.get.GetIndexedScriptResponse; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptAction; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptRequest; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptRequestBuilder; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptResponse; +import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptAction; +import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest; +import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequestBuilder; +import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptResponse; +import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptAction; +import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest; +import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequestBuilder; +import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptResponse; +import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptAction; +import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequest; +import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequestBuilder; +import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptResponse; import org.elasticsearch.action.ingest.DeletePipelineAction; import org.elasticsearch.action.ingest.DeletePipelineRequest; import org.elasticsearch.action.ingest.DeletePipelineRequestBuilder; @@ -504,102 +504,6 @@ public abstract class AbstractClient extends AbstractComponent implements Client return prepareGet().setIndex(index).setType(type).setId(id); } - - @Override - public ActionFuture getIndexedScript(final GetIndexedScriptRequest request) { - return execute(GetIndexedScriptAction.INSTANCE, request); - } - - @Override - public void getIndexedScript(final GetIndexedScriptRequest request, final ActionListener listener) { - execute(GetIndexedScriptAction.INSTANCE, request, listener); - } - - @Override - public GetIndexedScriptRequestBuilder prepareGetIndexedScript() { - return new GetIndexedScriptRequestBuilder(this, GetIndexedScriptAction.INSTANCE); - } - - @Override - public GetIndexedScriptRequestBuilder prepareGetIndexedScript(String scriptLang, String id) { - return prepareGetIndexedScript().setScriptLang(scriptLang).setId(id); - } - - - /** - * Put an indexed script - */ - @Override - public PutIndexedScriptRequestBuilder preparePutIndexedScript() { - return new PutIndexedScriptRequestBuilder(this, PutIndexedScriptAction.INSTANCE); - } - - /** - * Put the indexed script - */ - @Override - public PutIndexedScriptRequestBuilder preparePutIndexedScript(@Nullable String scriptLang, String id, String source){ - return PutIndexedScriptAction.INSTANCE.newRequestBuilder(this).setScriptLang(scriptLang).setId(id).setSource(source); - } - - /** - * Put an indexed script - */ - @Override - public void putIndexedScript(final PutIndexedScriptRequest request, ActionListener listener){ - execute(PutIndexedScriptAction.INSTANCE, request, listener); - - } - - /** - * Put an indexed script - * - * @param request The put request - * @return The result future - */ - @Override - public ActionFuture putIndexedScript(final PutIndexedScriptRequest request){ - return execute(PutIndexedScriptAction.INSTANCE, request); - } - - /** - * delete an indexed script - */ - @Override - public void deleteIndexedScript(DeleteIndexedScriptRequest request, ActionListener listener){ - execute(DeleteIndexedScriptAction.INSTANCE, request, listener); - } - - /** - * Delete an indexed script - * - * @param request The put request - * @return The result future - */ - @Override - public ActionFuture deleteIndexedScript(DeleteIndexedScriptRequest request){ - return execute(DeleteIndexedScriptAction.INSTANCE, request); - } - - - /** - * Delete an indexed script - */ - @Override - public DeleteIndexedScriptRequestBuilder prepareDeleteIndexedScript(){ - return DeleteIndexedScriptAction.INSTANCE.newRequestBuilder(this); - } - - /** - * Delete an indexed script - */ - @Override - public DeleteIndexedScriptRequestBuilder prepareDeleteIndexedScript(@Nullable String scriptLang, String id){ - return prepareDeleteIndexedScript().setScriptLang(scriptLang).setId(id); - } - - - @Override public ActionFuture multiGet(final MultiGetRequest request) { return execute(MultiGetAction.INSTANCE, request); @@ -1264,6 +1168,62 @@ public abstract class AbstractClient extends AbstractComponent implements Client public ClusterAllocationExplainRequestBuilder prepareAllocationExplain() { return new ClusterAllocationExplainRequestBuilder(this, ClusterAllocationExplainAction.INSTANCE); } + + @Override + public ActionFuture getStoredScript(final GetStoredScriptRequest request) { + return execute(GetStoredScriptAction.INSTANCE, request); + } + + @Override + public void getStoredScript(final GetStoredScriptRequest request, final ActionListener listener) { + execute(GetStoredScriptAction.INSTANCE, request, listener); + } + + @Override + public GetStoredScriptRequestBuilder prepareGetStoredScript() { + return new GetStoredScriptRequestBuilder(this, GetStoredScriptAction.INSTANCE); + } + + @Override + public GetStoredScriptRequestBuilder prepareGetStoredScript(String scriptLang, String id) { + return prepareGetStoredScript().setLang(scriptLang).setId(id); + } + + @Override + public PutStoredScriptRequestBuilder preparePutStoredScript() { + return new PutStoredScriptRequestBuilder(this, PutStoredScriptAction.INSTANCE); + } + + @Override + public void putStoredScript(final PutStoredScriptRequest request, ActionListener listener){ + execute(PutStoredScriptAction.INSTANCE, request, listener); + + } + + @Override + public ActionFuture putStoredScript(final PutStoredScriptRequest request){ + return execute(PutStoredScriptAction.INSTANCE, request); + } + + @Override + public void deleteStoredScript(DeleteStoredScriptRequest request, ActionListener listener){ + execute(DeleteStoredScriptAction.INSTANCE, request, listener); + } + + @Override + public ActionFuture deleteStoredScript(DeleteStoredScriptRequest request){ + return execute(DeleteStoredScriptAction.INSTANCE, request); + } + + @Override + public DeleteStoredScriptRequestBuilder prepareDeleteStoredScript(){ + return DeleteStoredScriptAction.INSTANCE.newRequestBuilder(this); + } + + @Override + public DeleteStoredScriptRequestBuilder prepareDeleteStoredScript(@Nullable String scriptLang, String id){ + return prepareDeleteStoredScript().setScriptLang(scriptLang).setId(id); + } } static class IndicesAdmin implements IndicesAdminClient { diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java index 934300e84ce..f48d8dec2bf 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java @@ -59,6 +59,7 @@ import org.elasticsearch.indices.recovery.RecoverySettings; import org.elasticsearch.indices.ttl.IndicesTTLService; import org.elasticsearch.ingest.IngestMetadata; import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.script.ScriptMetaData; import java.io.IOException; import java.util.ArrayList; @@ -115,6 +116,7 @@ public class MetaData implements Iterable, Diffable, Fr // register non plugin custom metadata registerPrototype(RepositoriesMetaData.TYPE, RepositoriesMetaData.PROTO); registerPrototype(IngestMetadata.TYPE, IngestMetadata.PROTO); + registerPrototype(ScriptMetaData.TYPE, ScriptMetaData.PROTO); } /** diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java index 455bfb61739..c8c352fc46d 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java @@ -272,22 +272,12 @@ public class MetaDataCreateIndexService extends AbstractComponent { } // now, put the request settings, so they override templates indexSettingsBuilder.put(request.settings()); - if (request.index().equals(ScriptService.SCRIPT_INDEX)) { - indexSettingsBuilder.put(SETTING_NUMBER_OF_SHARDS, settings.getAsInt(SETTING_NUMBER_OF_SHARDS, 1)); - } else { - if (indexSettingsBuilder.get(SETTING_NUMBER_OF_SHARDS) == null) { - indexSettingsBuilder.put(SETTING_NUMBER_OF_SHARDS, settings.getAsInt(SETTING_NUMBER_OF_SHARDS, 5)); - } + if (indexSettingsBuilder.get(SETTING_NUMBER_OF_SHARDS) == null) { + indexSettingsBuilder.put(SETTING_NUMBER_OF_SHARDS, settings.getAsInt(SETTING_NUMBER_OF_SHARDS, 5)); } - if (request.index().equals(ScriptService.SCRIPT_INDEX)) { - indexSettingsBuilder.put(SETTING_NUMBER_OF_REPLICAS, settings.getAsInt(SETTING_NUMBER_OF_REPLICAS, 0)); - indexSettingsBuilder.put(SETTING_AUTO_EXPAND_REPLICAS, "0-all"); - } else { - if (indexSettingsBuilder.get(SETTING_NUMBER_OF_REPLICAS) == null) { - indexSettingsBuilder.put(SETTING_NUMBER_OF_REPLICAS, settings.getAsInt(SETTING_NUMBER_OF_REPLICAS, 1)); - } + if (indexSettingsBuilder.get(SETTING_NUMBER_OF_REPLICAS) == null) { + indexSettingsBuilder.put(SETTING_NUMBER_OF_REPLICAS, settings.getAsInt(SETTING_NUMBER_OF_REPLICAS, 1)); } - if (settings.get(SETTING_AUTO_EXPAND_REPLICAS) != null && indexSettingsBuilder.get(SETTING_AUTO_EXPAND_REPLICAS) == null) { indexSettingsBuilder.put(SETTING_AUTO_EXPAND_REPLICAS, settings.get(SETTING_AUTO_EXPAND_REPLICAS)); } diff --git a/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java b/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java index 7d6dcc17dbf..c0b650e555d 100644 --- a/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java +++ b/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java @@ -139,17 +139,17 @@ import org.elasticsearch.rest.action.ingest.RestSimulatePipelineAction; import org.elasticsearch.rest.action.main.RestMainAction; import org.elasticsearch.rest.action.percolate.RestMultiPercolateAction; import org.elasticsearch.rest.action.percolate.RestPercolateAction; -import org.elasticsearch.rest.action.script.RestDeleteIndexedScriptAction; -import org.elasticsearch.rest.action.script.RestGetIndexedScriptAction; -import org.elasticsearch.rest.action.script.RestPutIndexedScriptAction; +import org.elasticsearch.rest.action.admin.cluster.storedscripts.RestDeleteStoredScriptAction; +import org.elasticsearch.rest.action.admin.cluster.storedscripts.RestGetStoredScriptAction; +import org.elasticsearch.rest.action.admin.cluster.storedscripts.RestPutStoredScriptAction; import org.elasticsearch.rest.action.search.RestClearScrollAction; import org.elasticsearch.rest.action.search.RestMultiSearchAction; import org.elasticsearch.rest.action.search.RestSearchAction; import org.elasticsearch.rest.action.search.RestSearchScrollAction; import org.elasticsearch.rest.action.suggest.RestSuggestAction; -import org.elasticsearch.rest.action.template.RestDeleteSearchTemplateAction; -import org.elasticsearch.rest.action.template.RestGetSearchTemplateAction; -import org.elasticsearch.rest.action.template.RestPutSearchTemplateAction; +import org.elasticsearch.rest.action.admin.cluster.storedscripts.RestDeleteSearchTemplateAction; +import org.elasticsearch.rest.action.admin.cluster.storedscripts.RestGetSearchTemplateAction; +import org.elasticsearch.rest.action.admin.cluster.storedscripts.RestPutSearchTemplateAction; import org.elasticsearch.rest.action.termvectors.RestMultiTermVectorsAction; import org.elasticsearch.rest.action.termvectors.RestTermVectorsAction; import org.elasticsearch.rest.action.update.RestUpdateAction; @@ -271,9 +271,9 @@ public class NetworkModule extends AbstractModule { RestDeleteSearchTemplateAction.class, // Scripts API - RestGetIndexedScriptAction.class, - RestPutIndexedScriptAction.class, - RestDeleteIndexedScriptAction.class, + RestGetStoredScriptAction.class, + RestPutStoredScriptAction.class, + RestDeleteStoredScriptAction.class, RestFieldStatsAction.class, diff --git a/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java b/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java index 5622461c0ee..dc6e7c4dda1 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java +++ b/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java @@ -317,6 +317,7 @@ public final class ClusterSettings extends AbstractScopedSettings { ScriptService.SCRIPT_CACHE_SIZE_SETTING, ScriptService.SCRIPT_CACHE_EXPIRE_SETTING, ScriptService.SCRIPT_AUTO_RELOAD_ENABLED_SETTING, + ScriptService.SCRIPT_MAX_SIZE_IN_BYTES, IndicesService.INDICES_CACHE_CLEAN_INTERVAL_SETTING, IndicesFieldDataCache.INDICES_FIELDDATA_CACHE_SIZE_KEY, IndicesRequestCache.INDICES_CACHE_QUERY_SIZE, diff --git a/core/src/main/java/org/elasticsearch/index/IndexService.java b/core/src/main/java/org/elasticsearch/index/IndexService.java index dac757477b8..bd96727d28f 100644 --- a/core/src/main/java/org/elasticsearch/index/IndexService.java +++ b/core/src/main/java/org/elasticsearch/index/IndexService.java @@ -443,7 +443,8 @@ public final class IndexService extends AbstractIndexComponent implements IndexC return new QueryShardContext( indexSettings, indexCache.bitsetFilterCache(), indexFieldData, mapperService(), similarityService(), nodeServicesProvider.getScriptService(), nodeServicesProvider.getIndicesQueriesRegistry(), - indexCache.getPercolatorQueryCache(), indexReader + nodeServicesProvider.getClient(), indexCache.getPercolatorQueryCache(), indexReader, + nodeServicesProvider.getClusterService().state() ); } diff --git a/core/src/main/java/org/elasticsearch/index/NodeServicesProvider.java b/core/src/main/java/org/elasticsearch/index/NodeServicesProvider.java index fa245352ae7..866c938c0f5 100644 --- a/core/src/main/java/org/elasticsearch/index/NodeServicesProvider.java +++ b/core/src/main/java/org/elasticsearch/index/NodeServicesProvider.java @@ -20,6 +20,7 @@ package org.elasticsearch.index; import org.elasticsearch.client.Client; +import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.indices.breaker.CircuitBreakerService; @@ -40,15 +41,19 @@ public final class NodeServicesProvider { private final IndicesQueriesRegistry indicesQueriesRegistry; private final ScriptService scriptService; private final CircuitBreakerService circuitBreakerService; + private final ClusterService clusterService; @Inject - public NodeServicesProvider(ThreadPool threadPool, BigArrays bigArrays, Client client, ScriptService scriptService, IndicesQueriesRegistry indicesQueriesRegistry, CircuitBreakerService circuitBreakerService) { + public NodeServicesProvider(ThreadPool threadPool, BigArrays bigArrays, Client client, ScriptService scriptService, + IndicesQueriesRegistry indicesQueriesRegistry, CircuitBreakerService circuitBreakerService, + ClusterService clusterService) { this.threadPool = threadPool; this.bigArrays = bigArrays; this.client = client; this.indicesQueriesRegistry = indicesQueriesRegistry; this.scriptService = scriptService; this.circuitBreakerService = circuitBreakerService; + this.clusterService = clusterService; } public ThreadPool getThreadPool() { @@ -72,4 +77,8 @@ public final class NodeServicesProvider { public CircuitBreakerService getCircuitBreakerService() { return circuitBreakerService; } + + public ClusterService getClusterService() { + return clusterService; + } } diff --git a/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java b/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java index eb471cd818e..b1c8b03fe37 100755 --- a/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java @@ -138,18 +138,7 @@ public class MapperService extends AbstractIndexComponent { this.mapperRegistry = mapperRegistry; this.dynamic = this.indexSettings.getValue(INDEX_MAPPER_DYNAMIC_SETTING); - if (index().getName().equals(ScriptService.SCRIPT_INDEX)){ - defaultMappingSource = "{" + - "\"_default_\": {" + - "\"properties\": {" + - "\"script\": { \"enabled\": false }," + - "\"template\": { \"enabled\": false }" + - "}" + - "}" + - "}"; - } else { - defaultMappingSource = "{\"_default_\":{}}"; - } + defaultMappingSource = "{\"_default_\":{}}"; if (logger.isTraceEnabled()) { logger.trace("using dynamic[{}], default mapping source[{}]", dynamic, defaultMappingSource); diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java b/core/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java index ea16c7ea297..d8ec9ef2a47 100644 --- a/core/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java +++ b/core/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java @@ -22,6 +22,7 @@ import org.apache.lucene.index.IndexReader; import org.elasticsearch.client.Client; import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.ParseFieldMatcherSupplier; +import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.mapper.MapperService; @@ -36,22 +37,27 @@ public class QueryRewriteContext implements ParseFieldMatcherSupplier { protected final ScriptService scriptService; protected final IndexSettings indexSettings; protected final IndicesQueriesRegistry indicesQueriesRegistry; + protected final Client client; protected final IndexReader reader; + protected final ClusterState clusterState; public QueryRewriteContext(IndexSettings indexSettings, MapperService mapperService, ScriptService scriptService, - IndicesQueriesRegistry indicesQueriesRegistry, IndexReader reader) { + IndicesQueriesRegistry indicesQueriesRegistry, Client client, IndexReader reader, + ClusterState clusterState) { this.mapperService = mapperService; this.scriptService = scriptService; this.indexSettings = indexSettings; this.indicesQueriesRegistry = indicesQueriesRegistry; + this.client = client; this.reader = reader; + this.clusterState = clusterState; } /** * Returns a clients to fetch resources from local or remove nodes. */ public final Client getClient() { - return scriptService.getClient(); + return client; } /** @@ -86,6 +92,13 @@ public class QueryRewriteContext implements ParseFieldMatcherSupplier { return this.indexSettings.getParseFieldMatcher(); } + /** + * Returns the cluster state as is when the operation started. + */ + public ClusterState getClusterState() { + return clusterState; + } + /** * Returns a new {@link QueryParseContext} that wraps the provided parser, using the ParseFieldMatcher settings that * are configured in the index settings diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java b/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java index ed87ead696a..494c75aabf0 100644 --- a/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java +++ b/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java @@ -35,6 +35,8 @@ import org.apache.lucene.search.Query; import org.apache.lucene.search.join.BitSetProducer; import org.apache.lucene.search.similarities.Similarity; import org.elasticsearch.Version; +import org.elasticsearch.client.Client; +import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.Strings; @@ -93,9 +95,11 @@ public class QueryShardContext extends QueryRewriteContext { private NestedScope nestedScope; boolean isFilter; // pkg private for testing - public QueryShardContext(IndexSettings indexSettings, BitsetFilterCache bitsetFilterCache, IndexFieldDataService indexFieldDataService, MapperService mapperService, SimilarityService similarityService, ScriptService scriptService, - final IndicesQueriesRegistry indicesQueriesRegistry, PercolatorQueryCache percolatorQueryCache, IndexReader reader) { - super(indexSettings, mapperService, scriptService, indicesQueriesRegistry, reader); + public QueryShardContext(IndexSettings indexSettings, BitsetFilterCache bitsetFilterCache, IndexFieldDataService indexFieldDataService, + MapperService mapperService, SimilarityService similarityService, ScriptService scriptService, + final IndicesQueriesRegistry indicesQueriesRegistry, Client client, PercolatorQueryCache percolatorQueryCache, + IndexReader reader, ClusterState clusterState) { + super(indexSettings, mapperService, scriptService, indicesQueriesRegistry, client, reader, clusterState); this.indexSettings = indexSettings; this.similarityService = similarityService; this.mapperService = mapperService; @@ -108,7 +112,9 @@ public class QueryShardContext extends QueryRewriteContext { } public QueryShardContext(QueryShardContext source) { - this(source.indexSettings, source.bitsetFilterCache, source.indexFieldDataService, source.mapperService, source.similarityService, source.scriptService, source.indicesQueriesRegistry, source.percolatorQueryCache, source.reader); + this(source.indexSettings, source.bitsetFilterCache, source.indexFieldDataService, source.mapperService, + source.similarityService, source.scriptService, source.indicesQueriesRegistry, source.client, + source.percolatorQueryCache, source.reader, source.clusterState); this.types = source.getTypes(); } diff --git a/core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java index 8ff254b3462..12aba8ae879 100644 --- a/core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/ScriptQueryBuilder.java @@ -25,6 +25,7 @@ import org.apache.lucene.search.Query; import org.apache.lucene.search.RandomAccessWeight; import org.apache.lucene.search.Weight; import org.apache.lucene.util.Bits; +import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.io.stream.StreamInput; @@ -155,7 +156,7 @@ public class ScriptQueryBuilder extends AbstractQueryBuilder @Override protected Query doToQuery(QueryShardContext context) throws IOException { - return new ScriptQuery(script, context.getScriptService(), context.lookup()); + return new ScriptQuery(script, context.getScriptService(), context.lookup(), context.getClusterState()); } static class ScriptQuery extends Query { @@ -164,9 +165,9 @@ public class ScriptQueryBuilder extends AbstractQueryBuilder private final SearchScript searchScript; - public ScriptQuery(Script script, ScriptService scriptService, SearchLookup searchLookup) { + public ScriptQuery(Script script, ScriptService scriptService, SearchLookup searchLookup, ClusterState state) { this.script = script; - this.searchScript = scriptService.search(searchLookup, script, ScriptContext.Standard.SEARCH, Collections.emptyMap()); + this.searchScript = scriptService.search(searchLookup, script, ScriptContext.Standard.SEARCH, Collections.emptyMap(), state); } @Override diff --git a/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java index abd4f4b176f..80b3f2b1404 100644 --- a/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java @@ -50,7 +50,7 @@ public class TemplateQueryBuilder extends AbstractQueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { ExecutableScript executable = queryRewriteContext.getScriptService().executable(template, - ScriptContext.Standard.SEARCH, Collections.emptyMap()); + ScriptContext.Standard.SEARCH, Collections.emptyMap(), queryRewriteContext.getClusterState()); BytesReference querySource = (BytesReference) executable.run(); try (XContentParser qSourceParser = XContentFactory.xContent(querySource).createParser(querySource)) { final QueryParseContext queryParseContext = queryRewriteContext.newParseContext(qSourceParser); diff --git a/core/src/main/java/org/elasticsearch/index/query/functionscore/ScriptScoreFunctionBuilder.java b/core/src/main/java/org/elasticsearch/index/query/functionscore/ScriptScoreFunctionBuilder.java index a33a9c14fb7..1684e58eb48 100644 --- a/core/src/main/java/org/elasticsearch/index/query/functionscore/ScriptScoreFunctionBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/functionscore/ScriptScoreFunctionBuilder.java @@ -103,7 +103,7 @@ public class ScriptScoreFunctionBuilder extends ScoreFunctionBuilder model) { diff --git a/core/src/main/java/org/elasticsearch/rest/action/template/RestDeleteSearchTemplateAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestDeleteSearchTemplateAction.java similarity index 85% rename from core/src/main/java/org/elasticsearch/rest/action/template/RestDeleteSearchTemplateAction.java rename to core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestDeleteSearchTemplateAction.java index 3d0daf37b63..4a745d87e71 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/template/RestDeleteSearchTemplateAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestDeleteSearchTemplateAction.java @@ -16,19 +16,19 @@ * specific language governing permissions and limitations * under the License. */ -package org.elasticsearch.rest.action.template; +package org.elasticsearch.rest.action.admin.cluster.storedscripts; import org.elasticsearch.client.Client; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.rest.action.script.RestDeleteIndexedScriptAction; +import org.elasticsearch.rest.action.admin.cluster.storedscripts.RestDeleteStoredScriptAction; import org.elasticsearch.script.Template; import static org.elasticsearch.rest.RestRequest.Method.DELETE; -public class RestDeleteSearchTemplateAction extends RestDeleteIndexedScriptAction { +public class RestDeleteSearchTemplateAction extends RestDeleteStoredScriptAction { @Inject public RestDeleteSearchTemplateAction(Settings settings, RestController controller, Client client) { diff --git a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestDeleteStoredScriptAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestDeleteStoredScriptAction.java new file mode 100644 index 00000000000..a8190d30278 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestDeleteStoredScriptAction.java @@ -0,0 +1,57 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.elasticsearch.rest.action.admin.cluster.storedscripts; + +import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest; +import org.elasticsearch.client.Client; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.rest.BaseRestHandler; +import org.elasticsearch.rest.RestChannel; +import org.elasticsearch.rest.RestController; +import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.action.support.AcknowledgedRestListener; + +import static org.elasticsearch.rest.RestRequest.Method.DELETE; + +public class RestDeleteStoredScriptAction extends BaseRestHandler { + + @Inject + public RestDeleteStoredScriptAction(Settings settings, RestController controller, Client client) { + this(settings, controller, true, client); + } + + protected RestDeleteStoredScriptAction(Settings settings, RestController controller, boolean registerDefaultHandlers, Client client) { + super(settings, client); + if (registerDefaultHandlers) { + controller.registerHandler(DELETE, "/_scripts/{lang}/{id}", this); + } + } + + protected String getScriptLang(RestRequest request) { + return request.param("lang"); + } + + @Override + public void handleRequest(final RestRequest request, final RestChannel channel, Client client) { + DeleteStoredScriptRequest deleteStoredScriptRequest = new DeleteStoredScriptRequest(getScriptLang(request), request.param("id")); + client.admin().cluster().deleteStoredScript(deleteStoredScriptRequest, new AcknowledgedRestListener<>(channel)); + } + +} diff --git a/core/src/main/java/org/elasticsearch/rest/action/template/RestGetSearchTemplateAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestGetSearchTemplateAction.java similarity index 87% rename from core/src/main/java/org/elasticsearch/rest/action/template/RestGetSearchTemplateAction.java rename to core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestGetSearchTemplateAction.java index 4c25d6166e0..cb672d3567f 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/template/RestGetSearchTemplateAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestGetSearchTemplateAction.java @@ -16,14 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.elasticsearch.rest.action.template; +package org.elasticsearch.rest.action.admin.cluster.storedscripts; import org.elasticsearch.client.Client; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.rest.action.script.RestGetIndexedScriptAction; +import org.elasticsearch.rest.action.admin.cluster.storedscripts.RestGetStoredScriptAction; import org.elasticsearch.script.Template; import static org.elasticsearch.rest.RestRequest.Method.GET; @@ -31,7 +31,7 @@ import static org.elasticsearch.rest.RestRequest.Method.GET; /** * */ -public class RestGetSearchTemplateAction extends RestGetIndexedScriptAction { +public class RestGetSearchTemplateAction extends RestGetStoredScriptAction { @Inject public RestGetSearchTemplateAction(Settings settings, RestController controller, Client client) { diff --git a/core/src/main/java/org/elasticsearch/rest/action/script/RestGetIndexedScriptAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestGetStoredScriptAction.java similarity index 63% rename from core/src/main/java/org/elasticsearch/rest/action/script/RestGetIndexedScriptAction.java rename to core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestGetStoredScriptAction.java index 0ed1c309bc5..bf286f623fb 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/script/RestGetIndexedScriptAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestGetStoredScriptAction.java @@ -16,15 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.elasticsearch.rest.action.script; +package org.elasticsearch.rest.action.admin.cluster.storedscripts; -import org.elasticsearch.action.indexedscripts.get.GetIndexedScriptRequest; -import org.elasticsearch.action.indexedscripts.get.GetIndexedScriptResponse; +import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest; +import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptResponse; import org.elasticsearch.client.Client; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.index.VersionType; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.BytesRestResponse; import org.elasticsearch.rest.RestChannel; @@ -36,17 +35,14 @@ import org.elasticsearch.rest.action.support.RestBuilderListener; import static org.elasticsearch.rest.RestRequest.Method.GET; -/** - * - */ -public class RestGetIndexedScriptAction extends BaseRestHandler { +public class RestGetStoredScriptAction extends BaseRestHandler { @Inject - public RestGetIndexedScriptAction(Settings settings, RestController controller, Client client) { + public RestGetStoredScriptAction(Settings settings, RestController controller, Client client) { this(settings, controller, true, client); } - protected RestGetIndexedScriptAction(Settings settings, RestController controller, boolean registerDefaultHandlers, Client client) { + protected RestGetStoredScriptAction(Settings settings, RestController controller, boolean registerDefaultHandlers, Client client) { super(settings, client); if (registerDefaultHandlers) { controller.registerHandler(GET, "/_scripts/{lang}/{id}", this); @@ -63,20 +59,18 @@ public class RestGetIndexedScriptAction extends BaseRestHandler { @Override public void handleRequest(final RestRequest request, final RestChannel channel, Client client) { - final GetIndexedScriptRequest getRequest = new GetIndexedScriptRequest(getScriptLang(request), request.param("id")); - getRequest.version(request.paramAsLong("version", getRequest.version())); - getRequest.versionType(VersionType.fromString(request.param("version_type"), getRequest.versionType())); - client.getIndexedScript(getRequest, new RestBuilderListener(channel) { + final GetStoredScriptRequest getRequest = new GetStoredScriptRequest(getScriptLang(request), request.param("id")); + client.admin().cluster().getStoredScript(getRequest, new RestBuilderListener(channel) { @Override - public RestResponse buildResponse(GetIndexedScriptResponse response, XContentBuilder builder) throws Exception { + public RestResponse buildResponse(GetStoredScriptResponse response, XContentBuilder builder) throws Exception { builder.startObject(); - builder.field(Fields.LANG, response.getScriptLang()); - builder.field(Fields._ID, response.getId()); - builder.field(Fields.FOUND, response.isExists()); + builder.field(Fields.LANG, getRequest.lang()); + builder.field(Fields._ID, getRequest.id()); + boolean found = response.getStoredScript() != null; + builder.field(Fields.FOUND, found); RestStatus status = RestStatus.NOT_FOUND; - if (response.isExists()) { - builder.field(Fields._VERSION, response.getVersion()); - builder.field(getScriptFieldName(), response.getScript()); + if (found) { + builder.field(getScriptFieldName(), response.getStoredScript()); status = RestStatus.OK; } builder.endObject(); @@ -89,7 +83,6 @@ public class RestGetIndexedScriptAction extends BaseRestHandler { private static final String SCRIPT = "script"; private static final String LANG = "lang"; private static final String _ID = "_id"; - private static final String _VERSION = "_version"; private static final String FOUND = "found"; } } diff --git a/core/src/main/java/org/elasticsearch/rest/action/template/RestPutSearchTemplateAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestPutSearchTemplateAction.java similarity index 92% rename from core/src/main/java/org/elasticsearch/rest/action/template/RestPutSearchTemplateAction.java rename to core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestPutSearchTemplateAction.java index 4d0da8f0d14..e9284d51474 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/template/RestPutSearchTemplateAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestPutSearchTemplateAction.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.elasticsearch.rest.action.template; +package org.elasticsearch.rest.action.admin.cluster.storedscripts; import org.elasticsearch.client.Client; import org.elasticsearch.common.inject.Inject; @@ -25,7 +25,6 @@ import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestChannel; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.rest.action.script.RestPutIndexedScriptAction; import org.elasticsearch.script.Template; import static org.elasticsearch.rest.RestRequest.Method.POST; @@ -34,7 +33,7 @@ import static org.elasticsearch.rest.RestRequest.Method.PUT; /** * */ -public class RestPutSearchTemplateAction extends RestPutIndexedScriptAction { +public class RestPutSearchTemplateAction extends RestPutStoredScriptAction { @Inject public RestPutSearchTemplateAction(Settings settings, RestController controller, Client client) { diff --git a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestPutStoredScriptAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestPutStoredScriptAction.java new file mode 100644 index 00000000000..889ff459393 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/storedscripts/RestPutStoredScriptAction.java @@ -0,0 +1,75 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.elasticsearch.rest.action.admin.cluster.storedscripts; + +import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequest; +import org.elasticsearch.client.Client; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.rest.BaseRestHandler; +import org.elasticsearch.rest.RestChannel; +import org.elasticsearch.rest.RestController; +import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.action.support.AcknowledgedRestListener; + +import static org.elasticsearch.rest.RestRequest.Method.POST; +import static org.elasticsearch.rest.RestRequest.Method.PUT; + +public class RestPutStoredScriptAction extends BaseRestHandler { + + @Inject + public RestPutStoredScriptAction(Settings settings, RestController controller, Client client) { + this(settings, controller, true, client); + } + + protected RestPutStoredScriptAction(Settings settings, RestController controller, boolean registerDefaultHandlers, Client client) { + super(settings, client); + if (registerDefaultHandlers) { + controller.registerHandler(POST, "/_scripts/{lang}/{id}", this); + controller.registerHandler(PUT, "/_scripts/{lang}/{id}", this); + + controller.registerHandler(PUT, "/_scripts/{lang}/{id}/_create", new CreateHandler(settings, controller, client)); + controller.registerHandler(POST, "/_scripts/{lang}/{id}/_create", new CreateHandler(settings, controller, client)); + } + } + + final class CreateHandler extends BaseRestHandler { + protected CreateHandler(Settings settings, RestController controller, Client client) { + super(settings, client); + } + + @Override + public void handleRequest(RestRequest request, RestChannel channel, final Client client) { + request.params().put("op_type", "create"); + RestPutStoredScriptAction.this.handleRequest(request, channel, client); + } + } + + protected String getScriptLang(RestRequest request) { + return request.param("lang"); + } + + @Override + public void handleRequest(final RestRequest request, final RestChannel channel, Client client) { + PutStoredScriptRequest putRequest = new PutStoredScriptRequest(getScriptLang(request), request.param("id")); + putRequest.script(request.content()); + client.admin().cluster().putStoredScript(putRequest, new AcknowledgedRestListener<>(channel)); + } + +} diff --git a/core/src/main/java/org/elasticsearch/rest/action/admin/indices/validate/template/RestRenderSearchTemplateAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/indices/validate/template/RestRenderSearchTemplateAction.java index 1cbe7b95816..0db4b5b179c 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/admin/indices/validate/template/RestRenderSearchTemplateAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/indices/validate/template/RestRenderSearchTemplateAction.java @@ -92,7 +92,7 @@ public class RestRenderSearchTemplateAction extends BaseRestHandler { token); } } - template = new Template(templateId, ScriptType.INDEXED, Template.DEFAULT_LANG, null, params); + template = new Template(templateId, ScriptType.STORED, Template.DEFAULT_LANG, null, params); } renderSearchTemplateRequest = new RenderSearchTemplateRequest(); renderSearchTemplateRequest.template(template); diff --git a/core/src/main/java/org/elasticsearch/rest/action/script/RestDeleteIndexedScriptAction.java b/core/src/main/java/org/elasticsearch/rest/action/script/RestDeleteIndexedScriptAction.java deleted file mode 100644 index ce4cb9c057a..00000000000 --- a/core/src/main/java/org/elasticsearch/rest/action/script/RestDeleteIndexedScriptAction.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.elasticsearch.rest.action.script; - -import org.elasticsearch.action.indexedscripts.delete.DeleteIndexedScriptRequest; -import org.elasticsearch.action.indexedscripts.delete.DeleteIndexedScriptResponse; -import org.elasticsearch.client.Client; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.index.VersionType; -import org.elasticsearch.rest.BaseRestHandler; -import org.elasticsearch.rest.BytesRestResponse; -import org.elasticsearch.rest.RestChannel; -import org.elasticsearch.rest.RestController; -import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.rest.RestResponse; -import org.elasticsearch.rest.RestStatus; -import org.elasticsearch.rest.action.support.RestBuilderListener; - -import static org.elasticsearch.rest.RestRequest.Method.DELETE; -import static org.elasticsearch.rest.RestStatus.NOT_FOUND; -import static org.elasticsearch.rest.RestStatus.OK; - -public class RestDeleteIndexedScriptAction extends BaseRestHandler { - - @Inject - public RestDeleteIndexedScriptAction(Settings settings, RestController controller, Client client) { - this(settings, controller, true, client); - } - - protected RestDeleteIndexedScriptAction(Settings settings, RestController controller, boolean registerDefaultHandlers, Client client) { - super(settings, client); - if (registerDefaultHandlers) { - controller.registerHandler(DELETE, "/_scripts/{lang}/{id}", this); - } - } - - protected String getScriptLang(RestRequest request) { - return request.param("lang"); - } - - @Override - public void handleRequest(final RestRequest request, final RestChannel channel, Client client) { - DeleteIndexedScriptRequest deleteIndexedScriptRequest = new DeleteIndexedScriptRequest(getScriptLang(request), request.param("id")); - deleteIndexedScriptRequest.version(request.paramAsLong("version", deleteIndexedScriptRequest.version())); - deleteIndexedScriptRequest.versionType(VersionType.fromString(request.param("version_type"), deleteIndexedScriptRequest.versionType())); - client.deleteIndexedScript(deleteIndexedScriptRequest, new RestBuilderListener(channel) { - @Override - public RestResponse buildResponse(DeleteIndexedScriptResponse result, XContentBuilder builder) throws Exception { - builder.startObject() - .field(Fields.FOUND, result.isFound()) - .field(Fields._INDEX, result.getIndex()) - .field(Fields._TYPE, result.getType()) - .field(Fields._ID, result.getId()) - .field(Fields._VERSION, result.getVersion()) - .endObject(); - RestStatus status = OK; - if (!result.isFound()) { - status = NOT_FOUND; - } - return new BytesRestResponse(status, builder); - } - }); - } - - static final class Fields { - static final String FOUND = "found"; - static final String _INDEX = "_index"; - static final String _TYPE = "_type"; - static final String _ID = "_id"; - static final String _VERSION = "_version"; - } -} diff --git a/core/src/main/java/org/elasticsearch/rest/action/script/RestPutIndexedScriptAction.java b/core/src/main/java/org/elasticsearch/rest/action/script/RestPutIndexedScriptAction.java deleted file mode 100644 index b0f1842d98a..00000000000 --- a/core/src/main/java/org/elasticsearch/rest/action/script/RestPutIndexedScriptAction.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.elasticsearch.rest.action.script; - -import org.elasticsearch.action.index.IndexRequest; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptRequest; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptResponse; -import org.elasticsearch.client.Client; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.index.VersionType; -import org.elasticsearch.rest.BaseRestHandler; -import org.elasticsearch.rest.BytesRestResponse; -import org.elasticsearch.rest.RestChannel; -import org.elasticsearch.rest.RestController; -import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.rest.RestResponse; -import org.elasticsearch.rest.RestStatus; -import org.elasticsearch.rest.action.support.RestBuilderListener; - -import java.io.IOException; - -import static org.elasticsearch.rest.RestRequest.Method.POST; -import static org.elasticsearch.rest.RestRequest.Method.PUT; -import static org.elasticsearch.rest.RestStatus.BAD_REQUEST; -import static org.elasticsearch.rest.RestStatus.CREATED; -import static org.elasticsearch.rest.RestStatus.OK; - -/** - * - */ -public class RestPutIndexedScriptAction extends BaseRestHandler { - - @Inject - public RestPutIndexedScriptAction(Settings settings, RestController controller, Client client) { - this(settings, controller, true, client); - } - - protected RestPutIndexedScriptAction(Settings settings, RestController controller, boolean registerDefaultHandlers, Client client) { - super(settings, client); - if (registerDefaultHandlers) { - controller.registerHandler(POST, "/_scripts/{lang}/{id}", this); - controller.registerHandler(PUT, "/_scripts/{lang}/{id}", this); - - controller.registerHandler(PUT, "/_scripts/{lang}/{id}/_create", new CreateHandler(settings, controller, client)); - controller.registerHandler(POST, "/_scripts/{lang}/{id}/_create", new CreateHandler(settings, controller, client)); - } - } - - final class CreateHandler extends BaseRestHandler { - protected CreateHandler(Settings settings, RestController controller, Client client) { - super(settings, client); - } - - @Override - public void handleRequest(RestRequest request, RestChannel channel, final Client client) { - request.params().put("op_type", "create"); - RestPutIndexedScriptAction.this.handleRequest(request, channel, client); - } - } - - protected String getScriptLang(RestRequest request) { - return request.param("lang"); - } - - @Override - public void handleRequest(final RestRequest request, final RestChannel channel, Client client) { - PutIndexedScriptRequest putRequest = new PutIndexedScriptRequest(getScriptLang(request), request.param("id")); - putRequest.version(request.paramAsLong("version", putRequest.version())); - putRequest.versionType(VersionType.fromString(request.param("version_type"), putRequest.versionType())); - putRequest.source(request.content()); - String sOpType = request.param("op_type"); - if (sOpType != null) { - try { - putRequest.opType(IndexRequest.OpType.fromString(sOpType)); - } catch (IllegalArgumentException eia){ - try { - XContentBuilder builder = channel.newErrorBuilder(); - channel.sendResponse(new BytesRestResponse(BAD_REQUEST, builder.startObject().field("error", eia.getMessage()).endObject())); - return; - } catch (IOException e1) { - logger.warn("Failed to send response", e1); - return; - } - } - } - - client.putIndexedScript(putRequest, new RestBuilderListener(channel) { - @Override - public RestResponse buildResponse(PutIndexedScriptResponse response, XContentBuilder builder) throws Exception { - builder.startObject() - .field(Fields._ID, response.getId()) - .field(Fields._VERSION, response.getVersion()) - .field(Fields.CREATED, response.isCreated()); - builder.endObject(); - RestStatus status = OK; - if (response.isCreated()) { - status = CREATED; - } - return new BytesRestResponse(status, builder); - } - }); - } - - static final class Fields { - static final String _VERSION = "_version"; - static final String _ID = "_id"; - static final String CREATED = "created"; - } -} diff --git a/core/src/main/java/org/elasticsearch/script/AbstractScriptParser.java b/core/src/main/java/org/elasticsearch/script/AbstractScriptParser.java index c51bff59cfc..a1751037f43 100644 --- a/core/src/main/java/org/elasticsearch/script/AbstractScriptParser.java +++ b/core/src/main/java/org/elasticsearch/script/AbstractScriptParser.java @@ -78,8 +78,8 @@ public abstract class AbstractScriptParser { } else { throw new ScriptParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token); } - } else if (parseFieldMatcher.match(currentFieldName, ScriptType.INDEXED.getParseField()) || parseFieldMatcher.match(currentFieldName, ScriptService.SCRIPT_ID)) { - type = ScriptType.INDEXED; + } else if (parseFieldMatcher.match(currentFieldName, ScriptType.STORED.getParseField()) || parseFieldMatcher.match(currentFieldName, ScriptService.SCRIPT_ID)) { + type = ScriptType.STORED; if (token == XContentParser.Token.VALUE_STRING) { script = parser.text(); } else { @@ -110,7 +110,7 @@ public abstract class AbstractScriptParser { } if (script == null) { throw new ScriptParseException("expected one of [{}], [{}] or [{}] fields, but found none", ScriptType.INLINE.getParseField() - .getPreferredName(), ScriptType.FILE.getParseField().getPreferredName(), ScriptType.INDEXED.getParseField() + .getPreferredName(), ScriptType.FILE.getParseField().getPreferredName(), ScriptType.STORED.getParseField() .getPreferredName()); } assert type != null : "if script is not null, type should definitely not be null"; @@ -173,10 +173,10 @@ public abstract class AbstractScriptParser { } else { throw new ScriptParseException("Value must be of type String: [" + parameterName + "]"); } - } else if (parseFieldMatcher.match(parameterName, ScriptType.INDEXED.getParseField()) || parseFieldMatcher.match(parameterName, ScriptService.SCRIPT_ID)) { + } else if (parseFieldMatcher.match(parameterName, ScriptType.STORED.getParseField()) || parseFieldMatcher.match(parameterName, ScriptService.SCRIPT_ID)) { if (parameterValue instanceof String || parameterValue == null) { script = (String) parameterValue; - type = ScriptType.INDEXED; + type = ScriptType.STORED; if (removeMatchedEntries) { itr.remove(); } @@ -187,11 +187,11 @@ public abstract class AbstractScriptParser { } if (script == null) { throw new ScriptParseException("expected one of [{}], [{}] or [{}] fields, but found none", ScriptType.INLINE.getParseField() - .getPreferredName(), ScriptType.FILE.getParseField().getPreferredName(), ScriptType.INDEXED.getParseField() + .getPreferredName(), ScriptType.FILE.getParseField().getPreferredName(), ScriptType.STORED.getParseField() .getPreferredName()); } assert type != null : "if script is not null, type should definitely not be null"; return createScript(script, type, lang, params); } -} \ No newline at end of file +} diff --git a/core/src/main/java/org/elasticsearch/script/ScriptMetaData.java b/core/src/main/java/org/elasticsearch/script/ScriptMetaData.java new file mode 100644 index 00000000000..c0cf4bc65ca --- /dev/null +++ b/core/src/main/java/org/elasticsearch/script/ScriptMetaData.java @@ -0,0 +1,299 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.elasticsearch.script; + +import org.elasticsearch.ResourceNotFoundException; +import org.elasticsearch.cluster.AbstractDiffable; +import org.elasticsearch.cluster.Diff; +import org.elasticsearch.cluster.DiffableUtils; +import org.elasticsearch.cluster.metadata.MetaData; +import org.elasticsearch.common.ParseFieldMatcher; +import org.elasticsearch.common.ParsingException; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.common.xcontent.XContentHelper; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentParser.Token; +import org.elasticsearch.common.xcontent.XContentType; + +import java.io.IOException; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +public final class ScriptMetaData implements MetaData.Custom { + + public final static String TYPE = "stored_scripts"; + public final static ScriptMetaData PROTO = new ScriptMetaData(Collections.emptyMap()); + + private final Map scripts; + + ScriptMetaData(Map scripts) { + this.scripts = scripts; + } + + public BytesReference getScriptAsBytes(String language, String id) { + ScriptAsBytes scriptAsBytes = scripts.get(toKey(language, id)); + if (scriptAsBytes != null) { + return scriptAsBytes.script; + } else { + return null; + } + } + + public String getScript(String language, String id) { + BytesReference scriptAsBytes = getScriptAsBytes(language, id); + if (scriptAsBytes == null) { + return null; + } + + // Scripts can be stored via API in several ways: + // 1) wrapped into a 'script' json object or field + // 2) wrapped into a 'template' json object or field + // 3) just as is + // In order to fetch the actual script in consistent manner this parsing logic is needed: + try (XContentParser parser = XContentHelper.createParser(scriptAsBytes); + XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON)) { + parser.nextToken(); + parser.nextToken(); + switch (parser.currentName()) { + case "script": + if (parser.nextToken() == Token.VALUE_STRING) { + return parser.text(); + } else { + builder.copyCurrentStructure(parser); + } + break; + case "template": + if (parser.nextToken() == Token.VALUE_STRING) { + return parser.text(); + } else { + builder.copyCurrentStructure(parser); + } + break; + default: + // There is no enclosing 'script' or 'template' object so we just need to return the script as is... + // because the parsers current location is already beyond the beginning we need to add a START_OBJECT: + builder.startObject(); + builder.copyCurrentStructure(parser); + break; + } + return builder.string(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public String type() { + return TYPE; + } + + @Override + public ScriptMetaData fromXContent(XContentParser parser) throws IOException { + Map scripts = new HashMap<>(); + String key = null; + for (Token token = parser.nextToken(); token != Token.END_OBJECT; token = parser.nextToken()) { + switch (token) { + case FIELD_NAME: + key = parser.currentName(); + break; + case START_OBJECT: + XContentBuilder contentBuilder = XContentBuilder.builder(parser.contentType().xContent()); + contentBuilder.copyCurrentStructure(parser); + scripts.put(key, new ScriptAsBytes(contentBuilder.bytes())); + break; + default: + throw new ParsingException(parser.getTokenLocation(), "Unexpected token [" + token + "]"); + } + } + return new ScriptMetaData(scripts); + } + + @Override + public EnumSet context() { + return MetaData.API_AND_GATEWAY; + } + + @Override + public ScriptMetaData readFrom(StreamInput in) throws IOException { + int size = in.readVInt(); + Map scripts = new HashMap<>(); + for (int i = 0; i < size; i++) { + String languageAndId = in.readString(); + BytesReference script = in.readBytesReference(); + scripts.put(languageAndId, new ScriptAsBytes(script)); + } + return new ScriptMetaData(scripts); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + for (Map.Entry entry : scripts.entrySet()) { + builder.rawField(entry.getKey(), entry.getValue().script); + } + return builder; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeVInt(scripts.size()); + for (Map.Entry entry : scripts.entrySet()) { + out.writeString(entry.getKey()); + entry.getValue().writeTo(out); + } + } + + @Override + public Diff diff(MetaData.Custom before) { + return new ScriptMetadataDiff((ScriptMetaData) before, this); + } + + @Override + public Diff readDiffFrom(StreamInput in) throws IOException { + return new ScriptMetadataDiff(in); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ScriptMetaData other = (ScriptMetaData) o; + return scripts.equals(other.scripts); + } + + @Override + public int hashCode() { + return scripts.hashCode(); + } + + @Override + public String toString() { + return "ScriptMetaData{" + + "scripts=" + scripts + + '}'; + } + + static String toKey(String language, String id) { + if (id.contains("#")) { + throw new IllegalArgumentException("stored script id can't contain: '#'"); + } + if (language.contains("#")) { + throw new IllegalArgumentException("stored script language can't contain: '#'"); + } + + return language + "#" + id; + } + + final public static class Builder { + + private Map scripts; + + public Builder(ScriptMetaData previous) { + if (previous != null) { + this.scripts = new HashMap<>(previous.scripts); + } else { + this.scripts = new HashMap<>(); + } + } + + public Builder storeScript(String lang, String id, BytesReference script) { + scripts.put(toKey(lang, id), new ScriptAsBytes(script)); + return this; + } + + public Builder deleteScript(String lang, String id) { + if (scripts.remove(toKey(lang, id)) == null) { + throw new ResourceNotFoundException("Stored script with id [{}] for language [{}] does not exist", id, lang); + } + return this; + } + + public ScriptMetaData build() { + return new ScriptMetaData(Collections.unmodifiableMap(scripts)); + } + } + + final static class ScriptMetadataDiff implements Diff { + + final Diff> pipelines; + + ScriptMetadataDiff(ScriptMetaData before, ScriptMetaData after) { + this.pipelines = DiffableUtils.diff(before.scripts, after.scripts, DiffableUtils.getStringKeySerializer()); + } + + public ScriptMetadataDiff(StreamInput in) throws IOException { + pipelines = DiffableUtils.readJdkMapDiff(in, DiffableUtils.getStringKeySerializer(), new ScriptAsBytes(null)); + } + + @Override + public MetaData.Custom apply(MetaData.Custom part) { + return new ScriptMetaData(pipelines.apply(((ScriptMetaData) part).scripts)); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + pipelines.writeTo(out); + } + } + + final static class ScriptAsBytes extends AbstractDiffable { + + public ScriptAsBytes(BytesReference script) { + this.script = script; + } + + private final BytesReference script; + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeBytesReference(script); + } + + @Override + public ScriptAsBytes readFrom(StreamInput in) throws IOException { + return new ScriptAsBytes(in.readBytesReference()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ScriptAsBytes that = (ScriptAsBytes) o; + + return script.equals(that.script); + + } + + @Override + public int hashCode() { + return script.hashCode(); + } + } +} diff --git a/core/src/main/java/org/elasticsearch/script/ScriptParameterParser.java b/core/src/main/java/org/elasticsearch/script/ScriptParameterParser.java index 66af94a07b8..9807f660247 100644 --- a/core/src/main/java/org/elasticsearch/script/ScriptParameterParser.java +++ b/core/src/main/java/org/elasticsearch/script/ScriptParameterParser.java @@ -92,7 +92,7 @@ public class ScriptParameterParser { for (ParseField parameter : indexedParameters) { if (parseFieldMatcher.match(currentFieldName, parameter)) { String coreParameterName = parameter.getPreferredName().replace(INDEXED_SUFFIX, ""); - putParameterValue(coreParameterName, parser.textOrNull(), ScriptType.INDEXED); + putParameterValue(coreParameterName, parser.textOrNull(), ScriptType.STORED); return true; } } @@ -155,7 +155,7 @@ public class ScriptParameterParser { } else { throw new ScriptParseException("Value must be of type String: [" + parameterName + "]"); } - putParameterValue(coreParameterName, stringValue, ScriptType.INDEXED); + putParameterValue(coreParameterName, stringValue, ScriptType.STORED); if (removeMatchedEntries) { itr.remove(); } @@ -196,7 +196,7 @@ public class ScriptParameterParser { String value = params.param(parameter.getPreferredName()); if (value != null) { String coreParameterName = parameter.getPreferredName().replace(INDEXED_SUFFIX, ""); - putParameterValue(coreParameterName, value, ScriptType.INDEXED); + putParameterValue(coreParameterName, value, ScriptType.STORED); } } diff --git a/core/src/main/java/org/elasticsearch/script/ScriptService.java b/core/src/main/java/org/elasticsearch/script/ScriptService.java index fc375901607..a1ea88a2549 100644 --- a/core/src/main/java/org/elasticsearch/script/ScriptService.java +++ b/core/src/main/java/org/elasticsearch/script/ScriptService.java @@ -20,17 +20,17 @@ package org.elasticsearch.script; import org.apache.lucene.util.IOUtils; +import org.elasticsearch.ResourceNotFoundException; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.delete.DeleteRequest; -import org.elasticsearch.action.delete.DeleteResponse; -import org.elasticsearch.action.get.GetRequest; -import org.elasticsearch.action.get.GetResponse; -import org.elasticsearch.action.index.IndexRequest; -import org.elasticsearch.action.index.IndexResponse; -import org.elasticsearch.action.indexedscripts.delete.DeleteIndexedScriptRequest; -import org.elasticsearch.action.indexedscripts.get.GetIndexedScriptRequest; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptRequest; -import org.elasticsearch.client.Client; +import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest; +import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptResponse; +import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest; +import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequest; +import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptResponse; +import org.elasticsearch.cluster.AckedClusterStateUpdateTask; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.metadata.MetaData; +import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.Strings; @@ -45,15 +45,14 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.logging.LoggerMessageFormat; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.ConcurrentCollections; -import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.env.Environment; import org.elasticsearch.index.query.TemplateQueryBuilder; import org.elasticsearch.search.lookup.SearchLookup; @@ -77,9 +76,6 @@ import java.util.concurrent.ConcurrentMap; import static java.util.Collections.unmodifiableMap; -/** - * - */ public class ScriptService extends AbstractComponent implements Closeable { static final String DISABLE_DYNAMIC_SCRIPTING_SETTING = "script.disable_dynamic"; @@ -88,9 +84,10 @@ public class ScriptService extends AbstractComponent implements Closeable { Setting.intSetting("script.cache.max_size", 100, 0, Property.NodeScope); public static final Setting SCRIPT_CACHE_EXPIRE_SETTING = Setting.positiveTimeSetting("script.cache.expire", TimeValue.timeValueMillis(0), Property.NodeScope); - public static final String SCRIPT_INDEX = ".scripts"; public static final Setting SCRIPT_AUTO_RELOAD_ENABLED_SETTING = Setting.boolSetting("script.auto_reload_enabled", true, Property.NodeScope); + public static final Setting SCRIPT_MAX_SIZE_IN_BYTES = + Setting.intSetting("script.max_size_in_bytes", 65535, Property.NodeScope); private final String defaultLang; @@ -107,9 +104,6 @@ public class ScriptService extends AbstractComponent implements Closeable { private final ScriptContextRegistry scriptContextRegistry; private final ParseFieldMatcher parseFieldMatcher; - - private Client client = null; - private final ScriptMetrics scriptMetrics = new ScriptMetrics(); /** @@ -139,7 +133,8 @@ public class ScriptService extends AbstractComponent implements Closeable { @Inject public ScriptService(Settings settings, Environment env, Set scriptEngines, - ResourceWatcherService resourceWatcherService, ScriptEngineRegistry scriptEngineRegistry, ScriptContextRegistry scriptContextRegistry, ScriptSettings scriptSettings) throws IOException { + ResourceWatcherService resourceWatcherService, ScriptEngineRegistry scriptEngineRegistry, + ScriptContextRegistry scriptContextRegistry, ScriptSettings scriptSettings) throws IOException { super(settings); Objects.requireNonNull(scriptEngineRegistry); Objects.requireNonNull(scriptContextRegistry); @@ -147,7 +142,7 @@ public class ScriptService extends AbstractComponent implements Closeable { this.parseFieldMatcher = new ParseFieldMatcher(settings); if (Strings.hasLength(settings.get(DISABLE_DYNAMIC_SCRIPTING_SETTING))) { throw new IllegalArgumentException(DISABLE_DYNAMIC_SCRIPTING_SETTING + " is not a supported setting, replace with fine-grained script settings. \n" + - "Dynamic scripts can be enabled for all languages and all operations by replacing `script.disable_dynamic: false` with `script.inline: true` and `script.indexed: true` in elasticsearch.yml"); + "Dynamic scripts can be enabled for all languages and all operations by replacing `script.disable_dynamic: false` with `script.inline: true` and `script.stored: true` in elasticsearch.yml"); } this.scriptEngines = scriptEngines; @@ -201,12 +196,6 @@ public class ScriptService extends AbstractComponent implements Closeable { } } - //This isn't set in the ctor because doing so creates a guice circular - @Inject(optional=true) - public void setClient(Client client) { - this.client = client; - } - @Override public void close() throws IOException { IOUtils.close(scriptEngines); @@ -233,7 +222,7 @@ public class ScriptService extends AbstractComponent implements Closeable { /** * Checks if a script can be executed and compiles it if needed, or returns the previously compiled and cached script. */ - public CompiledScript compile(Script script, ScriptContext scriptContext, Map params) { + public CompiledScript compile(Script script, ScriptContext scriptContext, Map params, ClusterState state) { if (script == null) { throw new IllegalArgumentException("The parameter script (Script) must not be null."); } @@ -261,14 +250,14 @@ public class ScriptService extends AbstractComponent implements Closeable { " operation [" + scriptContext.getKey() + "] and lang [" + lang + "] are not supported"); } - return compileInternal(script, params); + return compileInternal(script, params, state); } /** * Compiles a script straight-away, or returns the previously compiled and cached script, * without checking if it can be executed based on settings. */ - public CompiledScript compileInternal(Script script, Map params) { + CompiledScript compileInternal(Script script, Map params, ClusterState state) { if (script == null) { throw new IllegalArgumentException("The parameter script (Script) must not be null."); } @@ -300,12 +289,12 @@ public class ScriptService extends AbstractComponent implements Closeable { //script.getScript() will be code if the script type is inline String code = script.getScript(); - if (type == ScriptType.INDEXED) { + if (type == ScriptType.STORED) { //The look up for an indexed script must be done every time in case //the script has been updated in the index since the last look up. final IndexedScript indexedScript = new IndexedScript(lang, name); name = indexedScript.id; - code = getScriptFromIndex(indexedScript.lang, indexedScript.id); + code = getScriptFromClusterState(state, indexedScript.lang, indexedScript.id); } CacheKey cacheKey = new CacheKey(scriptEngineService, type == ScriptType.INLINE ? null : name, code, params); @@ -329,14 +318,6 @@ public class ScriptService extends AbstractComponent implements Closeable { return compiledScript; } - public void queryScriptIndex(GetIndexedScriptRequest request, final ActionListener listener) { - String scriptLang = validateScriptLanguage(request.scriptLang()); - GetRequest getRequest = new GetRequest(SCRIPT_INDEX).type(scriptLang).id(request.id()) - .version(request.version()).versionType(request.versionType()) - .preference("_local"); //Set preference for no forking - client.get(getRequest, listener); - } - private String validateScriptLanguage(String scriptLang) { if (scriptLang == null) { scriptLang = defaultLang; @@ -346,21 +327,22 @@ public class ScriptService extends AbstractComponent implements Closeable { return scriptLang; } - String getScriptFromIndex(String scriptLang, String id) { - if (client == null) { - throw new IllegalArgumentException("Got an indexed script with no Client registered."); - } + String getScriptFromClusterState(ClusterState state, String scriptLang, String id) { scriptLang = validateScriptLanguage(scriptLang); - GetRequest getRequest = new GetRequest(SCRIPT_INDEX, scriptLang, id); - GetResponse responseFields = client.get(getRequest).actionGet(); - if (responseFields.isExists()) { - return getScriptFromResponse(responseFields); + ScriptMetaData scriptMetadata = state.metaData().custom(ScriptMetaData.TYPE); + if (scriptMetadata == null) { + throw new ResourceNotFoundException("Unable to find script [" + scriptLang + "/" + id + "] in cluster state"); } - throw new IllegalArgumentException("Unable to find script [" + SCRIPT_INDEX + "/" - + scriptLang + "/" + id + "]"); + + String script = scriptMetadata.getScript(scriptLang, id); + if (script == null) { + throw new ResourceNotFoundException("Unable to find script [" + scriptLang + "/" + id + "] in cluster state"); + } + return script; } - private void validate(BytesReference scriptBytes, String scriptLang) { + void validate(String id, String scriptLang, BytesReference scriptBytes) { + validateScriptSize(id, scriptBytes.length()); try (XContentParser parser = XContentFactory.xContent(scriptBytes).createParser(scriptBytes)) { parser.nextToken(); Template template = TemplateQueryBuilder.parse(scriptLang, parser, parseFieldMatcher, "params", "script", "template"); @@ -370,7 +352,7 @@ public class ScriptService extends AbstractComponent implements Closeable { ScriptEngineService scriptEngineService = getScriptEngineServiceForLang(scriptLang); //we don't know yet what the script will be used for, but if all of the operations for this lang with //indexed scripts are disabled, it makes no sense to even compile it. - if (isAnyScriptContextEnabled(scriptLang, scriptEngineService, ScriptType.INDEXED)) { + if (isAnyScriptContextEnabled(scriptLang, scriptEngineService, ScriptType.STORED)) { Object compiled = scriptEngineService.compile(template.getScript(), Collections.emptyMap()); if (compiled == null) { throw new IllegalArgumentException("Unable to parse [" + template.getScript() + @@ -393,58 +375,72 @@ public class ScriptService extends AbstractComponent implements Closeable { } } - public void putScriptToIndex(PutIndexedScriptRequest request, ActionListener listener) { + public void storeScript(ClusterService clusterService, PutStoredScriptRequest request, ActionListener listener) { String scriptLang = validateScriptLanguage(request.scriptLang()); //verify that the script compiles - validate(request.source(), scriptLang); + validate(request.id(), scriptLang, request.script()); + clusterService.submitStateUpdateTask("put-script-" + request.id(), new AckedClusterStateUpdateTask(request, listener) { - IndexRequest indexRequest = new IndexRequest().index(SCRIPT_INDEX).type(scriptLang).id(request.id()) - .version(request.version()).versionType(request.versionType()) - .source(request.source()).opType(request.opType()).refresh(true); //Always refresh after indexing a template - client.index(indexRequest, listener); + @Override + protected PutStoredScriptResponse newResponse(boolean acknowledged) { + return new PutStoredScriptResponse(acknowledged); + } + + @Override + public ClusterState execute(ClusterState currentState) throws Exception { + return innerStoreScript(currentState, scriptLang, request); + } + }); } - public void deleteScriptFromIndex(DeleteIndexedScriptRequest request, ActionListener listener) { + static ClusterState innerStoreScript(ClusterState currentState, String validatedScriptLang, PutStoredScriptRequest request) { + ScriptMetaData scriptMetadata = currentState.metaData().custom(ScriptMetaData.TYPE); + ScriptMetaData.Builder scriptMetadataBuilder = new ScriptMetaData.Builder(scriptMetadata); + scriptMetadataBuilder.storeScript(validatedScriptLang, request.id(), request.script()); + MetaData.Builder metaDataBuilder = MetaData.builder(currentState.getMetaData()) + .putCustom(ScriptMetaData.TYPE, scriptMetadataBuilder.build()); + return ClusterState.builder(currentState).metaData(metaDataBuilder).build(); + } + + public void deleteStoredScript(ClusterService clusterService, DeleteStoredScriptRequest request, ActionListener listener) { String scriptLang = validateScriptLanguage(request.scriptLang()); - DeleteRequest deleteRequest = new DeleteRequest().index(SCRIPT_INDEX).type(scriptLang).id(request.id()) - .refresh(true).version(request.version()).versionType(request.versionType()); - client.delete(deleteRequest, listener); + clusterService.submitStateUpdateTask("delete-script-" + request.id(), new AckedClusterStateUpdateTask(request, listener) { + + @Override + protected DeleteStoredScriptResponse newResponse(boolean acknowledged) { + return new DeleteStoredScriptResponse(acknowledged); + } + + @Override + public ClusterState execute(ClusterState currentState) throws Exception { + return innerDeleteScript(currentState, scriptLang, request); + } + }); } - @SuppressWarnings("unchecked") - public static String getScriptFromResponse(GetResponse responseFields) { - Map source = responseFields.getSourceAsMap(); - if (source.containsKey("template")) { - try { - XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON); - Object template = source.get("template"); - if (template instanceof Map ){ - builder.map((Map)template); - return builder.string(); - } else { - return template.toString(); - } - } catch (IOException | ClassCastException e) { - throw new IllegalStateException("Unable to parse " + responseFields.getSourceAsString() + " as json", e); - } - } else if (source.containsKey("script")) { - return source.get("script").toString(); + static ClusterState innerDeleteScript(ClusterState currentState, String validatedLang, DeleteStoredScriptRequest request) { + ScriptMetaData scriptMetadata = currentState.metaData().custom(ScriptMetaData.TYPE); + ScriptMetaData.Builder scriptMetadataBuilder = new ScriptMetaData.Builder(scriptMetadata); + scriptMetadataBuilder.deleteScript(validatedLang, request.id()); + MetaData.Builder metaDataBuilder = MetaData.builder(currentState.getMetaData()) + .putCustom(ScriptMetaData.TYPE, scriptMetadataBuilder.build()); + return ClusterState.builder(currentState).metaData(metaDataBuilder).build(); + } + + public String getStoredScript(ClusterState state, GetStoredScriptRequest request) { + ScriptMetaData scriptMetadata = state.metaData().custom(ScriptMetaData.TYPE); + if (scriptMetadata != null) { + return scriptMetadata.getScript(request.lang(), request.id()); } else { - try { - XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON); - builder.map(responseFields.getSource()); - return builder.string(); - } catch (IOException|ClassCastException e) { - throw new IllegalStateException("Unable to parse " + responseFields.getSourceAsString() + " as json", e); - } + return null; } } /** * Compiles (or retrieves from cache) and executes the provided script */ - public ExecutableScript executable(Script script, ScriptContext scriptContext, Map params) { - return executable(compile(script, scriptContext, params), script.getParams()); + public ExecutableScript executable(Script script, ScriptContext scriptContext, Map params, ClusterState state) { + return executable(compile(script, scriptContext, params, state), script.getParams()); } /** @@ -457,8 +453,8 @@ public class ScriptService extends AbstractComponent implements Closeable { /** * Compiles (or retrieves from cache) and executes the provided search script */ - public SearchScript search(SearchLookup lookup, Script script, ScriptContext scriptContext, Map params) { - CompiledScript compiledScript = compile(script, scriptContext, params); + public SearchScript search(SearchLookup lookup, Script script, ScriptContext scriptContext, Map params, ClusterState state) { + CompiledScript compiledScript = compile(script, scriptContext, params, state); return getScriptEngineServiceForLang(compiledScript.lang()).search(compiledScript, lookup, script.getParams()); } @@ -493,8 +489,17 @@ public class ScriptService extends AbstractComponent implements Closeable { return scriptMetrics.stats(); } - public Client getClient() { - return client; + private void validateScriptSize(String identifier, int scriptSizeInBytes) { + int allowedScriptSizeInBytes = SCRIPT_MAX_SIZE_IN_BYTES.get(settings); + if (scriptSizeInBytes > allowedScriptSizeInBytes) { + String message = LoggerMessageFormat.format( + "Limit of script size in bytes [{}] has been exceeded for script [{}] with size [{}]", + allowedScriptSizeInBytes, + identifier, + scriptSizeInBytes + ); + throw new IllegalArgumentException(message); + } } /** @@ -603,7 +608,7 @@ public class ScriptService extends AbstractComponent implements Closeable { public enum ScriptType { INLINE(0, "inline", "inline", ScriptMode.SANDBOX), - INDEXED(1, "id", "indexed", ScriptMode.SANDBOX), + STORED(1, "id", "stored", ScriptMode.SANDBOX), FILE(2, "file", "file", ScriptMode.ON); private final int val; @@ -619,7 +624,7 @@ public class ScriptService extends AbstractComponent implements Closeable { } } throw new IllegalArgumentException("Unexpected value read for ScriptType got [" + scriptTypeVal + "] expected one of [" - + INLINE.val + "," + FILE.val + "," + INDEXED.val + "]"); + + INLINE.val + "," + FILE.val + "," + STORED.val + "]"); } public static void writeTo(ScriptType scriptType, StreamOutput out) throws IOException{ diff --git a/core/src/main/java/org/elasticsearch/search/SearchService.java b/core/src/main/java/org/elasticsearch/search/SearchService.java index c03a13b5ee7..880e6f0e916 100644 --- a/core/src/main/java/org/elasticsearch/search/SearchService.java +++ b/core/src/main/java/org/elasticsearch/search/SearchService.java @@ -566,7 +566,8 @@ public class SearchService extends AbstractLifecycleComponent imp context.scrollContext().scroll = request.scroll(); } if (request.template() != null) { - ExecutableScript executable = this.scriptService.executable(request.template(), ScriptContext.Standard.SEARCH, Collections.emptyMap()); + ExecutableScript executable = this.scriptService.executable(request.template(), ScriptContext.Standard.SEARCH, + Collections.emptyMap(), context.getQueryShardContext().getClusterState()); BytesReference run = (BytesReference) executable.run(); try (XContentParser parser = XContentFactory.xContent(run).createParser(run)) { QueryParseContext queryParseContext = new QueryParseContext(indicesService.getIndicesQueryRegistry(), parser, @@ -774,7 +775,8 @@ public class SearchService extends AbstractLifecycleComponent imp } if (source.scriptFields() != null) { for (org.elasticsearch.search.builder.SearchSourceBuilder.ScriptField field : source.scriptFields()) { - SearchScript searchScript = context.scriptService().search(context.lookup(), field.script(), ScriptContext.Standard.SEARCH, Collections.emptyMap()); + SearchScript searchScript = context.scriptService().search(context.lookup(), field.script(), ScriptContext.Standard.SEARCH, + Collections.emptyMap(), context.getQueryShardContext().getClusterState()); context.scriptFields().add(new ScriptField(field.fieldName(), searchScript, field.ignoreFailure())); } } diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/InternalAggregation.java b/core/src/main/java/org/elasticsearch/search/aggregations/InternalAggregation.java index 3604ac97217..5ae78417f6f 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/InternalAggregation.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/InternalAggregation.java @@ -18,6 +18,8 @@ */ package org.elasticsearch.search.aggregations; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.stream.StreamInput; @@ -93,11 +95,13 @@ public abstract class InternalAggregation implements Aggregation, ToXContent, St public static class ReduceContext { private final BigArrays bigArrays; - private ScriptService scriptService; + private final ScriptService scriptService; + private final ClusterState clusterState; - public ReduceContext(BigArrays bigArrays, ScriptService scriptService) { + public ReduceContext(BigArrays bigArrays, ScriptService scriptService, ClusterState clusterState) { this.bigArrays = bigArrays; this.scriptService = scriptService; + this.clusterState = clusterState; } public BigArrays bigArrays() { @@ -107,6 +111,10 @@ public abstract class InternalAggregation implements Aggregation, ToXContent, St public ScriptService scriptService() { return scriptService; } + + public ClusterState clusterState() { + return clusterState; + } } diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/heuristics/ScriptHeuristic.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/heuristics/ScriptHeuristic.java index 015fc76cdad..22fce0113e9 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/heuristics/ScriptHeuristic.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/heuristics/ScriptHeuristic.java @@ -22,6 +22,7 @@ package org.elasticsearch.search.aggregations.bucket.significant.heuristics; import org.elasticsearch.ElasticsearchParseException; +import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.io.stream.StreamInput; @@ -78,16 +79,16 @@ public class ScriptHeuristic extends SignificanceHeuristic { @Override public void initialize(InternalAggregation.ReduceContext context) { - initialize(context.scriptService()); + initialize(context.scriptService(), context.clusterState()); } @Override public void initialize(SearchContext context) { - initialize(context.scriptService()); + initialize(context.scriptService(), context.getQueryShardContext().getClusterState()); } - public void initialize(ScriptService scriptService) { - searchScript = scriptService.executable(script, ScriptContext.Standard.AGGS, Collections.emptyMap()); + public void initialize(ScriptService scriptService, ClusterState state) { + searchScript = scriptService.executable(script, ScriptContext.Standard.AGGS, Collections.emptyMap(), state); searchScript.setNextVar("_subset_freq", subsetDfHolder); searchScript.setNextVar("_subset_size", subsetSizeHolder); searchScript.setNextVar("_superset_freq", supersetDfHolder); diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/metrics/scripted/InternalScriptedMetric.java b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/scripted/InternalScriptedMetric.java index 2c09d58afdb..d6814871108 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/metrics/scripted/InternalScriptedMetric.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/scripted/InternalScriptedMetric.java @@ -92,7 +92,7 @@ public class InternalScriptedMetric extends InternalMetricsAggregation implement vars.putAll(firstAggregation.reduceScript.getParams()); } CompiledScript compiledScript = reduceContext.scriptService().compile(firstAggregation.reduceScript, - ScriptContext.Standard.AGGS, Collections.emptyMap()); + ScriptContext.Standard.AGGS, Collections.emptyMap(), reduceContext.clusterState()); ExecutableScript script = reduceContext.scriptService().executable(compiledScript, vars); aggregation = script.run(); } else { diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/metrics/scripted/ScriptedMetricAggregator.java b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/scripted/ScriptedMetricAggregator.java index ab4335a704e..053b0e82d69 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/metrics/scripted/ScriptedMetricAggregator.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/scripted/ScriptedMetricAggregator.java @@ -20,6 +20,7 @@ package org.elasticsearch.search.aggregations.metrics.scripted; import org.apache.lucene.index.LeafReaderContext; +import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.LeafSearchScript; import org.elasticsearch.script.Script; @@ -51,12 +52,13 @@ public class ScriptedMetricAggregator extends MetricsAggregator { super(name, context, parent, pipelineAggregators, metaData); this.params = params; ScriptService scriptService = context.searchContext().scriptService(); + ClusterState state = context.searchContext().getQueryShardContext().getClusterState(); if (initScript != null) { - scriptService.executable(initScript, ScriptContext.Standard.AGGS, Collections.emptyMap()).run(); + scriptService.executable(initScript, ScriptContext.Standard.AGGS, Collections.emptyMap(), state).run(); } - this.mapScript = scriptService.search(context.searchContext().lookup(), mapScript, ScriptContext.Standard.AGGS, Collections.emptyMap()); + this.mapScript = scriptService.search(context.searchContext().lookup(), mapScript, ScriptContext.Standard.AGGS, Collections.emptyMap(), state); if (combineScript != null) { - this.combineScript = scriptService.executable(combineScript, ScriptContext.Standard.AGGS, Collections.emptyMap()); + this.combineScript = scriptService.executable(combineScript, ScriptContext.Standard.AGGS, Collections.emptyMap(), state); } else { this.combineScript = null; } diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregatorFactory.java b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregatorFactory.java index b24adb04fe0..478f03c7eac 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregatorFactory.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregatorFactory.java @@ -106,7 +106,7 @@ public class TopHitsAggregatorFactory extends AggregatorFactory originalAgg = (InternalMultiBucketAggregation) aggregation; List buckets = originalAgg.getBuckets(); - CompiledScript compiledScript = reduceContext.scriptService().compile(script, ScriptContext.Standard.AGGS, Collections.emptyMap()); + CompiledScript compiledScript = reduceContext.scriptService().compile(script, ScriptContext.Standard.AGGS, + Collections.emptyMap(), reduceContext.clusterState()); List newBuckets = new ArrayList<>(); for (Bucket bucket : buckets) { Map vars = new HashMap<>(); diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketselector/BucketSelectorPipelineAggregator.java b/core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketselector/BucketSelectorPipelineAggregator.java index 7759d9ddc96..ed61b881d56 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketselector/BucketSelectorPipelineAggregator.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketselector/BucketSelectorPipelineAggregator.java @@ -85,11 +85,12 @@ public class BucketSelectorPipelineAggregator extends PipelineAggregator { @Override public InternalAggregation reduce(InternalAggregation aggregation, ReduceContext reduceContext) { - InternalMultiBucketAggregation originalAgg = + InternalMultiBucketAggregation originalAgg = (InternalMultiBucketAggregation) aggregation; List buckets = originalAgg.getBuckets(); - CompiledScript compiledScript = reduceContext.scriptService().compile(script, ScriptContext.Standard.AGGS, Collections.emptyMap()); + CompiledScript compiledScript = reduceContext.scriptService().compile(script, ScriptContext.Standard.AGGS, + Collections.emptyMap(), reduceContext.clusterState()); List newBuckets = new ArrayList<>(); for (Bucket bucket : buckets) { Map vars = new HashMap<>(); diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregatorBuilder.java b/core/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregatorBuilder.java index fb07854ecbc..c92faa09613 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregatorBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregatorBuilder.java @@ -377,7 +377,8 @@ public abstract class ValuesSourceAggregatorBuilder results) { @@ -397,7 +399,8 @@ public class SearchPhaseController extends AbstractComponent { for (AtomicArray.Entry entry : queryResults) { aggregationsList.add((InternalAggregations) entry.value.queryResult().aggregations()); } - aggregations = InternalAggregations.reduce(aggregationsList, new ReduceContext(bigArrays, scriptService)); + ReduceContext reduceContext = new ReduceContext(bigArrays, scriptService, clusterService.state()); + aggregations = InternalAggregations.reduce(aggregationsList, reduceContext); } } @@ -419,8 +422,8 @@ public class SearchPhaseController extends AbstractComponent { return (InternalAggregation) p; }).collect(Collectors.toList()); for (SiblingPipelineAggregator pipelineAggregator : pipelineAggregators) { - InternalAggregation newAgg = pipelineAggregator.doReduce(new InternalAggregations(newAggs), new ReduceContext( - bigArrays, scriptService)); + ReduceContext reduceContext = new ReduceContext(bigArrays, scriptService, clusterService.state()); + InternalAggregation newAgg = pipelineAggregator.doReduce(new InternalAggregations(newAggs), reduceContext); newAggs.add(newAgg); } aggregations = new InternalAggregations(newAggs); diff --git a/core/src/main/java/org/elasticsearch/search/fetch/script/ScriptFieldsParseElement.java b/core/src/main/java/org/elasticsearch/search/fetch/script/ScriptFieldsParseElement.java index de1703b5c98..408bf166e15 100644 --- a/core/src/main/java/org/elasticsearch/search/fetch/script/ScriptFieldsParseElement.java +++ b/core/src/main/java/org/elasticsearch/search/fetch/script/ScriptFieldsParseElement.java @@ -98,7 +98,8 @@ public class ScriptFieldsParseElement implements SearchParseElement { throw new SearchParseException(context, "must specify a script in script fields", parser.getTokenLocation()); } - SearchScript searchScript = context.scriptService().search(context.lookup(), script, ScriptContext.Standard.SEARCH, Collections.emptyMap()); + SearchScript searchScript = context.scriptService().search(context.lookup(), script, ScriptContext.Standard.SEARCH, + Collections.emptyMap(), context.getQueryShardContext().getClusterState()); context.scriptFields().add(new ScriptFieldsContext.ScriptField(fieldName, searchScript, ignoreException)); } } diff --git a/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java b/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java index 9f268c44213..8a713e4992b 100644 --- a/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java @@ -304,7 +304,7 @@ public class ScriptSortBuilder extends SortBuilder { @Override public SortField build(QueryShardContext context) throws IOException { final SearchScript searchScript = context.getScriptService().search( - context.lookup(), script, ScriptContext.Standard.SEARCH, Collections.emptyMap()); + context.lookup(), script, ScriptContext.Standard.SEARCH, Collections.emptyMap(), context.getClusterState()); MultiValueMode valueMode = null; if (sortMode != null) { diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionBuilder.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionBuilder.java index d3ddbeb2f1a..4ff74fb08df 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionBuilder.java @@ -631,7 +631,7 @@ public class PhraseSuggestionBuilder extends SuggestionBuilder(GetAction.NAME, client.threadPool())); client.prepareSearch().execute().addListener(new AssertingActionListener<>(SearchAction.NAME, client.threadPool())); client.prepareDelete("idx", "type", "id").execute().addListener(new AssertingActionListener<>(DeleteAction.NAME, client.threadPool())); - client.prepareDeleteIndexedScript("lang", "id").execute().addListener(new AssertingActionListener<>(DeleteIndexedScriptAction.NAME, client.threadPool())); + client.admin().cluster().prepareDeleteStoredScript("lang", "id").execute().addListener(new AssertingActionListener<>(DeleteStoredScriptAction.NAME, client.threadPool())); client.prepareIndex("idx", "type", "id").setSource("source").execute().addListener(new AssertingActionListener<>(IndexAction.NAME, client.threadPool())); // choosing arbitrary cluster admin actions to test diff --git a/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java b/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java index 3571d8c8b65..7beeaaee0a6 100644 --- a/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java +++ b/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java @@ -35,6 +35,8 @@ import org.elasticsearch.Version; import org.elasticsearch.cache.recycler.PageCacheRecycler; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.metadata.IndexMetaData; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.cluster.service.ClusterServiceUtils; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; @@ -122,7 +124,8 @@ public class IndexModuleTests extends ESTestCase { ScriptSettings scriptSettings = new ScriptSettings(scriptEngineRegistry, scriptContextRegistry); ScriptService scriptService = new ScriptService(settings, environment, scriptEngines, new ResourceWatcherService(settings, threadPool), scriptEngineRegistry, scriptContextRegistry, scriptSettings); IndicesQueriesRegistry indicesQueriesRegistry = new IndicesQueriesRegistry(); - return new NodeServicesProvider(threadPool, bigArrays, client, scriptService, indicesQueriesRegistry, circuitBreakerService); + ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool); + return new NodeServicesProvider(threadPool, bigArrays, client, scriptService, indicesQueriesRegistry, circuitBreakerService, clusterService); } @Override @@ -143,6 +146,7 @@ public class IndexModuleTests extends ESTestCase { super.tearDown(); nodeEnvironment.close(); indicesQueryCache.close(); + nodeServicesProvider.getClusterService().close(); ThreadPool.terminate(nodeServicesProvider.getThreadPool(), 10, TimeUnit.SECONDS); } diff --git a/core/src/test/java/org/elasticsearch/index/percolator/PercolatorQueryCacheTests.java b/core/src/test/java/org/elasticsearch/index/percolator/PercolatorQueryCacheTests.java index bf7570f1007..30986e45e4b 100644 --- a/core/src/test/java/org/elasticsearch/index/percolator/PercolatorQueryCacheTests.java +++ b/core/src/test/java/org/elasticsearch/index/percolator/PercolatorQueryCacheTests.java @@ -43,6 +43,7 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.util.BytesRef; import org.elasticsearch.Version; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; +import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.bytes.BytesReference; @@ -120,8 +121,9 @@ public class PercolatorQueryCacheTests extends ESTestCase { mapperService.merge("type", new CompressedXContent(PutMappingRequest.buildFromSimplifiedDef("type", fields).string()), MapperService.MergeReason.MAPPING_UPDATE, false); cache = new PercolatorQueryCache(idxSettings, () -> queryShardContext); + ClusterState state = ClusterState.builder(new ClusterName("_name")).build(); queryShardContext = new QueryShardContext(idxSettings, null, null, mapperService, similarityService, null, - indicesQueriesRegistry, cache, null); + indicesQueriesRegistry, null, cache, null, state); } public void testLoadQueries() throws Exception { diff --git a/core/src/test/java/org/elasticsearch/index/query/AbstractQueryTestCase.java b/core/src/test/java/org/elasticsearch/index/query/AbstractQueryTestCase.java index 3509a362a3d..a3004ba896c 100644 --- a/core/src/test/java/org/elasticsearch/index/query/AbstractQueryTestCase.java +++ b/core/src/test/java/org/elasticsearch/index/query/AbstractQueryTestCase.java @@ -38,6 +38,7 @@ import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.action.termvectors.MultiTermVectorsRequest; import org.elasticsearch.action.termvectors.MultiTermVectorsResponse; import org.elasticsearch.client.Client; +import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.metadata.MetaData; @@ -738,8 +739,10 @@ public abstract class AbstractQueryTestCase> * @return a new {@link QueryShardContext} based on the base test index and queryParserService */ protected static QueryShardContext createShardContext() { + ClusterState state = ClusterState.builder(new ClusterName("_name")).build(); + Client client = injector.getInstance(Client.class); return new QueryShardContext(idxSettings, bitsetFilterCache, indexFieldDataService, mapperService, similarityService, - scriptService, indicesQueriesRegistry, percolatorQueryCache, null); + scriptService, indicesQueriesRegistry, client, percolatorQueryCache, null, state); } /** diff --git a/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java b/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java index 4b634a2b3f0..f82561a4179 100644 --- a/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java @@ -363,7 +363,7 @@ public class QueryDSLDocumentationTests extends ESTestCase { public void testTemplate() { templateQuery( "gender_template", - ScriptType.INDEXED, + ScriptType.STORED, new HashMap<>()); } diff --git a/core/src/test/java/org/elasticsearch/index/query/QueryShardContextTests.java b/core/src/test/java/org/elasticsearch/index/query/QueryShardContextTests.java index 68332d755b6..b6d69374661 100644 --- a/core/src/test/java/org/elasticsearch/index/query/QueryShardContextTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/QueryShardContextTests.java @@ -47,7 +47,7 @@ public class QueryShardContextTests extends ESTestCase { MapperService mapperService = mock(MapperService.class); when(mapperService.getIndexSettings()).thenReturn(indexSettings); QueryShardContext context = new QueryShardContext( - indexSettings, null, null, mapperService, null, null, null, null, null + indexSettings, null, null, mapperService, null, null, null, null, null, null, null ); context.setAllowUnmappedFields(false); diff --git a/core/src/test/java/org/elasticsearch/index/query/RangeQueryRewriteTests.java b/core/src/test/java/org/elasticsearch/index/query/RangeQueryRewriteTests.java index 71d70e28618..d8e7ddf7640 100644 --- a/core/src/test/java/org/elasticsearch/index/query/RangeQueryRewriteTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/RangeQueryRewriteTests.java @@ -37,7 +37,7 @@ public class RangeQueryRewriteTests extends ESSingleNodeTestCase { IndexService indexService = createIndex("test"); IndexReader reader = new MultiReader(); QueryRewriteContext context = new QueryRewriteContext(indexService.getIndexSettings(), - indexService.mapperService(), null, null, reader); + indexService.mapperService(), null, null, null, reader, null); RangeQueryBuilder range = new RangeQueryBuilder("foo"); assertEquals(Relation.DISJOINT, range.getRelation(context)); } @@ -54,7 +54,7 @@ public class RangeQueryRewriteTests extends ESSingleNodeTestCase { indexService.mapperService().merge("type", new CompressedXContent(mapping), MergeReason.MAPPING_UPDATE, false); QueryRewriteContext context = new QueryRewriteContext(indexService.getIndexSettings(), - indexService.mapperService(), null, null, null); + indexService.mapperService(), null, null, null, null, null); RangeQueryBuilder range = new RangeQueryBuilder("foo"); // can't make assumptions on a missing reader, so it must return INTERSECT assertEquals(Relation.INTERSECTS, range.getRelation(context)); @@ -73,7 +73,7 @@ public class RangeQueryRewriteTests extends ESSingleNodeTestCase { new CompressedXContent(mapping), MergeReason.MAPPING_UPDATE, false); IndexReader reader = new MultiReader(); QueryRewriteContext context = new QueryRewriteContext(indexService.getIndexSettings(), - indexService.mapperService(), null, null, reader); + indexService.mapperService(), null, null, null, reader, null); RangeQueryBuilder range = new RangeQueryBuilder("foo"); // no values -> DISJOINT assertEquals(Relation.DISJOINT, range.getRelation(context)); diff --git a/core/src/test/java/org/elasticsearch/script/FileScriptTests.java b/core/src/test/java/org/elasticsearch/script/FileScriptTests.java index 64f6cc85b34..e591a0f7128 100644 --- a/core/src/test/java/org/elasticsearch/script/FileScriptTests.java +++ b/core/src/test/java/org/elasticsearch/script/FileScriptTests.java @@ -55,7 +55,7 @@ public class FileScriptTests extends ESTestCase { .put("script.engine." + MockScriptEngine.NAME + ".file.aggs", "false").build(); ScriptService scriptService = makeScriptService(settings); Script script = new Script("script1", ScriptService.ScriptType.FILE, MockScriptEngine.NAME, null); - assertNotNull(scriptService.compile(script, ScriptContext.Standard.SEARCH, Collections.emptyMap())); + assertNotNull(scriptService.compile(script, ScriptContext.Standard.SEARCH, Collections.emptyMap(), null)); } public void testAllOpsDisabled() throws Exception { @@ -69,7 +69,7 @@ public class FileScriptTests extends ESTestCase { Script script = new Script("script1", ScriptService.ScriptType.FILE, MockScriptEngine.NAME, null); for (ScriptContext context : ScriptContext.Standard.values()) { try { - scriptService.compile(script, context, Collections.emptyMap()); + scriptService.compile(script, context, Collections.emptyMap(), null); fail(context.getKey() + " script should have been rejected"); } catch(Exception e) { assertTrue(e.getMessage(), e.getMessage().contains("scripts of type [file], operation [" + context.getKey() + "] and lang [" + MockScriptEngine.NAME + "] are disabled")); diff --git a/core/src/test/java/org/elasticsearch/script/NativeScriptTests.java b/core/src/test/java/org/elasticsearch/script/NativeScriptTests.java index eebd926796e..b57fc260b73 100644 --- a/core/src/test/java/org/elasticsearch/script/NativeScriptTests.java +++ b/core/src/test/java/org/elasticsearch/script/NativeScriptTests.java @@ -19,6 +19,8 @@ package org.elasticsearch.script; +import org.elasticsearch.cluster.ClusterName; +import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.inject.Injector; import org.elasticsearch.common.inject.ModulesBuilder; @@ -61,8 +63,9 @@ public class NativeScriptTests extends ESTestCase { ScriptService scriptService = injector.getInstance(ScriptService.class); + ClusterState state = ClusterState.builder(new ClusterName("_name")).build(); ExecutableScript executable = scriptService.executable(new Script("my", ScriptType.INLINE, NativeScriptEngineService.NAME, null), - ScriptContext.Standard.SEARCH, Collections.emptyMap()); + ScriptContext.Standard.SEARCH, Collections.emptyMap(), state); assertThat(executable.run().toString(), equalTo("test")); terminate(injector.getInstance(ThreadPool.class)); } @@ -89,7 +92,7 @@ public class NativeScriptTests extends ESTestCase { for (ScriptContext scriptContext : scriptContextRegistry.scriptContexts()) { assertThat(scriptService.compile(new Script("my", ScriptType.INLINE, NativeScriptEngineService.NAME, null), scriptContext, - Collections.emptyMap()), notNullValue()); + Collections.emptyMap(), null), notNullValue()); } } diff --git a/core/src/test/java/org/elasticsearch/script/ScriptContextTests.java b/core/src/test/java/org/elasticsearch/script/ScriptContextTests.java index b6e8ee6833d..30b61ada18d 100644 --- a/core/src/test/java/org/elasticsearch/script/ScriptContextTests.java +++ b/core/src/test/java/org/elasticsearch/script/ScriptContextTests.java @@ -60,7 +60,7 @@ public class ScriptContextTests extends ESTestCase { for (ScriptService.ScriptType scriptType : ScriptService.ScriptType.values()) { try { Script script = new Script("1", scriptType, MockScriptEngine.NAME, null); - scriptService.compile(script, new ScriptContext.Plugin(PLUGIN_NAME, "custom_globally_disabled_op"), Collections.emptyMap()); + scriptService.compile(script, new ScriptContext.Plugin(PLUGIN_NAME, "custom_globally_disabled_op"), Collections.emptyMap(), null); fail("script compilation should have been rejected"); } catch (ScriptException e) { assertThat(e.getMessage(), containsString("scripts of type [" + scriptType + "], operation [" + PLUGIN_NAME + "_custom_globally_disabled_op] and lang [" + MockScriptEngine.NAME + "] are disabled")); @@ -72,16 +72,16 @@ public class ScriptContextTests extends ESTestCase { ScriptService scriptService = makeScriptService(); Script script = new Script("1", ScriptService.ScriptType.INLINE, MockScriptEngine.NAME, null); try { - scriptService.compile(script, new ScriptContext.Plugin(PLUGIN_NAME, "custom_exp_disabled_op"), Collections.emptyMap()); + scriptService.compile(script, new ScriptContext.Plugin(PLUGIN_NAME, "custom_exp_disabled_op"), Collections.emptyMap(), null); fail("script compilation should have been rejected"); } catch (ScriptException e) { assertTrue(e.getMessage(), e.getMessage().contains("scripts of type [inline], operation [" + PLUGIN_NAME + "_custom_exp_disabled_op] and lang [" + MockScriptEngine.NAME + "] are disabled")); } // still works for other script contexts - assertNotNull(scriptService.compile(script, ScriptContext.Standard.AGGS, Collections.emptyMap())); - assertNotNull(scriptService.compile(script, ScriptContext.Standard.SEARCH, Collections.emptyMap())); - assertNotNull(scriptService.compile(script, new ScriptContext.Plugin(PLUGIN_NAME, "custom_op"), Collections.emptyMap())); + assertNotNull(scriptService.compile(script, ScriptContext.Standard.AGGS, Collections.emptyMap(), null)); + assertNotNull(scriptService.compile(script, ScriptContext.Standard.SEARCH, Collections.emptyMap(), null)); + assertNotNull(scriptService.compile(script, new ScriptContext.Plugin(PLUGIN_NAME, "custom_op"), Collections.emptyMap(), null)); } public void testUnknownPluginScriptContext() throws Exception { @@ -89,7 +89,7 @@ public class ScriptContextTests extends ESTestCase { for (ScriptService.ScriptType scriptType : ScriptService.ScriptType.values()) { try { Script script = new Script("1", scriptType, MockScriptEngine.NAME, null); - scriptService.compile(script, new ScriptContext.Plugin(PLUGIN_NAME, "unknown"), Collections.emptyMap()); + scriptService.compile(script, new ScriptContext.Plugin(PLUGIN_NAME, "unknown"), Collections.emptyMap(), null); fail("script compilation should have been rejected"); } catch (IllegalArgumentException e) { assertTrue(e.getMessage(), e.getMessage().contains("script context [" + PLUGIN_NAME + "_unknown] not supported")); @@ -108,7 +108,7 @@ public class ScriptContextTests extends ESTestCase { for (ScriptService.ScriptType scriptType : ScriptService.ScriptType.values()) { try { Script script = new Script("1", scriptType, MockScriptEngine.NAME, null); - scriptService.compile(script, context, Collections.emptyMap()); + scriptService.compile(script, context, Collections.emptyMap(), null); fail("script compilation should have been rejected"); } catch (IllegalArgumentException e) { assertTrue(e.getMessage(), e.getMessage().contains("script context [test] not supported")); diff --git a/core/src/test/java/org/elasticsearch/script/ScriptMetaDataTests.java b/core/src/test/java/org/elasticsearch/script/ScriptMetaDataTests.java new file mode 100644 index 00000000000..86c3fe561d6 --- /dev/null +++ b/core/src/test/java/org/elasticsearch/script/ScriptMetaDataTests.java @@ -0,0 +1,158 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.elasticsearch.script; + +import org.elasticsearch.cluster.DiffableUtils; +import org.elasticsearch.common.bytes.BytesArray; +import org.elasticsearch.common.io.stream.InputStreamStreamInput; +import org.elasticsearch.common.io.stream.OutputStreamStreamOutput; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.common.xcontent.XContentHelper; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.test.ESTestCase; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + + +public class ScriptMetaDataTests extends ESTestCase { + + 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("lang", "template", sourceBuilder.bytes()); + + sourceBuilder = XContentFactory.jsonBuilder(); + sourceBuilder.startObject().field("template", "value").endObject(); + builder.storeScript("lang", "template_field", sourceBuilder.bytes()); + + sourceBuilder = XContentFactory.jsonBuilder(); + sourceBuilder.startObject().startObject("script").field("field", "value").endObject().endObject(); + builder.storeScript("lang", "script", sourceBuilder.bytes()); + + sourceBuilder = XContentFactory.jsonBuilder(); + sourceBuilder.startObject().field("script", "value").endObject(); + builder.storeScript("lang", "script_field", sourceBuilder.bytes()); + + sourceBuilder = XContentFactory.jsonBuilder(); + sourceBuilder.startObject().field("field", "value").endObject(); + builder.storeScript("lang", "any", sourceBuilder.bytes()); + + ScriptMetaData scriptMetaData = builder.build(); + assertEquals("{\"field\":\"value\"}", scriptMetaData.getScript("lang", "template")); + assertEquals("value", scriptMetaData.getScript("lang", "template_field")); + assertEquals("{\"field\":\"value\"}", scriptMetaData.getScript("lang", "script")); + assertEquals("value", scriptMetaData.getScript("lang", "script_field")); + assertEquals("{\"field\":\"value\"}", scriptMetaData.getScript("lang", "any")); + } + + public void testToAndFromXContent() throws IOException { + XContentType contentType = randomFrom(XContentType.values()); + XContentBuilder xContentBuilder = XContentBuilder.builder(contentType.xContent()); + ScriptMetaData expected = randomScriptMetaData(contentType); + + xContentBuilder.startObject(); + expected.toXContent(xContentBuilder, new ToXContent.MapParams(Collections.emptyMap())); + xContentBuilder.endObject(); + xContentBuilder = shuffleXContent(xContentBuilder, Collections.emptySet()); + + XContentParser parser = XContentHelper.createParser(xContentBuilder.bytes()); + parser.nextToken(); + ScriptMetaData result = ScriptMetaData.PROTO.fromXContent(parser); + assertEquals(expected, result); + assertEquals(expected.hashCode(), result.hashCode()); + } + + public void testReadFromWriteTo() throws IOException { + ScriptMetaData expected = randomScriptMetaData(randomFrom(XContentType.values())); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + expected.writeTo(new OutputStreamStreamOutput(out)); + + ScriptMetaData result = ScriptMetaData.PROTO.readFrom(new InputStreamStreamInput(new ByteArrayInputStream(out.toByteArray()))); + assertEquals(expected, result); + assertEquals(expected.hashCode(), result.hashCode()); + } + + public void testDiff() throws Exception { + ScriptMetaData.Builder builder = new ScriptMetaData.Builder(null); + builder.storeScript("lang", "1", new BytesArray("abc")); + builder.storeScript("lang", "2", new BytesArray("def")); + builder.storeScript("lang", "3", new BytesArray("ghi")); + ScriptMetaData scriptMetaData1 = builder.build(); + + builder = new ScriptMetaData.Builder(scriptMetaData1); + builder.storeScript("lang", "2", new BytesArray("changed")); + builder.deleteScript("lang", "3"); + builder.storeScript("lang", "4", new BytesArray("jkl")); + ScriptMetaData scriptMetaData2 = builder.build(); + + ScriptMetaData.ScriptMetadataDiff diff = (ScriptMetaData.ScriptMetadataDiff) scriptMetaData2.diff(scriptMetaData1); + assertEquals(1, ((DiffableUtils.MapDiff) diff.pipelines).getDeletes().size()); + assertEquals("lang#3", ((DiffableUtils.MapDiff) diff.pipelines).getDeletes().get(0)); + assertEquals(1, ((DiffableUtils.MapDiff) diff.pipelines).getDiffs().size()); + assertNotNull(((DiffableUtils.MapDiff) diff.pipelines).getDiffs().get("lang#2")); + assertEquals(1, ((DiffableUtils.MapDiff) diff.pipelines).getUpserts().size()); + assertNotNull(((DiffableUtils.MapDiff) diff.pipelines).getUpserts().get("lang#4")); + + ScriptMetaData result = (ScriptMetaData) diff.apply(scriptMetaData1); + assertEquals(new BytesArray("abc"), result.getScriptAsBytes("lang", "1")); + assertEquals(new BytesArray("changed"), result.getScriptAsBytes("lang", "2")); + assertEquals(new BytesArray("jkl"), result.getScriptAsBytes("lang", "4")); + } + + public void testBuilder() { + ScriptMetaData.Builder builder = new ScriptMetaData.Builder(null); + builder.storeScript("_lang", "_id", new BytesArray("{\"script\":\"1 + 1\"}")); + + IllegalArgumentException e = + expectThrows(IllegalArgumentException.class, () -> builder.storeScript("_lang#", "_id", new BytesArray("{}"))); + assertEquals("stored script language can't contain: '#'", e.getMessage()); + e = expectThrows(IllegalArgumentException.class, () -> builder.storeScript("_lang", "_id#", new BytesArray("{}"))); + assertEquals("stored script id can't contain: '#'", e.getMessage()); + e = expectThrows(IllegalArgumentException.class, () -> builder.deleteScript("_lang#", "_id")); + assertEquals("stored script language can't contain: '#'", e.getMessage()); + e = expectThrows(IllegalArgumentException.class, () -> builder.deleteScript("_lang", "_id#")); + assertEquals("stored script id can't contain: '#'", e.getMessage()); + + ScriptMetaData result = builder.build(); + assertEquals("1 + 1", result.getScript("_lang", "_id")); + } + + 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 = randomAsciiOfLength(4); + XContentBuilder sourceBuilder = XContentBuilder.builder(sourceContentType.xContent()); + sourceBuilder.startObject().field(randomAsciiOfLength(4), randomAsciiOfLength(4)).endObject(); + builder.storeScript(lang, randomAsciiOfLength(i + 1), sourceBuilder.bytes()); + } + return builder.build(); + } + +} diff --git a/core/src/test/java/org/elasticsearch/script/ScriptModesTests.java b/core/src/test/java/org/elasticsearch/script/ScriptModesTests.java index 305cfc183e6..9470bb98b6f 100644 --- a/core/src/test/java/org/elasticsearch/script/ScriptModesTests.java +++ b/core/src/test/java/org/elasticsearch/script/ScriptModesTests.java @@ -109,7 +109,7 @@ public class ScriptModesTests extends ESTestCase { public void testDefaultSettings() { this.scriptModes = new ScriptModes(scriptSettings, Settings.EMPTY); assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE); - assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED, ScriptType.INLINE); + assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.STORED, ScriptType.INLINE); } public void testMissingSetting() { @@ -147,8 +147,8 @@ public class ScriptModesTests extends ESTestCase { if (randomScriptTypesSet.contains(ScriptType.FILE) == false) { assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE); } - if (randomScriptTypesSet.contains(ScriptType.INDEXED) == false) { - assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED); + if (randomScriptTypesSet.contains(ScriptType.STORED) == false) { + assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.STORED); } if (randomScriptTypesSet.contains(ScriptType.INLINE) == false) { assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INLINE); @@ -179,18 +179,18 @@ public class ScriptModesTests extends ESTestCase { ScriptContext[] complementOf = complementOf(randomScriptContexts); assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, complementOf); - assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INDEXED, ScriptType.INLINE}, complementOf); + assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.STORED, ScriptType.INLINE}, complementOf); } public void testConflictingScriptTypeAndOpGenericSettings() { ScriptContext scriptContext = randomFrom(scriptContexts); Settings.Builder builder = Settings.builder().put("script" + "." + scriptContext.getKey(), randomFrom(DISABLE_VALUES)) - .put("script.indexed", randomFrom(ENABLE_VALUES)).put("script.inline", "sandbox"); + .put("script.stored", randomFrom(ENABLE_VALUES)).put("script.inline", "sandbox"); //operations generic settings have precedence over script type generic settings this.scriptModes = new ScriptModes(scriptSettings, builder.build()); assertScriptModesAllTypes(ScriptMode.OFF, ALL_LANGS, scriptContext); ScriptContext[] complementOf = complementOf(scriptContext); - assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE, ScriptType.INDEXED}, complementOf); + assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE, ScriptType.STORED}, complementOf); assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INLINE}, complementOf); } diff --git a/core/src/test/java/org/elasticsearch/script/ScriptParameterParserTests.java b/core/src/test/java/org/elasticsearch/script/ScriptParameterParserTests.java index 8cadbb3e95b..c177063998f 100644 --- a/core/src/test/java/org/elasticsearch/script/ScriptParameterParserTests.java +++ b/core/src/test/java/org/elasticsearch/script/ScriptParameterParserTests.java @@ -96,7 +96,7 @@ public class ScriptParameterParserTests extends ESTestCase { } ScriptParameterParser paramParser = new ScriptParameterParser(); assertThat(paramParser.token(parser.currentName(), parser.currentToken(), parser, ParseFieldMatcher.STRICT), equalTo(true)); - assertDefaultParameterValue(paramParser, "scriptValue", ScriptType.INDEXED); + assertDefaultParameterValue(paramParser, "scriptValue", ScriptType.STORED); assertThat(paramParser.lang(), nullValue()); parser = XContentHelper.createParser(new BytesArray("{ \"scriptId\" : \"scriptValue\" }")); @@ -106,7 +106,7 @@ public class ScriptParameterParserTests extends ESTestCase { } paramParser = new ScriptParameterParser(); assertThat(paramParser.token(parser.currentName(), parser.currentToken(), parser, ParseFieldMatcher.STRICT), equalTo(true)); - assertDefaultParameterValue(paramParser, "scriptValue", ScriptType.INDEXED); + assertDefaultParameterValue(paramParser, "scriptValue", ScriptType.STORED); assertThat(paramParser.lang(), nullValue()); } @@ -161,7 +161,7 @@ public class ScriptParameterParserTests extends ESTestCase { ScriptParameterParser paramParser = new ScriptParameterParser(parameters); assertThat(paramParser.getScriptParameterValue("foo"), nullValue()); assertThat(paramParser.token(parser.currentName(), parser.currentToken(), parser, ParseFieldMatcher.STRICT), equalTo(true)); - assertParameterValue(paramParser, "foo", "scriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "foo", "scriptValue", ScriptType.STORED); assertThat(paramParser.lang(), nullValue()); } @@ -271,7 +271,7 @@ public class ScriptParameterParserTests extends ESTestCase { ScriptParameterParser paramParser = new ScriptParameterParser(parameters); assertThat(paramParser.getScriptParameterValue("foo"), nullValue()); assertThat(paramParser.token(parser.currentName(), parser.currentToken(), parser, ParseFieldMatcher.STRICT), equalTo(true)); - assertParameterValue(paramParser, "foo", "scriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "foo", "scriptValue", ScriptType.STORED); assertThat(paramParser.lang(), nullValue()); token = parser.nextToken(); while (token != Token.VALUE_STRING) { @@ -295,7 +295,7 @@ public class ScriptParameterParserTests extends ESTestCase { ScriptParameterParser paramParser = new ScriptParameterParser(parameters); assertThat(paramParser.getScriptParameterValue("foo"), nullValue()); assertThat(paramParser.token(parser.currentName(), parser.currentToken(), parser, ParseFieldMatcher.STRICT), equalTo(true)); - assertParameterValue(paramParser, "foo", "scriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "foo", "scriptValue", ScriptType.STORED); assertThat(paramParser.lang(), nullValue()); token = parser.nextToken(); while (token != Token.VALUE_STRING) { @@ -351,7 +351,7 @@ public class ScriptParameterParserTests extends ESTestCase { assertThat(paramParser.token(parser.currentName(), parser.currentToken(), parser, ParseFieldMatcher.STRICT), equalTo(true)); assertParameterValue(paramParser, "foo", "fooScriptValue", ScriptType.INLINE); assertParameterValue(paramParser, "bar", "barScriptValue", ScriptType.FILE); - assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.STORED); assertThat(paramParser.getScriptParameterValue("bar_file"), nullValue()); assertThat(paramParser.getScriptParameterValue("baz_id"), nullValue()); assertThat(paramParser.lang(), nullValue()); @@ -410,7 +410,7 @@ public class ScriptParameterParserTests extends ESTestCase { assertThat(paramParser.token(parser.currentName(), parser.currentToken(), parser, ParseFieldMatcher.STRICT), equalTo(true)); assertParameterValue(paramParser, "foo", "fooScriptValue", ScriptType.INLINE); assertParameterValue(paramParser, "bar", "barScriptValue", ScriptType.FILE); - assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.STORED); assertThat(paramParser.getScriptParameterValue("bar_file"), nullValue()); assertThat(paramParser.getScriptParameterValue("baz_id"), nullValue()); assertThat(paramParser.lang(), equalTo("myLang")); @@ -491,7 +491,7 @@ public class ScriptParameterParserTests extends ESTestCase { assertThat(paramParser.token(parser.currentName(), parser.currentToken(), parser, ParseFieldMatcher.STRICT), equalTo(true)); assertParameterValue(paramParser, "foo", "fooScriptValue", ScriptType.INLINE); assertThat(paramParser.getScriptParameterValue("bar"), nullValue()); - assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.STORED); assertThat(paramParser.getScriptParameterValue("bar_file"), nullValue()); assertThat(paramParser.getScriptParameterValue("baz_id"), nullValue()); assertThat(paramParser.getScriptParameterValue("other"), nullValue()); @@ -577,7 +577,7 @@ public class ScriptParameterParserTests extends ESTestCase { config.put("script_id", "scriptValue"); ScriptParameterParser paramParser = new ScriptParameterParser(); paramParser.parseConfig(config, true, ParseFieldMatcher.STRICT); - assertDefaultParameterValue(paramParser, "scriptValue", ScriptType.INDEXED); + assertDefaultParameterValue(paramParser, "scriptValue", ScriptType.STORED); assertThat(paramParser.lang(), nullValue()); assertThat(config.isEmpty(), equalTo(true)); @@ -585,7 +585,7 @@ public class ScriptParameterParserTests extends ESTestCase { config.put("scriptId", "scriptValue"); paramParser = new ScriptParameterParser(); paramParser.parseConfig(config, true, ParseFieldMatcher.STRICT); - assertDefaultParameterValue(paramParser, "scriptValue", ScriptType.INDEXED); + assertDefaultParameterValue(paramParser, "scriptValue", ScriptType.STORED); assertThat(paramParser.lang(), nullValue()); assertThat(config.isEmpty(), equalTo(true)); } @@ -595,7 +595,7 @@ public class ScriptParameterParserTests extends ESTestCase { config.put("script_id", "scriptValue"); ScriptParameterParser paramParser = new ScriptParameterParser(); paramParser.parseConfig(config, false, ParseFieldMatcher.STRICT); - assertDefaultParameterValue(paramParser, "scriptValue", ScriptType.INDEXED); + assertDefaultParameterValue(paramParser, "scriptValue", ScriptType.STORED); assertThat(paramParser.lang(), nullValue()); assertThat(config.size(), equalTo(1)); assertThat((String) config.get("script_id"), equalTo("scriptValue")); @@ -604,7 +604,7 @@ public class ScriptParameterParserTests extends ESTestCase { config.put("scriptId", "scriptValue"); paramParser = new ScriptParameterParser(); paramParser.parseConfig(config, false, ParseFieldMatcher.STRICT); - assertDefaultParameterValue(paramParser, "scriptValue", ScriptType.INDEXED); + assertDefaultParameterValue(paramParser, "scriptValue", ScriptType.STORED); assertThat(paramParser.lang(), nullValue()); assertThat(config.size(), equalTo(1)); assertThat((String) config.get("scriptId"), equalTo("scriptValue")); @@ -653,7 +653,7 @@ public class ScriptParameterParserTests extends ESTestCase { ScriptParameterParser paramParser = new ScriptParameterParser(parameters); assertThat(paramParser.getScriptParameterValue("foo"), nullValue()); paramParser.parseConfig(config, true, ParseFieldMatcher.STRICT); - assertParameterValue(paramParser, "foo", "scriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "foo", "scriptValue", ScriptType.STORED); assertThat(paramParser.lang(), nullValue()); assertThat(config.isEmpty(), equalTo(true)); } @@ -767,7 +767,7 @@ public class ScriptParameterParserTests extends ESTestCase { paramParser.parseConfig(config, true, ParseFieldMatcher.STRICT); assertParameterValue(paramParser, "foo", "fooScriptValue", ScriptType.INLINE); assertParameterValue(paramParser, "bar", "barScriptValue", ScriptType.FILE); - assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.STORED); assertThat(paramParser.getScriptParameterValue("bar_file"), nullValue()); assertThat(paramParser.getScriptParameterValue("baz_id"), nullValue()); assertThat(paramParser.lang(), nullValue()); @@ -794,7 +794,7 @@ public class ScriptParameterParserTests extends ESTestCase { paramParser.parseConfig(config, true, ParseFieldMatcher.STRICT); assertParameterValue(paramParser, "foo", "fooScriptValue", ScriptType.INLINE); assertParameterValue(paramParser, "bar", "barScriptValue", ScriptType.FILE); - assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.STORED); assertThat(paramParser.getScriptParameterValue("bar_file"), nullValue()); assertThat(paramParser.getScriptParameterValue("baz_id"), nullValue()); assertThat(paramParser.lang(), equalTo("myLang")); @@ -821,7 +821,7 @@ public class ScriptParameterParserTests extends ESTestCase { paramParser.parseConfig(config, false, ParseFieldMatcher.STRICT); assertParameterValue(paramParser, "foo", "fooScriptValue", ScriptType.INLINE); assertParameterValue(paramParser, "bar", "barScriptValue", ScriptType.FILE); - assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.STORED); assertThat(paramParser.getScriptParameterValue("bar_file"), nullValue()); assertThat(paramParser.getScriptParameterValue("baz_id"), nullValue()); assertThat(paramParser.lang(), equalTo("myLang")); @@ -879,7 +879,7 @@ public class ScriptParameterParserTests extends ESTestCase { paramParser.parseConfig(config, true, ParseFieldMatcher.STRICT); assertParameterValue(paramParser, "foo", "fooScriptValue", ScriptType.INLINE); assertThat(paramParser.getScriptParameterValue("bar"), nullValue()); - assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.STORED); assertThat(paramParser.getScriptParameterValue("bar_file"), nullValue()); assertThat(paramParser.getScriptParameterValue("baz_id"), nullValue()); assertThat(paramParser.getScriptParameterValue("other"), nullValue()); @@ -1026,7 +1026,7 @@ public class ScriptParameterParserTests extends ESTestCase { MapParams params = new MapParams(config); ScriptParameterParser paramParser = new ScriptParameterParser(); paramParser.parseParams(params); - assertDefaultParameterValue(paramParser, "scriptValue", ScriptType.INDEXED); + assertDefaultParameterValue(paramParser, "scriptValue", ScriptType.STORED); assertThat(paramParser.lang(), nullValue()); } @@ -1073,7 +1073,7 @@ public class ScriptParameterParserTests extends ESTestCase { assertThat(paramParser.getScriptParameterValue("foo"), nullValue()); MapParams params = new MapParams(config); paramParser.parseParams(params); - assertParameterValue(paramParser, "foo", "scriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "foo", "scriptValue", ScriptType.STORED); assertThat(paramParser.lang(), nullValue()); } @@ -1193,7 +1193,7 @@ public class ScriptParameterParserTests extends ESTestCase { paramParser.parseParams(params); assertParameterValue(paramParser, "foo", "fooScriptValue", ScriptType.INLINE); assertParameterValue(paramParser, "bar", "barScriptValue", ScriptType.FILE); - assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.STORED); assertThat(paramParser.getScriptParameterValue("bar_file"), nullValue()); assertThat(paramParser.getScriptParameterValue("baz_id"), nullValue()); assertThat(paramParser.lang(), nullValue()); @@ -1220,7 +1220,7 @@ public class ScriptParameterParserTests extends ESTestCase { paramParser.parseParams(params); assertParameterValue(paramParser, "foo", "fooScriptValue", ScriptType.INLINE); assertParameterValue(paramParser, "bar", "barScriptValue", ScriptType.FILE); - assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.STORED); assertThat(paramParser.getScriptParameterValue("bar_file"), nullValue()); assertThat(paramParser.getScriptParameterValue("baz_id"), nullValue()); assertThat(paramParser.lang(), equalTo("myLang")); @@ -1247,7 +1247,7 @@ public class ScriptParameterParserTests extends ESTestCase { paramParser.parseParams(params); assertParameterValue(paramParser, "foo", "fooScriptValue", ScriptType.INLINE); assertParameterValue(paramParser, "bar", "barScriptValue", ScriptType.FILE); - assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.STORED); assertThat(paramParser.getScriptParameterValue("bar_file"), nullValue()); assertThat(paramParser.getScriptParameterValue("baz_id"), nullValue()); assertThat(paramParser.lang(), equalTo("myLang")); @@ -1300,7 +1300,7 @@ public class ScriptParameterParserTests extends ESTestCase { paramParser.parseParams(params); assertParameterValue(paramParser, "foo", "fooScriptValue", ScriptType.INLINE); assertThat(paramParser.getScriptParameterValue("bar"), nullValue()); - assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.INDEXED); + assertParameterValue(paramParser, "baz", "bazScriptValue", ScriptType.STORED); assertThat(paramParser.getScriptParameterValue("bar_file"), nullValue()); assertThat(paramParser.getScriptParameterValue("baz_id"), nullValue()); assertThat(paramParser.getScriptParameterValue("other"), nullValue()); diff --git a/core/src/test/java/org/elasticsearch/script/ScriptServiceTests.java b/core/src/test/java/org/elasticsearch/script/ScriptServiceTests.java index edc04a8bda5..1d5a43b8158 100644 --- a/core/src/test/java/org/elasticsearch/script/ScriptServiceTests.java +++ b/core/src/test/java/org/elasticsearch/script/ScriptServiceTests.java @@ -18,9 +18,19 @@ */ package org.elasticsearch.script; +import org.elasticsearch.ResourceNotFoundException; +import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest; +import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest; +import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequest; +import org.elasticsearch.cluster.ClusterName; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.bytes.BytesArray; +import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.env.Environment; import org.elasticsearch.script.ScriptService.ScriptType; import org.elasticsearch.search.lookup.SearchLookup; @@ -60,7 +70,7 @@ public class ScriptServiceTests extends ESTestCase { static { DEFAULT_SCRIPT_MODES.put(ScriptType.FILE, ScriptMode.ON); - DEFAULT_SCRIPT_MODES.put(ScriptType.INDEXED, ScriptMode.SANDBOX); + DEFAULT_SCRIPT_MODES.put(ScriptType.STORED, ScriptMode.SANDBOX); DEFAULT_SCRIPT_MODES.put(ScriptType.INLINE, ScriptMode.SANDBOX); } @@ -104,7 +114,7 @@ public class ScriptServiceTests extends ESTestCase { Environment environment = new Environment(finalSettings); scriptService = new ScriptService(finalSettings, environment, Collections.singleton(scriptEngineService), resourceWatcherService, scriptEngineRegistry, scriptContextRegistry, scriptSettings) { @Override - String getScriptFromIndex(String scriptLang, String id) { + String getScriptFromClusterState(ClusterState state, String scriptLang, String id) { //mock the script that gets retrieved from an index return "100"; } @@ -129,7 +139,7 @@ public class ScriptServiceTests extends ESTestCase { resourceWatcherService.notifyNow(); CompiledScript compiledScript = scriptService.compile(new Script("test_script", ScriptType.FILE, "test", null), - ScriptContext.Standard.SEARCH, Collections.emptyMap()); + ScriptContext.Standard.SEARCH, Collections.emptyMap(), emptyClusterState()); assertThat(compiledScript.compiled(), equalTo((Object) "compiled_test_file")); Files.delete(testFileNoExt); @@ -138,7 +148,7 @@ public class ScriptServiceTests extends ESTestCase { try { scriptService.compile(new Script("test_script", ScriptType.FILE, "test", null), ScriptContext.Standard.SEARCH, - Collections.emptyMap()); + Collections.emptyMap(), emptyClusterState()); fail("the script test_script should no longer exist"); } catch (IllegalArgumentException ex) { assertThat(ex.getMessage(), containsString("Unable to find on disk file script [test_script] using lang [test]")); @@ -156,7 +166,7 @@ public class ScriptServiceTests extends ESTestCase { resourceWatcherService.notifyNow(); CompiledScript compiledScript = scriptService.compile(new Script("file_script", ScriptType.FILE, "test", null), - ScriptContext.Standard.SEARCH, Collections.emptyMap()); + ScriptContext.Standard.SEARCH, Collections.emptyMap(), emptyClusterState()); assertThat(compiledScript.compiled(), equalTo((Object) "compiled_test_file_script")); Files.delete(testHiddenFile); @@ -167,18 +177,18 @@ public class ScriptServiceTests extends ESTestCase { public void testInlineScriptCompiledOnceCache() throws IOException { buildScriptService(Settings.EMPTY); CompiledScript compiledScript1 = scriptService.compile(new Script("1+1", ScriptType.INLINE, "test", null), - randomFrom(scriptContexts), Collections.emptyMap()); + randomFrom(scriptContexts), Collections.emptyMap(), emptyClusterState()); CompiledScript compiledScript2 = scriptService.compile(new Script("1+1", ScriptType.INLINE, "test", null), - randomFrom(scriptContexts), Collections.emptyMap()); + randomFrom(scriptContexts), Collections.emptyMap(), emptyClusterState()); assertThat(compiledScript1.compiled(), sameInstance(compiledScript2.compiled())); } public void testInlineScriptCompiledOnceMultipleLangAcronyms() throws IOException { buildScriptService(Settings.EMPTY); CompiledScript compiledScript1 = scriptService.compile(new Script("script", ScriptType.INLINE, "test", null), - randomFrom(scriptContexts), Collections.emptyMap()); + randomFrom(scriptContexts), Collections.emptyMap(), emptyClusterState()); CompiledScript compiledScript2 = scriptService.compile(new Script("script", ScriptType.INLINE, "test2", null), - randomFrom(scriptContexts), Collections.emptyMap()); + randomFrom(scriptContexts), Collections.emptyMap(), emptyClusterState()); assertThat(compiledScript1.compiled(), sameInstance(compiledScript2.compiled())); } @@ -186,9 +196,9 @@ public class ScriptServiceTests extends ESTestCase { buildScriptService(Settings.EMPTY); createFileScripts("test"); CompiledScript compiledScript1 = scriptService.compile(new Script("file_script", ScriptType.FILE, "test", null), - randomFrom(scriptContexts), Collections.emptyMap()); + randomFrom(scriptContexts), Collections.emptyMap(), emptyClusterState()); CompiledScript compiledScript2 = scriptService.compile(new Script("file_script", ScriptType.FILE, "test2", null), - randomFrom(scriptContexts), Collections.emptyMap()); + randomFrom(scriptContexts), Collections.emptyMap(), emptyClusterState()); assertThat(compiledScript1.compiled(), sameInstance(compiledScript2.compiled())); } @@ -199,7 +209,7 @@ public class ScriptServiceTests extends ESTestCase { builder.put("script.file", randomFrom(ScriptModesTests.ENABLE_VALUES)); } if (rarely()) { - builder.put("script.indexed", "sandbox"); + builder.put("script.stored", "sandbox"); } if (rarely()) { builder.put("script.inline", "sandbox"); @@ -210,7 +220,7 @@ public class ScriptServiceTests extends ESTestCase { for (ScriptContext scriptContext : scriptContexts) { //custom engine is sandboxed, all scripts are enabled by default assertCompileAccepted("test", "script", ScriptType.INLINE, scriptContext); - assertCompileAccepted("test", "script", ScriptType.INDEXED, scriptContext); + assertCompileAccepted("test", "script", ScriptType.STORED, scriptContext); assertCompileAccepted("test", "file_script", ScriptType.FILE, scriptContext); } } @@ -347,7 +357,7 @@ public class ScriptServiceTests extends ESTestCase { for (String type : scriptEngineService.getTypes()) { try { scriptService.compile(new Script("test", randomFrom(ScriptType.values()), type, null), new ScriptContext.Plugin( - pluginName, unknownContext), Collections.emptyMap()); + pluginName, unknownContext), Collections.emptyMap(), emptyClusterState()); fail("script compilation should have been rejected"); } catch(IllegalArgumentException e) { assertThat(e.getMessage(), containsString("script context [" + pluginName + "_" + unknownContext + "] not supported")); @@ -357,19 +367,23 @@ public class ScriptServiceTests extends ESTestCase { public void testCompileCountedInCompilationStats() throws IOException { buildScriptService(Settings.EMPTY); - scriptService.compile(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), Collections.emptyMap()); + scriptService.compile(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), + Collections.emptyMap(), emptyClusterState()); assertEquals(1L, scriptService.stats().getCompilations()); } public void testExecutableCountedInCompilationStats() throws IOException { buildScriptService(Settings.EMPTY); - scriptService.executable(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), Collections.emptyMap()); + ClusterState state = ClusterState.builder(new ClusterName("_name")).build(); + scriptService.executable(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), Collections.emptyMap(), state); assertEquals(1L, scriptService.stats().getCompilations()); } public void testSearchCountedInCompilationStats() throws IOException { buildScriptService(Settings.EMPTY); - scriptService.search(null, new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), Collections.emptyMap()); + ClusterState state = ClusterState.builder(new ClusterName("_name")).build(); + scriptService.search(null, new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), + Collections.emptyMap(), state); assertEquals(1L, scriptService.stats().getCompilations()); } @@ -378,7 +392,8 @@ public class ScriptServiceTests extends ESTestCase { int numberOfCompilations = randomIntBetween(1, 1024); for (int i = 0; i < numberOfCompilations; i++) { scriptService - .compile(new Script(i + " + " + i, ScriptType.INLINE, "test", null), randomFrom(scriptContexts), Collections.emptyMap()); + .compile(new Script(i + " + " + i, ScriptType.INLINE, "test", null), randomFrom(scriptContexts), + Collections.emptyMap(), emptyClusterState()); } assertEquals(numberOfCompilations, scriptService.stats().getCompilations()); } @@ -387,21 +402,24 @@ public class ScriptServiceTests extends ESTestCase { Settings.Builder builder = Settings.builder(); builder.put(ScriptService.SCRIPT_CACHE_SIZE_SETTING.getKey(), 1); buildScriptService(builder.build()); - scriptService.executable(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), Collections.emptyMap()); - scriptService.executable(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), Collections.emptyMap()); + ClusterState state = ClusterState.builder(new ClusterName("_name")).build(); + scriptService.executable(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), Collections.emptyMap(), state); + scriptService.executable(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), Collections.emptyMap(), state); assertEquals(1L, scriptService.stats().getCompilations()); } public void testFileScriptCountedInCompilationStats() throws IOException { buildScriptService(Settings.EMPTY); createFileScripts("test"); - scriptService.compile(new Script("file_script", ScriptType.FILE, "test", null), randomFrom(scriptContexts), Collections.emptyMap()); + scriptService.compile(new Script("file_script", ScriptType.FILE, "test", null), randomFrom(scriptContexts), + Collections.emptyMap(), emptyClusterState()); assertEquals(1L, scriptService.stats().getCompilations()); } public void testIndexedScriptCountedInCompilationStats() throws IOException { buildScriptService(Settings.EMPTY); - scriptService.compile(new Script("script", ScriptType.INDEXED, "test", null), randomFrom(scriptContexts), Collections.emptyMap()); + scriptService.compile(new Script("script", ScriptType.STORED, "test", null), randomFrom(scriptContexts), + Collections.emptyMap(), emptyClusterState()); assertEquals(1L, scriptService.stats().getCompilations()); } @@ -409,8 +427,9 @@ public class ScriptServiceTests extends ESTestCase { Settings.Builder builder = Settings.builder(); builder.put(ScriptService.SCRIPT_CACHE_SIZE_SETTING.getKey(), 1); buildScriptService(builder.build()); - scriptService.executable(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), Collections.emptyMap()); - scriptService.executable(new Script("2+2", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), Collections.emptyMap()); + ClusterState state = ClusterState.builder(new ClusterName("_name")).build(); + scriptService.executable(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), Collections.emptyMap(), state); + scriptService.executable(new Script("2+2", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), Collections.emptyMap(), state); assertEquals(2L, scriptService.stats().getCompilations()); assertEquals(1L, scriptService.stats().getCacheEvictions()); } @@ -419,11 +438,78 @@ public class ScriptServiceTests extends ESTestCase { Settings.Builder builder = Settings.builder(); builder.put("script.default_lang", "test"); buildScriptService(builder.build()); - CompiledScript script = - scriptService.compile(new Script("1 + 1", ScriptType.INLINE, null, null), randomFrom(scriptContexts), Collections.emptyMap()); + CompiledScript script = scriptService.compile(new Script("1 + 1", ScriptType.INLINE, null, null), + randomFrom(scriptContexts), Collections.emptyMap(), emptyClusterState()); assertEquals(script.lang(), "test"); } + public void testStoreScript() throws Exception { + BytesReference script = XContentFactory.jsonBuilder().startObject() + .field("script", "abc") + .endObject().bytes(); + + ClusterState empty = ClusterState.builder(new ClusterName("_name")).build(); + PutStoredScriptRequest request = new PutStoredScriptRequest("_lang", "_id") + .script(script); + ClusterState result = ScriptService.innerStoreScript(empty, "_lang", request); + ScriptMetaData scriptMetaData = result.getMetaData().custom(ScriptMetaData.TYPE); + assertNotNull(scriptMetaData); + assertEquals("abc", scriptMetaData.getScript("_lang", "_id")); + assertEquals(script, scriptMetaData.getScriptAsBytes("_lang", "_id")); + } + + public void testDeleteScript() throws Exception { + ClusterState cs = ClusterState.builder(new ClusterName("_name")) + .metaData(MetaData.builder() + .putCustom(ScriptMetaData.TYPE, + new ScriptMetaData.Builder(null).storeScript("_lang", "_id", new BytesArray("abc")).build())) + .build(); + + DeleteStoredScriptRequest request = new DeleteStoredScriptRequest("_lang", "_id"); + ClusterState result = ScriptService.innerDeleteScript(cs, "_lang", request); + ScriptMetaData scriptMetaData = result.getMetaData().custom(ScriptMetaData.TYPE); + assertNotNull(scriptMetaData); + assertNull(scriptMetaData.getScript("_lang", "_id")); + assertNull(scriptMetaData.getScriptAsBytes("_lang", "_id")); + + ResourceNotFoundException e = expectThrows(ResourceNotFoundException.class, () -> { + ScriptService.innerDeleteScript(cs, "_lang", new DeleteStoredScriptRequest("_lang", "_non_existing_id")); + }); + assertEquals("Stored script with id [_non_existing_id] for language [_lang] does not exist", e.getMessage()); + } + + public void testGetStoredScript() throws Exception { + buildScriptService(Settings.EMPTY); + ClusterState cs = ClusterState.builder(new ClusterName("_name")) + .metaData(MetaData.builder() + .putCustom(ScriptMetaData.TYPE, + new ScriptMetaData.Builder(null).storeScript("_lang", "_id", + new BytesArray("{\"script\":\"abc\"}")).build())) + .build(); + + assertEquals("abc", scriptService.getStoredScript(cs, new GetStoredScriptRequest("_lang", "_id"))); + assertNull(scriptService.getStoredScript(cs, new GetStoredScriptRequest("_lang", "_id2"))); + + cs = ClusterState.builder(new ClusterName("_name")).build(); + assertNull(scriptService.getStoredScript(cs, new GetStoredScriptRequest("_lang", "_id"))); + } + + public void testValidateScriptSize() throws Exception { + int maxSize = 0xFFFF; + buildScriptService(Settings.EMPTY); + // allowed + scriptService.validate("_id", "test", new BytesArray("{\"script\":\"" + randomAsciiOfLength(maxSize - 13) + "\"}")); + + // disallowed + IllegalArgumentException e = expectThrows(IllegalArgumentException.class, + () -> { + scriptService.validate("_id", "test", new BytesArray("{\"script\":\"" + randomAsciiOfLength(maxSize - 12) + "\"}")); + }); + assertThat(e.getMessage(), equalTo( + "Limit of script size in bytes [" + maxSize+ "] has been exceeded for script [_id] with size [" + (maxSize + 1) + "]")); + } + + private void createFileScripts(String... langs) throws IOException { for (String lang : langs) { Path scriptPath = scriptsFilePath.resolve("file_script." + lang); @@ -434,7 +520,7 @@ public class ScriptServiceTests extends ESTestCase { private void assertCompileRejected(String lang, String script, ScriptType scriptType, ScriptContext scriptContext) { try { - scriptService.compile(new Script(script, scriptType, lang, null), scriptContext, Collections.emptyMap()); + scriptService.compile(new Script(script, scriptType, lang, null), scriptContext, Collections.emptyMap(), emptyClusterState()); fail("compile should have been rejected for lang [" + lang + "], script_type [" + scriptType + "], scripted_op [" + scriptContext + "]"); } catch(ScriptException e) { //all good @@ -442,7 +528,11 @@ public class ScriptServiceTests extends ESTestCase { } private void assertCompileAccepted(String lang, String script, ScriptType scriptType, ScriptContext scriptContext) { - assertThat(scriptService.compile(new Script(script, scriptType, lang, null), scriptContext, Collections.emptyMap()), notNullValue()); + ClusterState state = emptyClusterState(); + assertThat( + scriptService.compile(new Script(script, scriptType, lang, null), scriptContext, Collections.emptyMap(), state), + notNullValue() + ); } public static class TestEngineService implements ScriptEngineService { @@ -492,4 +582,8 @@ public class ScriptServiceTests extends ESTestCase { } } + private static ClusterState emptyClusterState() { + return ClusterState.builder(new ClusterName("_name")).build(); + } + } diff --git a/core/src/test/java/org/elasticsearch/script/StoredScriptsIT.java b/core/src/test/java/org/elasticsearch/script/StoredScriptsIT.java new file mode 100644 index 00000000000..a46ee0d6640 --- /dev/null +++ b/core/src/test/java/org/elasticsearch/script/StoredScriptsIT.java @@ -0,0 +1,88 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.elasticsearch.script; + +import org.elasticsearch.action.admin.cluster.validate.template.RenderSearchTemplateResponse; +import org.elasticsearch.common.bytes.BytesArray; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.test.ESIntegTestCase; + +import java.util.Collection; + +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; + +public class StoredScriptsIT extends ESIntegTestCase { + + private final static int SCRIPT_MAX_SIZE_IN_BYTES = 64; + private final static String LANG = MockScriptEngine.NAME; + + @Override + protected Settings nodeSettings(int nodeOrdinal) { + return Settings.builder().put(super.nodeSettings(nodeOrdinal)) + .put(ScriptService.SCRIPT_MAX_SIZE_IN_BYTES.getKey(), SCRIPT_MAX_SIZE_IN_BYTES) + .build(); + } + + @Override + protected Collection> nodePlugins() { + return pluginList(MockScriptEngine.TestPlugin.class); + } + + public void testBasics() { + assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(LANG) + .setId("foobar") + .setSource(new BytesArray("{\"script\":\"1\"}"))); + String script = client().admin().cluster().prepareGetStoredScript(LANG, "foobar") + .get().getStoredScript(); + assertNotNull(script); + assertEquals("1", script); + + RenderSearchTemplateResponse response = client().admin().cluster().prepareRenderSearchTemplate() + .template(new Template("/" + LANG + "/foobar", ScriptService.ScriptType.STORED, LANG, null, null)) + .get(); + assertEquals("1", response.source().toUtf8()); + + assertAcked(client().admin().cluster().prepareDeleteStoredScript() + .setId("foobar") + .setScriptLang(LANG)); + script = client().admin().cluster().prepareGetStoredScript(LANG, "foobar") + .get().getStoredScript(); + assertNull(script); + + IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> client().admin().cluster().preparePutStoredScript() + .setScriptLang("lang#") + .setId("id#") + .setSource(new BytesArray("{}")) + .get()); + assertEquals("Validation Failed: 1: id can't contain: '#';2: lang can't contain: '#';", e.getMessage()); + } + + public void testMaxScriptSize() { + IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> client().admin().cluster().preparePutStoredScript() + .setScriptLang(LANG) + .setId("foobar") + .setSource(new BytesArray(randomAsciiOfLength(SCRIPT_MAX_SIZE_IN_BYTES + 1))) + .get() + ); + assertEquals("Limit of script size in bytes [64] has been exceeded for script [foobar] with size [65]", e.getMessage()); + } + +} diff --git a/core/src/test/java/org/elasticsearch/search/highlight/HighlightBuilderTests.java b/core/src/test/java/org/elasticsearch/search/highlight/HighlightBuilderTests.java index bc674c19a85..5e706d1f509 100644 --- a/core/src/test/java/org/elasticsearch/search/highlight/HighlightBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/search/highlight/HighlightBuilderTests.java @@ -290,7 +290,7 @@ public class HighlightBuilderTests extends ESTestCase { IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(index, indexSettings); // shard context will only need indicesQueriesRegistry for building Query objects nested in highlighter QueryShardContext mockShardContext = new QueryShardContext(idxSettings, null, null, null, null, null, indicesQueriesRegistry, - null, null) { + null, null, null, null) { @Override public MappedFieldType fieldMapper(String name) { TextFieldMapper.Builder builder = new TextFieldMapper.Builder(name); diff --git a/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java b/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java index de3df9b34aa..fde0b08974f 100644 --- a/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java @@ -160,7 +160,7 @@ public class QueryRescoreBuilderTests extends ESTestCase { IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(randomAsciiOfLengthBetween(1, 10), indexSettings); // shard context will only need indicesQueriesRegistry for building Query objects nested in query rescorer QueryShardContext mockShardContext = new QueryShardContext(idxSettings, null, null, null, null, null, indicesQueriesRegistry, - null, null) { + null, null, null, null) { @Override public MappedFieldType fieldMapper(String name) { TextFieldMapper.Builder builder = new TextFieldMapper.Builder(name); diff --git a/core/src/test/java/org/elasticsearch/search/sort/AbstractSortTestCase.java b/core/src/test/java/org/elasticsearch/search/sort/AbstractSortTestCase.java index fecc048f291..a8562493c7a 100644 --- a/core/src/test/java/org/elasticsearch/search/sort/AbstractSortTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/sort/AbstractSortTestCase.java @@ -22,6 +22,7 @@ package org.elasticsearch.search.sort; import org.apache.lucene.search.SortField; import org.apache.lucene.util.Accountable; import org.elasticsearch.common.ParseFieldMatcher; +import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; @@ -95,7 +96,7 @@ public abstract class AbstractSortTestCase> extends EST scriptService = new ScriptService(baseSettings, environment, Collections.singleton(new TestEngineService()), new ResourceWatcherService(baseSettings, null), scriptEngineRegistry, scriptContextRegistry, scriptSettings) { @Override - public CompiledScript compile(Script script, ScriptContext scriptContext, Map params) { + public CompiledScript compile(Script script, ScriptContext scriptContext, Map params, ClusterState state) { return new CompiledScript(ScriptType.INLINE, "mockName", "test", script); } }; @@ -226,7 +227,7 @@ public abstract class AbstractSortTestCase> extends EST } }); return new QueryShardContext(idxSettings, bitsetFilterCache, ifds, null, null, scriptService, - indicesQueriesRegistry, null, null) { + indicesQueriesRegistry, null, null, null, null) { @Override public MappedFieldType fieldMapper(String name) { return provideMappedFieldType(name); diff --git a/core/src/test/java/org/elasticsearch/transport/ContextAndHeaderTransportIT.java b/core/src/test/java/org/elasticsearch/transport/ContextAndHeaderTransportIT.java index 30476adc18c..5c3f0999ea2 100644 --- a/core/src/test/java/org/elasticsearch/transport/ContextAndHeaderTransportIT.java +++ b/core/src/test/java/org/elasticsearch/transport/ContextAndHeaderTransportIT.java @@ -89,7 +89,7 @@ public class ContextAndHeaderTransportIT extends ESIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put("script.indexed", "true") + .put("script.stored", "true") .put(NetworkModule.HTTP_ENABLED.getKey(), true) .build(); } diff --git a/dev-tools/smoke_test_rc.py b/dev-tools/smoke_test_rc.py index 18aa10e2ed6..365afe72582 100644 --- a/dev-tools/smoke_test_rc.py +++ b/dev-tools/smoke_test_rc.py @@ -204,7 +204,7 @@ def smoke_test_release(release, files, expected_hash, plugins): headers = {} print(' Starting elasticsearch deamon from [%s]' % es_dir) try: - run('%s; %s -Ees.node.name=smoke_tester -Ees.cluster.name=prepare_release -Ees.script.inline=true -Ees.script.indexed=true -Ees.repositories.url.allowed_urls=http://snapshot.test* %s -Ees.pidfile=%s -Ees.node.portsfile=true' + run('%s; %s -Ees.node.name=smoke_tester -Ees.cluster.name=prepare_release -Ees.script.inline=true -Ees.script.stored=true -Ees.repositories.url.allowed_urls=http://snapshot.test* %s -Ees.pidfile=%s -Ees.node.portsfile=true' % (java_exe(), es_run_path, '-d', os.path.join(es_dir, 'es-smoke.pid'))) if not wait_for_node_startup(es_dir, header=headers): print("elasticsearch logs:") diff --git a/docs/reference/migration/migrate_5_0.asciidoc b/docs/reference/migration/migrate_5_0.asciidoc index 9d2370a983c..c315069786d 100644 --- a/docs/reference/migration/migrate_5_0.asciidoc +++ b/docs/reference/migration/migrate_5_0.asciidoc @@ -42,6 +42,7 @@ way to do this is to upgrade to Elasticsearch 2.3 or later and to use the * <> * <> * <> +* <> include::migrate_5_0/search.asciidoc[] @@ -69,3 +70,5 @@ include::migrate_5_0/plugins.asciidoc[] include::migrate_5_0/fs.asciidoc[] include::migrate_5_0/aggregations.asciidoc[] + +include::migrate_5_0/scripting.asciidoc[] diff --git a/docs/reference/migration/migrate_5_0/scripting.asciidoc b/docs/reference/migration/migrate_5_0/scripting.asciidoc new file mode 100644 index 00000000000..14d04d32a6d --- /dev/null +++ b/docs/reference/migration/migrate_5_0/scripting.asciidoc @@ -0,0 +1,57 @@ +[[breaking_50_scripting]] +=== Script related changes + +==== Indexed scripts and templates + +Indexed scrips and templates have been replaced by <> +which stores the scripts and templates in the cluster state instead of a dedicate `.scripts` index. + +For the size of stored scripts there is a soft limit of 65535 bytes. If scripts exceed that size then +the `script.max_size_in_bytes` setting can be added to elasticsearch.yml to change the soft limit to a higher value. +If scripts are really large, other options like native scripts should be considered. + +Previously indexed scripts in the `.scripts` index will not be used any more as +Elasticsearch will now try to fetch the scripts from the cluster state. Upon upgrading +to 5.x the `.scripts` index will remain to exist, so it can be used by a script to migrate +the stored scripts from the `.scripts` index into the cluster state. The format of the scripts +hasn't changed. + +The following Python script can be used to import your indexed scripts into the cluster state +as stored scripts: + +[source,python] +----------------------------------- +from elasticsearch import Elasticsearch,helpers + +es = Elasticsearch([ + {'host': 'localhost'} +]) + +for doc in helpers.scan(es, index=".scripts", preserve_order=True): + es.put_script(lang=doc['_type'], id=doc['_id'], body=doc['_source']) +----------------------------------- + +This script makes use of the official Elasticsearch Python client and +therefor you need to make sure that your have installed the client in your +environment. For more information on this please visit the +https://www.elastic.co/guide/en/elasticsearch/client/python-api/current/index.html[elasticsearch-py page]. + +After you have moved the scripts via the provided script or otherwise then you can verify with the following +request if the migration has happened successfully: + +[source,js] +----------------------------------- +GET _cluster/state?filter_path=metadata.stored_scripts +----------------------------------- + +The response should include all your scripts from the `.scripts` index. +After you have verified that all your scripts have been moved, optionally as a last step, +you can delete the `.scripts` index as Elasticsearch no longer uses it. + +==== Indexed scripts Java APIs + +All the methods related to interacting with indexed scripts have been removed. +The Java API methods for interacting with stored scripts have been added under `ClusterAdminClient` class. +The sugar methods that used to exist on the indexed scripts API methods don't exist on the methods for +stored scripts. The only way to provide scripts is by using `BytesReference` implementation, if a string needs to be +provided the `BytesArray` class should be used. \ No newline at end of file diff --git a/docs/reference/migration/migrate_5_0/settings.asciidoc b/docs/reference/migration/migrate_5_0/settings.asciidoc index 459faa3c9d6..e209176f8c8 100644 --- a/docs/reference/migration/migrate_5_0/settings.asciidoc +++ b/docs/reference/migration/migrate_5_0/settings.asciidoc @@ -237,4 +237,16 @@ and thus require the setting. The `action.get.realtime` setting has been removed. This setting was a fallback realtime setting for the get and mget APIs when realtime wasn't specified. Now if the parameter isn't specified we always -default to true. \ No newline at end of file +default to true. + +==== Indexed script settings + +Due to the fact that indexed script has been replaced by stored +scripts the following settings have been replaced to: + +* `script.indexed` has been replaced by `script.stored` +* `script.engine.*.indexed.aggs` has been replaced by `script.engine.*.stored.aggs` (where `*` represents the script language, like `groovy`, `mustache`, `plainless` etc.) +* `script.engine.*.stored.mapping` has been replaced by `script.engine.*.stored.mapping` (where `*` represents the script language, like `groovy`, `mustache`, `plainless` etc.) +* `script.engine.*.stored.search` has been replaced by `script.engine.*.stored.search` (where `*` represents the script language, like `groovy`, `mustache`, `plainless` etc.) +* `script.engine.*.stored.update` has been replaced by `script.engine.*.stored.update` (where `*` represents the script language, like `groovy`, `mustache`, `plainless` etc.) +* `script.engine.*.stored.plugin` has been replaced by `script.engine.*.stored.plugin` (where `*` represents the script language, like `groovy`, `mustache`, `plainless` etc.) \ No newline at end of file diff --git a/docs/reference/modules/scripting/scripting.asciidoc b/docs/reference/modules/scripting/scripting.asciidoc index 12524407900..047ad0aa136 100644 --- a/docs/reference/modules/scripting/scripting.asciidoc +++ b/docs/reference/modules/scripting/scripting.asciidoc @@ -145,10 +145,10 @@ a script placed under `config/scripts/group1/group2/test.py` will be named `group1_group2_test`. [float] -=== Indexed Scripts -Elasticsearch allows you to store scripts in an internal index known as -`.scripts` and reference them by id. There are REST endpoints to manage -indexed scripts as follows: +[[modules-scripting-stored-scripts]] +=== Stored Scripts +Elasticsearch allows you to store scripts in the cluster state. +There are REST endpoints to manage stored scripts as follows: Requests to the scripts endpoint look like : [source,js] @@ -156,21 +156,19 @@ Requests to the scripts endpoint look like : /_scripts/{lang}/{id} ----------------------------------- Where the `lang` part is the language the script is in and the `id` part is the id -of the script. In the `.scripts` index the type of the document will be set to the `lang`. - +of the script. [source,js] ----------------------------------- -curl -XPOST localhost:9200/_scripts/groovy/indexedCalculateScore -d '{ +curl -XPOST localhost:9200/_scripts/groovy/calculateScore -d '{ "script": "log(_score * 2) + my_modifier" }' ----------------------------------- -This will create a document with id: `indexedCalculateScore` and type: `groovy` in the -`.scripts` index. The type of the document is the language used by the script. +This will store the script under the `calculateScore` in the cluster +state. -This script can be accessed at query time by using the `id` script parameter and passing -the script id: +This script can be accessed at query time by using the `id` and `lang` script parameters: [source,js] -------------------------------------------------- @@ -186,7 +184,7 @@ curl -XPOST localhost:9200/_search -d '{ { "script_score": { "script": { - "id": "indexedCalculateScore", + "id": "calculateScore", "lang" : "groovy", "params": { "my_modifier": 8 @@ -203,7 +201,7 @@ curl -XPOST localhost:9200/_search -d '{ The script can be viewed by: [source,js] ----------------------------------- -curl -XGET localhost:9200/_scripts/groovy/indexedCalculateScore +curl -XGET localhost:9200/_scripts/groovy/calculateScore ----------------------------------- This is rendered as: @@ -215,12 +213,15 @@ This is rendered as: }' ----------------------------------- -Indexed scripts can be deleted by: +Stored scripts can be deleted by: [source,js] ----------------------------------- -curl -XDELETE localhost:9200/_scripts/groovy/indexedCalculateScore +curl -XDELETE localhost:9200/_scripts/groovy/calculateScore ----------------------------------- +NOTE: The size of stored scripts is limited to 65535 bytes. This can be changed by setting `script.max_size_in_bytes` +setting to increase that soft limit, but if scripts are really large then alternatives like native scripts should be considered. + [float] [[enable-dynamic-scripting]] === Enabling dynamic scripting @@ -245,7 +246,7 @@ every script engine, through the following settings that need to be added to the [source,yaml] ----------------------------------- script.inline: true -script.indexed: true +script.stored: true ----------------------------------- @@ -253,7 +254,7 @@ While this still allows execution of named scripts provided in the config, or _native_ Java scripts registered through plugins, it also allows users to run arbitrary scripts via the API. Instead of sending the name of the file as the script, the body of the script can be sent instead or retrieved from the -`.scripts` indexed if previously stored. +cluster state if previously stored. There are three possible configuration values for any of the fine-grained script settings: @@ -271,7 +272,7 @@ The default values are the following: [source,yaml] ----------------------------------- script.inline: sandbox -script.indexed: sandbox +script.stored: sandbox script.file: true ----------------------------------- @@ -322,11 +323,11 @@ script.engine.groovy.file.mapping: true script.engine.groovy.file.search: true script.engine.groovy.file.update: true script.engine.groovy.file.plugin: true -script.engine.groovy.indexed.aggs: true -script.engine.groovy.indexed.mapping: false -script.engine.groovy.indexed.search: true -script.engine.groovy.indexed.update: false -script.engine.groovy.indexed.plugin: false +script.engine.groovy.stored.aggs: true +script.engine.groovy.stored.mapping: false +script.engine.groovy.stored.search: true +script.engine.groovy.stored.update: false +script.engine.groovy.stored.plugin: false script.engine.groovy.inline.aggs: true script.engine.groovy.inline.mapping: false script.engine.groovy.inline.search: false diff --git a/docs/reference/query-dsl/template-query.asciidoc b/docs/reference/query-dsl/template-query.asciidoc index 80155671459..35365e6f9b2 100644 --- a/docs/reference/query-dsl/template-query.asciidoc +++ b/docs/reference/query-dsl/template-query.asciidoc @@ -79,7 +79,7 @@ GET /_search ------------------------------------------ <1> Name of the query template in `config/scripts/`, i.e., `my_template.mustache`. -Alternatively, you can register a query template in the special `.scripts` index with: +Alternatively, you can register a query template in the cluster state with: [source,js] ------------------------------------------ diff --git a/docs/reference/search/search-template.asciidoc b/docs/reference/search/search-template.asciidoc index facdcf904b8..25c4c0423f1 100644 --- a/docs/reference/search/search-template.asciidoc +++ b/docs/reference/search/search-template.asciidoc @@ -238,7 +238,7 @@ GET /_search/template <1> Name of the query template in `config/scripts/`, i.e., `storedTemplate.mustache`. -You can also register search templates by storing it in the elasticsearch cluster in a special index named `.scripts`. +You can also register search templates by storing it in the cluster state. There are REST APIs to manage these indexed templates. [source,js] diff --git a/modules/lang-expression/src/test/java/org/elasticsearch/script/expression/IndexedExpressionTests.java b/modules/lang-expression/src/test/java/org/elasticsearch/script/expression/IndexedExpressionTests.java index 06e04f41a44..731e8760e80 100644 --- a/modules/lang-expression/src/test/java/org/elasticsearch/script/expression/IndexedExpressionTests.java +++ b/modules/lang-expression/src/test/java/org/elasticsearch/script/expression/IndexedExpressionTests.java @@ -19,6 +19,7 @@ package org.elasticsearch.script.expression; +import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.script.Script; @@ -39,8 +40,8 @@ public class IndexedExpressionTests extends ESIntegTestCase { @Override protected Settings nodeSettings(int nodeOrdinal) { Settings.Builder builder = Settings.builder().put(super.nodeSettings(nodeOrdinal)); - builder.put("script.engine.expression.indexed.update", "false"); - builder.put("script.engine.expression.indexed.search", "false"); + builder.put("script.engine.expression.stored.update", "false"); + builder.put("script.engine.expression.stored.search", "false"); return builder.build(); } @@ -50,36 +51,36 @@ public class IndexedExpressionTests extends ESIntegTestCase { } public void testAllOpsDisabledIndexedScripts() throws IOException { - if (randomBoolean()) { - client().preparePutIndexedScript(ExpressionScriptEngineService.NAME, "script1", "{\"script\":\"2\"}").get(); - } else { - client().prepareIndex(ScriptService.SCRIPT_INDEX, ExpressionScriptEngineService.NAME, "script1").setSource("{\"script\":\"2\"}").get(); - } + client().admin().cluster().preparePutStoredScript() + .setScriptLang(ExpressionScriptEngineService.NAME) + .setId("script1") + .setSource(new BytesArray("{\"script\":\"2\"}")) + .get(); client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}").get(); try { client().prepareUpdate("test", "scriptTest", "1") - .setScript(new Script("script1", ScriptService.ScriptType.INDEXED, ExpressionScriptEngineService.NAME, null)).get(); + .setScript(new Script("script1", ScriptService.ScriptType.STORED, ExpressionScriptEngineService.NAME, null)).get(); fail("update script should have been rejected"); } catch(Exception e) { assertThat(e.getMessage(), containsString("failed to execute script")); - assertThat(e.getCause().getMessage(), containsString("scripts of type [indexed], operation [update] and lang [expression] are disabled")); + assertThat(e.getCause().getMessage(), containsString("scripts of type [stored], operation [update] and lang [expression] are disabled")); } try { client().prepareSearch() .setSource( - new SearchSourceBuilder().scriptField("test1", new Script("script1", ScriptType.INDEXED, "expression", null))) + new SearchSourceBuilder().scriptField("test1", new Script("script1", ScriptType.STORED, "expression", null))) .setIndices("test").setTypes("scriptTest").get(); fail("search script should have been rejected"); } catch(Exception e) { - assertThat(e.toString(), containsString("scripts of type [indexed], operation [search] and lang [expression] are disabled")); + assertThat(e.toString(), containsString("scripts of type [stored], operation [search] and lang [expression] are disabled")); } try { client().prepareSearch("test") .setSource( new SearchSourceBuilder().aggregation(AggregationBuilders.terms("test").script( - new Script("script1", ScriptType.INDEXED, "expression", null)))).get(); + new Script("script1", ScriptType.STORED, "expression", null)))).get(); } catch (Exception e) { - assertThat(e.toString(), containsString("scripts of type [indexed], operation [aggs] and lang [expression] are disabled")); + assertThat(e.toString(), containsString("scripts of type [stored], operation [aggs] and lang [expression] are disabled")); } } } diff --git a/modules/lang-groovy/build.gradle b/modules/lang-groovy/build.gradle index 884fe8b65ba..59f5fa4242a 100644 --- a/modules/lang-groovy/build.gradle +++ b/modules/lang-groovy/build.gradle @@ -29,7 +29,7 @@ dependencies { integTest { cluster { setting 'script.inline', 'true' - setting 'script.indexed', 'true' + setting 'script.stored', 'true' } } diff --git a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/BucketScriptTests.java b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/BucketScriptTests.java index 28549a12958..e481e2f59ae 100644 --- a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/BucketScriptTests.java +++ b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/BucketScriptTests.java @@ -21,6 +21,7 @@ package org.elasticsearch.messy.tests; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.script.Script; @@ -85,7 +86,10 @@ public class BucketScriptTests extends ESIntegTestCase { builders.add(client().prepareIndex("idx", "type").setSource(newDocBuilder())); } - client().preparePutIndexedScript().setId("my_script").setScriptLang(GroovyScriptEngineService.NAME).setSource("{ \"script\": \"_value0 + _value1 + _value2\" }").get(); + client().admin().cluster().preparePutStoredScript() + .setId("my_script") + .setScriptLang(GroovyScriptEngineService.NAME) + .setSource(new BytesArray("{ \"script\": \"_value0 + _value1 + _value2\" }")).get(); indexRandom(true, builders); ensureSearchable(); @@ -241,7 +245,7 @@ public class BucketScriptTests extends ESIntegTestCase { .subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation(sum("field4Sum").field(FIELD_4_NAME)) .subAggregation( - bucketScript("seriesArithmetic", bucketsPathsMap, + bucketScript("seriesArithmetic", bucketsPathsMap, new Script("foo + bar + baz", ScriptType.INLINE, null, null)))).execute().actionGet(); assertSearchResponse(response); @@ -377,7 +381,7 @@ public class BucketScriptTests extends ESIntegTestCase { .subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation(sum("field4Sum").field(FIELD_4_NAME)) .subAggregation( - bucketScript("seriesArithmetic", new Script("my_script", ScriptType.INDEXED, null, null), + bucketScript("seriesArithmetic", new Script("my_script", ScriptType.STORED, null, null), "field2Sum", "field3Sum", "field4Sum"))).execute().actionGet(); assertSearchResponse(response); diff --git a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/BucketSelectorTests.java b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/BucketSelectorTests.java index ffee8c75377..5b796a92d7f 100644 --- a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/BucketSelectorTests.java +++ b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/BucketSelectorTests.java @@ -21,6 +21,7 @@ package org.elasticsearch.messy.tests; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.script.Script; @@ -93,8 +94,8 @@ public class BucketSelectorTests extends ESIntegTestCase { builders.add(client().prepareIndex("idx_with_gaps", "type").setSource(newDocBuilder(3, 1, 0, 0))); builders.add(client().prepareIndex("idx_with_gaps", "type").setSource(newDocBuilder(3, 3, 0, 0))); - client().preparePutIndexedScript().setId("my_script").setScriptLang(GroovyScriptEngineService.NAME) - .setSource("{ \"script\": \"Double.isNaN(_value0) ? false : (_value0 + _value1 > 100)\" }").get(); + client().admin().cluster().preparePutStoredScript().setId("my_script").setScriptLang(GroovyScriptEngineService.NAME) + .setSource(new BytesArray("{ \"script\": \"Double.isNaN(_value0) ? false : (_value0 + _value1 > 100)\" }")).get(); indexRandom(true, builders); ensureSearchable(); @@ -358,7 +359,7 @@ public class BucketSelectorTests extends ESIntegTestCase { .subAggregation(sum("field2Sum").field(FIELD_2_NAME)) .subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation( - bucketSelector("bucketSelector", new Script("my_script", ScriptType.INDEXED, null, null), + bucketSelector("bucketSelector", new Script("my_script", ScriptType.STORED, null, null), "field2Sum", "field3Sum"))).execute().actionGet(); assertSearchResponse(response); diff --git a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/IndexedScriptTests.java b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/IndexedScriptTests.java index c4445a97277..623d2cf155c 100644 --- a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/IndexedScriptTests.java +++ b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/IndexedScriptTests.java @@ -22,10 +22,9 @@ package org.elasticsearch.messy.tests; import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.index.IndexRequestBuilder; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptResponse; import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.script.Script; @@ -46,6 +45,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; @@ -60,27 +60,26 @@ public class IndexedScriptTests extends ESIntegTestCase { @Override protected Settings nodeSettings(int nodeOrdinal) { Settings.Builder builder = Settings.builder().put(super.nodeSettings(nodeOrdinal)); - builder.put("script.engine.groovy.indexed.update", "false"); - builder.put("script.engine.groovy.indexed.search", "true"); - builder.put("script.engine.groovy.indexed.aggs", "true"); + builder.put("script.engine.groovy.stored.update", "false"); + builder.put("script.engine.groovy.stored.search", "true"); + builder.put("script.engine.groovy.stored.aggs", "true"); builder.put("script.engine.groovy.inline.aggs", "false"); return builder.build(); } public void testFieldIndexedScript() throws ExecutionException, InterruptedException { + client().admin().cluster().preparePutStoredScript() + .setId("script1") + .setScriptLang("groovy") + .setSource(new BytesArray("{ \"script\" : \"2\"}")) + .get(); + client().admin().cluster().preparePutStoredScript() + .setId("script2") + .setScriptLang("groovy") + .setSource(new BytesArray("{ \"script\" : \"factor * 2\"}")) + .get(); + List builders = new ArrayList<>(); - builders.add(client().prepareIndex(ScriptService.SCRIPT_INDEX, "groovy", "script1").setSource("{" + - "\"script\":\"2\""+ - "}").setTimeout(TimeValue.timeValueSeconds(randomIntBetween(2,10)))); - - builders.add(client().prepareIndex(ScriptService.SCRIPT_INDEX, "groovy", "script2").setSource("{" + - "\"script\":\"factor*2\""+ - "}")); - - indexRandom(true, builders); - - builders.clear(); - builders.add(client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}")); builders.add(client().prepareIndex("test", "scriptTest", "2").setSource("{\"theField\":\"foo 2\"}")); builders.add(client().prepareIndex("test", "scriptTest", "3").setSource("{\"theField\":\"foo 3\"}")); @@ -94,14 +93,14 @@ public class IndexedScriptTests extends ESIntegTestCase { .prepareSearch() .setSource( new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).size(1) - .scriptField("test1", new Script("script1", ScriptType.INDEXED, "groovy", null)) - .scriptField("test2", new Script("script2", ScriptType.INDEXED, "groovy", script2Params))) + .scriptField("test1", new Script("script1", ScriptType.STORED, "groovy", null)) + .scriptField("test2", new Script("script2", ScriptType.STORED, "groovy", script2Params))) .setIndices("test").setTypes("scriptTest").get(); assertHitCount(searchResponse, 5); assertTrue(searchResponse.getHits().hits().length == 1); SearchHit sh = searchResponse.getHits().getAt(0); - assertThat((Integer) sh.field("test1").getValue(), equalTo(2)); - assertThat((Integer) sh.field("test2").getValue(), equalTo(6)); + assertThat(sh.field("test1").getValue(), equalTo(2)); + assertThat(sh.field("test2").getValue(), equalTo(6)); } // Relates to #10397 @@ -113,53 +112,52 @@ public class IndexedScriptTests extends ESIntegTestCase { int iterations = randomIntBetween(2, 11); for (int i = 1; i < iterations; i++) { - PutIndexedScriptResponse response = - client().preparePutIndexedScript(GroovyScriptEngineService.NAME, "script1", "{\"script\":\"" + i + "\"}").get(); - assertEquals(i, response.getVersion()); + assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(GroovyScriptEngineService.NAME) + .setId("script1") + .setSource(new BytesArray("{\"script\":\"" + i + "\"}"))); SearchResponse searchResponse = client() .prepareSearch() .setSource( new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).scriptField("test_field", - new Script("script1", ScriptType.INDEXED, "groovy", null))).setIndices("test_index") + new Script("script1", ScriptType.STORED, "groovy", null))).setIndices("test_index") .setTypes("test_type").get(); assertHitCount(searchResponse, 1); SearchHit sh = searchResponse.getHits().getAt(0); - assertThat((Integer)sh.field("test_field").getValue(), equalTo(i)); + assertThat(sh.field("test_field").getValue(), equalTo(i)); } } public void testDisabledUpdateIndexedScriptsOnly() { - if (randomBoolean()) { - client().preparePutIndexedScript(GroovyScriptEngineService.NAME, "script1", "{\"script\":\"2\"}").get(); - } else { - client().prepareIndex(ScriptService.SCRIPT_INDEX, GroovyScriptEngineService.NAME, "script1").setSource("{\"script\":\"2\"}").get(); - } + assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(GroovyScriptEngineService.NAME) + .setId("script1") + .setSource(new BytesArray("{\"script\":\"2\"}"))); client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}").get(); try { client().prepareUpdate("test", "scriptTest", "1") - .setScript(new Script("script1", ScriptService.ScriptType.INDEXED, GroovyScriptEngineService.NAME, null)).get(); + .setScript(new Script("script1", ScriptService.ScriptType.STORED, GroovyScriptEngineService.NAME, null)).get(); fail("update script should have been rejected"); } catch (Exception e) { assertThat(e.getMessage(), containsString("failed to execute script")); assertThat(ExceptionsHelper.detailedMessage(e), - containsString("scripts of type [indexed], operation [update] and lang [groovy] are disabled")); + containsString("scripts of type [stored], operation [update] and lang [groovy] are disabled")); } } public void testDisabledAggsDynamicScripts() { //dynamic scripts don't need to be enabled for an indexed script to be indexed and later on executed - if (randomBoolean()) { - client().preparePutIndexedScript(GroovyScriptEngineService.NAME, "script1", "{\"script\":\"2\"}").get(); - } else { - client().prepareIndex(ScriptService.SCRIPT_INDEX, GroovyScriptEngineService.NAME, "script1").setSource("{\"script\":\"2\"}").get(); - } + assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(GroovyScriptEngineService.NAME) + .setId("script1") + .setSource(new BytesArray("{\"script\":\"2\"}"))); client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}").get(); refresh(); SearchResponse searchResponse = client() .prepareSearch("test") .setSource( new SearchSourceBuilder().aggregation(AggregationBuilders.terms("test").script( - new Script("script1", ScriptType.INDEXED, null, null)))).get(); + new Script("script1", ScriptType.STORED, null, null)))).get(); assertHitCount(searchResponse, 1); assertThat(searchResponse.getAggregations().get("test"), notNullValue()); } diff --git a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ScriptIndexSettingsTests.java b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ScriptIndexSettingsTests.java deleted file mode 100644 index 34ca4f49662..00000000000 --- a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ScriptIndexSettingsTests.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.elasticsearch.messy.tests; - -import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse; -import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest; -import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse; -import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; -import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptResponse; -import org.elasticsearch.action.support.IndicesOptions; -import org.elasticsearch.index.IndexNotFoundException; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.script.ScriptService; -import org.elasticsearch.script.groovy.GroovyPlugin; -import org.elasticsearch.test.ESIntegTestCase; - -import java.util.Collection; -import java.util.Collections; - -import static org.hamcrest.Matchers.is; - -@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST) -public class ScriptIndexSettingsTests extends ESIntegTestCase { - @Override - protected Collection> nodePlugins() { - return Collections.singleton(GroovyPlugin.class); - } - - public void testScriptIndexSettings() { - PutIndexedScriptResponse putIndexedScriptResponse = - client().preparePutIndexedScript().setId("foobar").setScriptLang("groovy").setSource("{ \"script\": 1 }") - .get(); - assertTrue(putIndexedScriptResponse.isCreated()); - ensureGreen(); - - IndicesExistsRequest existsRequest = new IndicesExistsRequest(); - String[] index = new String[1]; - index[0] = ScriptService.SCRIPT_INDEX; - existsRequest.indices(index); - - - IndicesExistsResponse existsResponse = cluster().client().admin().indices().exists(existsRequest).actionGet(); - assertTrue(existsResponse.isExists()); - - GetSettingsRequest settingsRequest = new GetSettingsRequest(); - settingsRequest.indices(ScriptService.SCRIPT_INDEX); - settingsRequest.indicesOptions(IndicesOptions.strictExpandOpen()); - GetSettingsResponse settingsResponse = client() - .admin() - .indices() - .getSettings(settingsRequest) - .actionGet(); - - String numberOfShards = settingsResponse.getSetting(ScriptService.SCRIPT_INDEX,"index.number_of_shards"); - String numberOfReplicas = settingsResponse.getSetting(ScriptService.SCRIPT_INDEX,"index.auto_expand_replicas"); - - assertEquals("Number of shards should be 1", "1", numberOfShards); - assertEquals("Auto expand replicas should be 0-all", "0-all", numberOfReplicas); - } - - public void testDeleteScriptIndex() { - PutIndexedScriptResponse putIndexedScriptResponse = - client().preparePutIndexedScript().setId("foobar").setScriptLang("groovy").setSource("{ \"script\": 1 }") - .get(); - assertTrue(putIndexedScriptResponse.isCreated()); - DeleteIndexResponse deleteResponse = client().admin().indices().prepareDelete(ScriptService.SCRIPT_INDEX).get(); - assertTrue(deleteResponse.isAcknowledged()); - ensureGreen(); - try { - client().prepareGetIndexedScript("groovy","foobar").get(); - fail("Expected IndexNotFoundException"); - } catch (IndexNotFoundException e) { - assertThat(e.getMessage(), is("no such index")); - } - } -} diff --git a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ScriptedMetricTests.java b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ScriptedMetricTests.java index 11c7c2ab6d4..713ef12e1a7 100644 --- a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ScriptedMetricTests.java +++ b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ScriptedMetricTests.java @@ -20,8 +20,8 @@ package org.elasticsearch.messy.tests; import org.elasticsearch.action.index.IndexRequestBuilder; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptResponse; import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.plugins.Plugin; @@ -51,6 +51,7 @@ import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.search.aggregations.AggregationBuilders.global; import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram; import static org.elasticsearch.search.aggregations.AggregationBuilders.scriptedMetric; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.equalTo; @@ -101,20 +102,25 @@ public class ScriptedMetricTests extends ESIntegTestCase { jsonBuilder().startObject().field("value", i * 2).endObject())); } - PutIndexedScriptResponse indexScriptResponse = client().preparePutIndexedScript(GroovyScriptEngineService.NAME, "initScript_indexed", "{\"script\":\"vars.multiplier = 3\"}").get(); - assertThat(indexScriptResponse.isCreated(), equalTo(true)); - indexScriptResponse = client().preparePutIndexedScript(GroovyScriptEngineService.NAME, "mapScript_indexed", "{\"script\":\"_agg.add(vars.multiplier)\"}").get(); - assertThat(indexScriptResponse.isCreated(), equalTo(true)); - indexScriptResponse = client().preparePutIndexedScript(GroovyScriptEngineService.NAME, "combineScript_indexed", - "{\"script\":\"newaggregation = []; sum = 0;for (a in _agg) { sum += a}; newaggregation.add(sum); return newaggregation\"}") - .get(); - assertThat(indexScriptResponse.isCreated(), equalTo(true)); - indexScriptResponse = client().preparePutIndexedScript( - "groovy", - "reduceScript_indexed", - "{\"script\":\"newaggregation = []; sum = 0;for (agg in _aggs) { for (a in agg) { sum += a} }; newaggregation.add(sum); return newaggregation\"}") - .get(); - assertThat(indexScriptResponse.isCreated(), equalTo(true)); + assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(GroovyScriptEngineService.NAME) + .setId("initScript_indexed") + .setSource(new BytesArray("{\"script\":\"vars.multiplier = 3\"}"))); + + assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(GroovyScriptEngineService.NAME) + .setId("mapScript_indexed") + .setSource(new BytesArray("{\"script\":\"_agg.add(vars.multiplier)\"}"))); + + assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(GroovyScriptEngineService.NAME) + .setId("combineScript_indexed") + .setSource(new BytesArray("{\"script\":\"newaggregation = []; sum = 0;for (a in _agg) { sum += a}; newaggregation.add(sum); return newaggregation\"}"))); + + assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(GroovyScriptEngineService.NAME) + .setId("reduceScript_indexed") + .setSource(new BytesArray("{\"script\":\"newaggregation = []; sum = 0;for (agg in _aggs) { for (a in agg) { sum += a} }; newaggregation.add(sum); return newaggregation\"}"))); indexRandom(true, builders); ensureSearchable(); @@ -595,10 +601,10 @@ public class ScriptedMetricTests extends ESIntegTestCase { .setQuery(matchAllQuery()) .addAggregation( scriptedMetric("scripted").params(params) - .initScript(new Script("initScript_indexed", ScriptType.INDEXED, null, null)) - .mapScript(new Script("mapScript_indexed", ScriptType.INDEXED, null, null)) - .combineScript(new Script("combineScript_indexed", ScriptType.INDEXED, null, null)) - .reduceScript(new Script("reduceScript_indexed", ScriptType.INDEXED, null, null))).execute().actionGet(); + .initScript(new Script("initScript_indexed", ScriptType.STORED, null, null)) + .mapScript(new Script("mapScript_indexed", ScriptType.STORED, null, null)) + .combineScript(new Script("combineScript_indexed", ScriptType.STORED, null, null)) + .reduceScript(new Script("reduceScript_indexed", ScriptType.STORED, null, null))).execute().actionGet(); assertSearchResponse(response); assertThat(response.getHits().getTotalHits(), equalTo(numDocs)); diff --git a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/package-info.java b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/package-info.java index adf34927ba4..ebc03bea2b3 100644 --- a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/package-info.java +++ b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/package-info.java @@ -65,7 +65,6 @@ renamed: core/src/test/java/org/elasticsearch/percolator/PercolatorIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/PercolatorTests.java renamed: core/src/test/java/org/elasticsearch/search/functionscore/RandomScoreFunctionIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/RandomScoreFunctionTests.java renamed: core/src/test/java/org/elasticsearch/search/aggregations/bucket/RangeIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/RangeTests.java - renamed: core/src/test/java/org/elasticsearch/script/ScriptIndexSettingsIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ScriptIndexSettingsTests.java renamed: core/src/test/java/org/elasticsearch/search/scriptfilter/ScriptQuerySearchIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ScriptQuerySearchTests.java renamed: core/src/test/java/org/elasticsearch/search/aggregations/metrics/ScriptedMetricIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ScriptedMetricTests.java renamed: core/src/test/java/org/elasticsearch/search/fields/SearchFieldsIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SearchFieldsTests.java diff --git a/modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/16_update2.yaml b/modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/16_update2.yaml index ee977429b59..5e1f99eeeff 100644 --- a/modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/16_update2.yaml +++ b/modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/16_update2.yaml @@ -9,7 +9,7 @@ id: "1" lang: "groovy" body: { "script": "_score * doc[\"myParent.weight\"].value" } - - match: { _id: "1" } + - match: { acknowledged: true } - do: get_script: @@ -18,7 +18,6 @@ - match: { found: true } - match: { lang: groovy } - match: { _id: "1" } - - match: { _version: 1 } - match: { "script": "_score * doc[\"myParent.weight\"].value" } - do: @@ -29,27 +28,19 @@ - match: { found: false } - match: { lang: groovy } - match: { _id: "2" } - - is_false: _version - is_false: script - do: delete_script: id: "1" lang: "groovy" - - match: { found: true } - - match: { _index: ".scripts" } - - match: { _id: "1" } - - match: { _version: 2 } + - match: { acknowledged: true } - do: catch: missing delete_script: id: "non_existing" lang: "groovy" - - match: { found: false } - - match: { _index: ".scripts" } - - match: { _id: "non_existing" } - - match: { _version: 1 } - do: catch: request diff --git a/modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/20_versions.yaml b/modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/20_versions.yaml deleted file mode 100644 index 1e34bccca71..00000000000 --- a/modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/20_versions.yaml +++ /dev/null @@ -1,116 +0,0 @@ ---- -"External version": - - - skip: - features: groovy_scripting - - - - do: - put_script: - lang: groovy - id: 1 - body: { "script": "_score * doc[\"myParent.weight\"].value" } - version_type: external - version: 0 - - - match: { _version: 0 } - - - do: - put_script: - lang: groovy - id: 1 - body: { "script": "_score * doc[\"myParent.weight\"].value" } - version_type: external - version: 5 - - - match: { _version: 5 } - - - do: - catch: conflict - get_script: - lang: groovy - id: 1 - version: 3 - - - do: - catch: conflict - delete_script: - lang: groovy - id: 1 - version: 3 - - - do: - get_script: - lang: groovy - id: 1 - version: 5 - version_type: external - - is_true: script - - - do: - get_script: - lang: groovy - id: 1 - version: 5 - version_type: external_gte - - is_true: script - - - do: - catch: conflict - get_script: - lang: groovy - id: 1 - version: 10 - version_type: external_gte - - - do: - catch: conflict - delete_script: - lang: groovy - id: 1 - version: 3 - version_type: external - - - do: - get_script: - lang: groovy - id: 1 - version: 5 - version_type: force - - is_true: script - - - do: - get_script: - lang: groovy - id: 1 - version: 10 - version_type: force - - is_true: script - - - do: - catch: conflict - put_script: - lang: groovy - id: 1 - body: { "script": "_score * doc[\"myParent.weight\"].value" } - version_type: external - version: 5 - - - do: - catch: conflict - put_script: - lang: groovy - id: 1 - body: { "script": "_score * doc[\"myParent.weight\"].value" } - version_type: external - version: 0 - - - do: - put_script: - lang: groovy - id: 1 - body: { "script": "_score * doc[\"myParent.weight\"].value" } - version_type: external - version: 6 - - - match: { _version: 6} diff --git a/modules/lang-mustache/build.gradle b/modules/lang-mustache/build.gradle index 8eed31dd668..374fd94e7d9 100644 --- a/modules/lang-mustache/build.gradle +++ b/modules/lang-mustache/build.gradle @@ -29,6 +29,6 @@ dependencies { integTest { cluster { setting 'script.inline', 'true' - setting 'script.indexed', 'true' + setting 'script.stored', 'true' } } diff --git a/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/RenderSearchTemplateTests.java b/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/RenderSearchTemplateTests.java index 8d73da63033..f2345c6583b 100644 --- a/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/RenderSearchTemplateTests.java +++ b/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/RenderSearchTemplateTests.java @@ -32,6 +32,7 @@ import org.elasticsearch.script.Template; import org.elasticsearch.script.mustache.MustachePlugin; import org.elasticsearch.script.mustache.MustacheScriptEngineService; import org.elasticsearch.test.ESIntegTestCase; +import org.elasticsearch.test.hamcrest.ElasticsearchAssertions; import java.nio.file.Files; import java.nio.file.Path; @@ -54,7 +55,10 @@ public class RenderSearchTemplateTests extends ESIntegTestCase { @Override protected void setupSuiteScopeCluster() throws Exception { - client().preparePutIndexedScript(MustacheScriptEngineService.NAME, "index_template_1", "{ \"template\": " + TEMPLATE_CONTENTS + " }").get(); + ElasticsearchAssertions.assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(MustacheScriptEngineService.NAME) + .setId("index_template_1") + .setSource(new BytesArray("{ \"template\": " + TEMPLATE_CONTENTS + " }"))); } @Override @@ -104,7 +108,7 @@ public class RenderSearchTemplateTests extends ESIntegTestCase { Map params = new HashMap<>(); params.put("value", "bar"); params.put("size", 20); - Template template = new Template("index_template_1", ScriptType.INDEXED, MustacheScriptEngineService.NAME, XContentType.JSON, params); + Template template = new Template("index_template_1", ScriptType.STORED, MustacheScriptEngineService.NAME, XContentType.JSON, params); RenderSearchTemplateResponse response = client().admin().cluster().prepareRenderSearchTemplate().template(template).get(); assertThat(response, notNullValue()); BytesReference source = response.source(); @@ -118,7 +122,7 @@ public class RenderSearchTemplateTests extends ESIntegTestCase { params = new HashMap<>(); params.put("value", "baz"); params.put("size", 100); - template = new Template("index_template_1", ScriptType.INDEXED, MustacheScriptEngineService.NAME, XContentType.JSON, params); + template = new Template("index_template_1", ScriptType.STORED, MustacheScriptEngineService.NAME, XContentType.JSON, params); response = client().admin().cluster().prepareRenderSearchTemplate().template(template).get(); assertThat(response, notNullValue()); source = response.source(); diff --git a/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/TemplateQueryParserTests.java b/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/TemplateQueryParserTests.java index 37cae5092cb..0815e27ce76 100644 --- a/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/TemplateQueryParserTests.java +++ b/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/TemplateQueryParserTests.java @@ -149,7 +149,8 @@ public class TemplateQueryParserTests extends ESTestCase { } }); IndicesQueriesRegistry indicesQueriesRegistry = injector.getInstance(IndicesQueriesRegistry.class); - context = new QueryShardContext(idxSettings, bitsetFilterCache, indexFieldDataService, mapperService, similarityService, scriptService, indicesQueriesRegistry, null, null); + context = new QueryShardContext(idxSettings, bitsetFilterCache, indexFieldDataService, mapperService, + similarityService, scriptService, indicesQueriesRegistry, proxy, null, null, null); } @Override diff --git a/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/TemplateQueryTests.java b/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/TemplateQueryTests.java index d4d400c145a..50e1a53207e 100644 --- a/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/TemplateQueryTests.java +++ b/modules/lang-mustache/src/test/java/org/elasticsearch/messy/tests/TemplateQueryTests.java @@ -26,16 +26,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.elasticsearch.action.index.IndexRequest.OpType; import org.elasticsearch.action.index.IndexRequestBuilder; -import org.elasticsearch.action.indexedscripts.delete.DeleteIndexedScriptResponse; -import org.elasticsearch.action.indexedscripts.get.GetIndexedScriptResponse; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptRequestBuilder; -import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptResponse; +import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptResponse; import org.elasticsearch.action.search.SearchPhaseExecutionException; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.ParseFieldMatcher; +import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; @@ -53,6 +50,7 @@ import org.elasticsearch.test.ESIntegTestCase; import org.junit.Before; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertFailures; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures; @@ -257,33 +255,33 @@ public class TemplateQueryTests extends ESIntegTestCase { } public void testIndexedTemplateClient() throws Exception { - createIndex(ScriptService.SCRIPT_INDEX); - ensureGreen(ScriptService.SCRIPT_INDEX); - - PutIndexedScriptResponse scriptResponse = client().preparePutIndexedScript(MustacheScriptEngineService.NAME, "testTemplate", "{" + + assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(MustacheScriptEngineService.NAME) + .setId("testTemplate") + .setSource(new BytesArray("{" + "\"template\":{" + " \"query\":{" + " \"match\":{" + " \"theField\" : \"{{fieldParam}}\"}" + " }" + "}" + - "}").get(); + "}"))); - assertTrue(scriptResponse.isCreated()); - scriptResponse = client().preparePutIndexedScript(MustacheScriptEngineService.NAME, "testTemplate", "{" + + assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(MustacheScriptEngineService.NAME) + .setId("testTemplate").setSource(new BytesArray("{" + "\"template\":{" + " \"query\":{" + " \"match\":{" + " \"theField\" : \"{{fieldParam}}\"}" + " }" + "}" + - "}").get(); + "}"))); - assertEquals(scriptResponse.getVersion(), 2); - - GetIndexedScriptResponse getResponse = client().prepareGetIndexedScript(MustacheScriptEngineService.NAME, "testTemplate").get(); - assertTrue(getResponse.isExists()); + GetStoredScriptResponse getResponse = client().admin().cluster() + .prepareGetStoredScript(MustacheScriptEngineService.NAME, "testTemplate").get(); + assertNotNull(getResponse.getStoredScript()); List builders = new ArrayList<>(); @@ -299,22 +297,22 @@ public class TemplateQueryTests extends ESIntegTestCase { templateParams.put("fieldParam", "foo"); SearchResponse searchResponse = client().prepareSearch("test").setTypes("type") - .setTemplate(new Template("testTemplate", ScriptType.INDEXED, MustacheScriptEngineService.NAME, null, templateParams)) + .setTemplate(new Template("testTemplate", ScriptType.STORED, MustacheScriptEngineService.NAME, null, templateParams)) .get(); assertHitCount(searchResponse, 4); - DeleteIndexedScriptResponse deleteResponse = client().prepareDeleteIndexedScript(MustacheScriptEngineService.NAME, "testTemplate") - .get(); - assertTrue(deleteResponse.isFound()); + assertAcked(client().admin().cluster() + .prepareDeleteStoredScript(MustacheScriptEngineService.NAME, "testTemplate")); - getResponse = client().prepareGetIndexedScript(MustacheScriptEngineService.NAME, "testTemplate").get(); - assertFalse(getResponse.isExists()); + getResponse = client().admin().cluster() + .prepareGetStoredScript(MustacheScriptEngineService.NAME, "testTemplate").get(); + assertNull(getResponse.getStoredScript()); try { client().prepareSearch("test") .setTypes("type") .setTemplate( - new Template("/template_index/mustache/1000", ScriptType.INDEXED, MustacheScriptEngineService.NAME, null, + new Template("/template_index/mustache/1000", ScriptType.STORED, MustacheScriptEngineService.NAME, null, templateParams)).get(); fail("Expected SearchPhaseExecutionException"); } catch (SearchPhaseExecutionException e) { @@ -323,43 +321,50 @@ public class TemplateQueryTests extends ESIntegTestCase { } public void testIndexedTemplate() throws Exception { - createIndex(ScriptService.SCRIPT_INDEX); - ensureGreen(ScriptService.SCRIPT_INDEX); + assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(MustacheScriptEngineService.NAME) + .setId("1a") + .setSource(new BytesArray("{" + + "\"template\":{"+ + " \"query\":{" + + " \"match\":{" + + " \"theField\" : \"{{fieldParam}}\"}" + + " }" + + "}" + + "}" + )) + ); + assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(MustacheScriptEngineService.NAME) + .setId("2") + .setSource(new BytesArray("{" + + "\"template\":{"+ + " \"query\":{" + + " \"match\":{" + + " \"theField\" : \"{{fieldParam}}\"}" + + " }" + + "}" + + "}")) + ); + assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(MustacheScriptEngineService.NAME) + .setId("3") + .setSource(new BytesArray("{" + + "\"template\":{"+ + " \"match\":{" + + " \"theField\" : \"{{fieldParam}}\"}" + + " }" + + "}")) + ); + + + List builders = new ArrayList<>(); - builders.add(client().prepareIndex(ScriptService.SCRIPT_INDEX, MustacheScriptEngineService.NAME, "1a").setSource("{" + - "\"template\":{"+ - " \"query\":{" + - " \"match\":{" + - " \"theField\" : \"{{fieldParam}}\"}" + - " }" + - "}" + - "}")); - builders.add(client().prepareIndex(ScriptService.SCRIPT_INDEX, MustacheScriptEngineService.NAME, "2").setSource("{" + - "\"template\":{"+ - " \"query\":{" + - " \"match\":{" + - " \"theField\" : \"{{fieldParam}}\"}" + - " }" + - "}" + - "}")); - - builders.add(client().prepareIndex(ScriptService.SCRIPT_INDEX, MustacheScriptEngineService.NAME, "3").setSource("{" + - "\"template\":{"+ - " \"match\":{" + - " \"theField\" : \"{{fieldParam}}\"}" + - " }" + - "}")); - - indexRandom(true, builders); - - builders.clear(); - builders.add(client().prepareIndex("test", "type", "1").setSource("{\"theField\":\"foo\"}")); builders.add(client().prepareIndex("test", "type", "2").setSource("{\"theField\":\"foo 2\"}")); builders.add(client().prepareIndex("test", "type", "3").setSource("{\"theField\":\"foo 3\"}")); builders.add(client().prepareIndex("test", "type", "4").setSource("{\"theField\":\"foo 4\"}")); builders.add(client().prepareIndex("test", "type", "5").setSource("{\"theField\":\"bar\"}")); - indexRandom(true, builders); Map templateParams = new HashMap<>(); @@ -369,7 +374,7 @@ public class TemplateQueryTests extends ESIntegTestCase { .prepareSearch("test") .setTypes("type") .setTemplate( - new Template("/mustache/1a", ScriptService.ScriptType.INDEXED, MustacheScriptEngineService.NAME, null, + new Template("/mustache/1a", ScriptService.ScriptType.STORED, MustacheScriptEngineService.NAME, null, templateParams)).get(); assertHitCount(searchResponse, 4); @@ -377,7 +382,7 @@ public class TemplateQueryTests extends ESIntegTestCase { client().prepareSearch("test") .setTypes("type") .setTemplate( - new Template("/template_index/mustache/1000", ScriptService.ScriptType.INDEXED, + new Template("/template_index/mustache/1000", ScriptService.ScriptType.STORED, MustacheScriptEngineService.NAME, null, templateParams)).get(); fail("shouldn't get here"); } catch (SearchPhaseExecutionException spee) { @@ -389,7 +394,7 @@ public class TemplateQueryTests extends ESIntegTestCase { .prepareSearch("test") .setTypes("type") .setTemplate( - new Template("/myindex/mustache/1", ScriptService.ScriptType.INDEXED, MustacheScriptEngineService.NAME, null, + new Template("/myindex/mustache/1", ScriptService.ScriptType.STORED, MustacheScriptEngineService.NAME, null, templateParams)).get(); assertFailures(searchResponse); } catch (SearchPhaseExecutionException spee) { @@ -397,7 +402,7 @@ public class TemplateQueryTests extends ESIntegTestCase { } searchResponse = client().prepareSearch("test").setTypes("type") - .setTemplate(new Template("1a", ScriptService.ScriptType.INDEXED, MustacheScriptEngineService.NAME, null, templateParams)) + .setTemplate(new Template("1a", ScriptService.ScriptType.STORED, MustacheScriptEngineService.NAME, null, templateParams)) .get(); assertHitCount(searchResponse, 4); @@ -406,7 +411,7 @@ public class TemplateQueryTests extends ESIntegTestCase { .prepareSearch("test") .setTypes("type") .setTemplate( - new Template("/mustache/2", ScriptService.ScriptType.INDEXED, MustacheScriptEngineService.NAME, null, + new Template("/mustache/2", ScriptService.ScriptType.STORED, MustacheScriptEngineService.NAME, null, templateParams)).get(); assertHitCount(searchResponse, 1); @@ -414,7 +419,7 @@ public class TemplateQueryTests extends ESIntegTestCase { vars.put("fieldParam", "bar"); TemplateQueryBuilder builder = new TemplateQueryBuilder(new Template( - "3", ScriptService.ScriptType.INDEXED, null, null, vars)); + "3", ScriptService.ScriptType.STORED, null, null, vars)); SearchResponse sr = client().prepareSearch().setQuery(builder) .execute().actionGet(); assertHitCount(sr, 1); @@ -422,11 +427,11 @@ public class TemplateQueryTests extends ESIntegTestCase { // "{\"template\": {\"id\": \"3\",\"params\" : {\"fieldParam\" : \"foo\"}}}"; Map params = new HashMap<>(); params.put("fieldParam", "foo"); - TemplateQueryBuilder templateQuery = new TemplateQueryBuilder(new Template("3", ScriptType.INDEXED, null, null, params)); + TemplateQueryBuilder templateQuery = new TemplateQueryBuilder(new Template("3", ScriptType.STORED, null, null, params)); sr = client().prepareSearch().setQuery(templateQuery).get(); assertHitCount(sr, 4); - templateQuery = new TemplateQueryBuilder(new Template("/mustache/3", ScriptType.INDEXED, null, null, params)); + templateQuery = new TemplateQueryBuilder(new Template("/mustache/3", ScriptType.STORED, null, null, params)); sr = client().prepareSearch().setQuery(templateQuery).get(); assertHitCount(sr, 4); } @@ -441,12 +446,15 @@ public class TemplateQueryTests extends ESIntegTestCase { int iterations = randomIntBetween(2, 11); for (int i = 1; i < iterations; i++) { - PutIndexedScriptResponse scriptResponse = client().preparePutIndexedScript(MustacheScriptEngineService.NAME, "git01", - "{\"query\": {\"match\": {\"searchtext\": {\"query\": \"{{P_Keyword1}}\",\"type\": \"ooophrase_prefix\"}}}}").get(); - assertEquals(i * 2 - 1, scriptResponse.getVersion()); + assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(MustacheScriptEngineService.NAME) + .setId("git01") + .setSource(new BytesArray("{\"template\":{\"query\": {\"match\": {\"searchtext\": {\"query\": \"{{P_Keyword1}}\"," + + "\"type\": \"ooophrase_prefix\"}}}}}"))); - GetIndexedScriptResponse getResponse = client().prepareGetIndexedScript(MustacheScriptEngineService.NAME, "git01").get(); - assertTrue(getResponse.isExists()); + GetStoredScriptResponse getResponse = client().admin().cluster() + .prepareGetStoredScript(MustacheScriptEngineService.NAME, "git01").get(); + assertNotNull(getResponse.getStoredScript()); Map templateParams = new HashMap<>(); templateParams.put("P_Keyword1", "dev"); @@ -455,41 +463,39 @@ public class TemplateQueryTests extends ESIntegTestCase { client().prepareSearch("testindex") .setTypes("test") .setTemplate( - new Template("git01", ScriptService.ScriptType.INDEXED, MustacheScriptEngineService.NAME, null, + new Template("git01", ScriptService.ScriptType.STORED, MustacheScriptEngineService.NAME, null, templateParams)).get(); fail("Broken test template is parsing w/o error."); } catch (SearchPhaseExecutionException e) { // the above is expected to fail } - PutIndexedScriptRequestBuilder builder = client().preparePutIndexedScript(MustacheScriptEngineService.NAME, "git01", - "{\"query\": {\"match\": {\"searchtext\": {\"query\": \"{{P_Keyword1}}\",\"type\": \"phrase_prefix\"}}}}").setOpType( - OpType.INDEX); - scriptResponse = builder.get(); - assertEquals(i * 2, scriptResponse.getVersion()); + assertAcked(client().admin().cluster().preparePutStoredScript() + .setScriptLang(MustacheScriptEngineService.NAME) + .setId("git01") + .setSource(new BytesArray("{\"query\": {\"match\": {\"searchtext\": {\"query\": \"{{P_Keyword1}}\"," + + "\"type\": \"phrase_prefix\"}}}}"))); + SearchResponse searchResponse = client() .prepareSearch("testindex") .setTypes("test") .setTemplate( - new Template("git01", ScriptService.ScriptType.INDEXED, MustacheScriptEngineService.NAME, null, templateParams)) + new Template("git01", ScriptService.ScriptType.STORED, MustacheScriptEngineService.NAME, null, templateParams)) .get(); assertHitCount(searchResponse, 1); } } public void testIndexedTemplateWithArray() throws Exception { - createIndex(ScriptService.SCRIPT_INDEX); - ensureGreen(ScriptService.SCRIPT_INDEX); - List builders = new ArrayList<>(); - String multiQuery = "{\"query\":{\"terms\":{\"theField\":[\"{{#fieldParam}}\",\"{{.}}\",\"{{/fieldParam}}\"]}}}"; - builders.add(client().prepareIndex(ScriptService.SCRIPT_INDEX, MustacheScriptEngineService.NAME, "4").setSource(jsonBuilder().startObject().field("template", multiQuery).endObject())); - - indexRandom(true,builders); - - builders.clear(); - + assertAcked( + client().admin().cluster().preparePutStoredScript() + .setScriptLang(MustacheScriptEngineService.NAME) + .setId("4") + .setSource(jsonBuilder().startObject().field("template", multiQuery).endObject().bytes()) + ); + List builders = new ArrayList<>(); builders.add(client().prepareIndex("test", "type", "1").setSource("{\"theField\":\"foo\"}")); builders.add(client().prepareIndex("test", "type", "2").setSource("{\"theField\":\"foo 2\"}")); builders.add(client().prepareIndex("test", "type", "3").setSource("{\"theField\":\"foo 3\"}")); @@ -506,7 +512,7 @@ public class TemplateQueryTests extends ESIntegTestCase { .prepareSearch("test") .setTypes("type") .setTemplate( - new Template("/mustache/4", ScriptService.ScriptType.INDEXED, MustacheScriptEngineService.NAME, null, + new Template("/mustache/4", ScriptService.ScriptType.STORED, MustacheScriptEngineService.NAME, null, arrayTemplateParams)).get(); assertHitCount(searchResponse, 5); } diff --git a/modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/10_basic.yaml b/modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/10_basic.yaml index 195eea7c4b8..9533cde81ac 100644 --- a/modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/10_basic.yaml +++ b/modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/10_basic.yaml @@ -19,7 +19,7 @@ put_template: id: "1" body: { "template": { "query": { "match_all": {}}, "size": "{{my_size}}" } } - - match: { _id: "1" } + - match: { acknowledged: true } - do: get_template: @@ -27,7 +27,6 @@ - match: { found: true } - match: { lang: mustache } - match: { _id: "1" } - - match: { _version: 1 } - match: { template: /.*query\S\S\S\Smatch_all.*/ } - do: @@ -37,25 +36,16 @@ - match: { found: false } - match: { lang: mustache } - match: { _id: "2" } - - is_false: _version - - is_false: template - do: delete_template: id: "1" - - match: { found: true } - - match: { _index: ".scripts" } - - match: { _id: "1" } - - match: { _version: 2} + - match: { acknowledged: true } - do: catch: missing delete_template: id: "non_existing" - - match: { found: false } - - match: { _index: ".scripts" } - - match: { _id: "non_existing" } - - match: { _version: 1 } - do: catch: request diff --git a/modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/20_search.yaml b/modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/20_search.yaml index 4da748aac80..4c38dceb14d 100644 --- a/modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/20_search.yaml +++ b/modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/20_search.yaml @@ -20,11 +20,7 @@ put_template: id: "1" body: { "template": { "query": { "match" : { "text": "{{my_value}}" } }, "size": "{{my_size}}" } } - - match: { _id: "1" } - - - do: - indices.refresh: {} - + - match: { acknowledged: true } - do: search_template: diff --git a/modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/30_render_search_template.yaml b/modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/30_render_search_template.yaml index 5d5c3d5f761..658d5ed7a90 100644 --- a/modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/30_render_search_template.yaml +++ b/modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/30_render_search_template.yaml @@ -5,10 +5,7 @@ put_template: id: "1" body: { "template": { "query": { "match": { "text": "{{my_value}}" } }, "aggs": { "my_terms": { "terms": { "field": "{{my_field}}" } } } } } - - match: { _id: "1" } - - - do: - indices.refresh: {} + - match: { acknowledged: true } - do: render_search_template: @@ -60,10 +57,7 @@ put_template: id: "1" body: { "template": "{ \"query\": { \"match\": { \"text\": \"{{my_value}}\" } }, \"size\": {{my_size}} }" } - - match: { _id: "1" } - - - do: - indices.refresh: {} + - match: { acknowledged: true } - do: render_search_template: diff --git a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/AbstractAsyncBulkIndexByScrollAction.java b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/AbstractAsyncBulkIndexByScrollAction.java index bcc4b09b2e6..345b92df67b 100644 --- a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/AbstractAsyncBulkIndexByScrollAction.java +++ b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/AbstractAsyncBulkIndexByScrollAction.java @@ -24,6 +24,8 @@ import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.client.Client; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.index.mapper.internal.IdFieldMapper; import org.elasticsearch.index.mapper.internal.IndexFieldMapper; @@ -61,14 +63,14 @@ public abstract class AbstractAsyncBulkIndexByScrollAction< private final CompiledScript script; public AbstractAsyncBulkIndexByScrollAction(BulkByScrollTask task, ESLogger logger, ScriptService scriptService, - Client client, ThreadPool threadPool, Request mainRequest, SearchRequest firstSearchRequest, + ClusterState state, Client client, ThreadPool threadPool, Request mainRequest, SearchRequest firstSearchRequest, ActionListener listener) { super(task, logger, client, threadPool, mainRequest, firstSearchRequest, listener); this.scriptService = scriptService; if (mainRequest.getScript() == null) { script = null; } else { - script = scriptService.compile(mainRequest.getScript(), ScriptContext.Standard.UPDATE, emptyMap()); + script = scriptService.compile(mainRequest.getScript(), ScriptContext.Standard.UPDATE, emptyMap(), state); } } diff --git a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/TransportReindexAction.java b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/TransportReindexAction.java index 482f101653d..ccf72414c8b 100644 --- a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/TransportReindexAction.java +++ b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/TransportReindexAction.java @@ -71,9 +71,10 @@ public class TransportReindexAction extends HandledTransportAction listener) { - validateAgainstAliases(request.getSearchRequest(), request.getDestination(), indexNameExpressionResolver, autoCreateIndex, - clusterService.state()); - new AsyncIndexBySearchAction((BulkByScrollTask) task, logger, scriptService, client, threadPool, request, listener).start(); + ClusterState state = clusterService.state(); + validateAgainstAliases(request.getSearchRequest(), request.getDestination(), indexNameExpressionResolver, autoCreateIndex, state); + new AsyncIndexBySearchAction((BulkByScrollTask) task, logger, scriptService, client, state, threadPool, request, listener) + .start(); } @Override @@ -116,8 +117,8 @@ public class TransportReindexAction extends HandledTransportAction { public AsyncIndexBySearchAction(BulkByScrollTask task, ESLogger logger, ScriptService scriptService, Client client, - ThreadPool threadPool, ReindexRequest request, ActionListener listener) { - super(task, logger, scriptService, client, threadPool, request, request.getSearchRequest(), listener); + ClusterState state, ThreadPool threadPool, ReindexRequest request, ActionListener listener) { + super(task, logger, scriptService, state, client, threadPool, request, request.getSearchRequest(), listener); } @Override diff --git a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/TransportUpdateByQueryAction.java b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/TransportUpdateByQueryAction.java index d004e86ac0c..34440e8d749 100644 --- a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/TransportUpdateByQueryAction.java +++ b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/TransportUpdateByQueryAction.java @@ -26,7 +26,9 @@ import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.HandledTransportAction; import org.elasticsearch.client.Client; +import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.Settings; @@ -50,21 +52,25 @@ import java.util.List; public class TransportUpdateByQueryAction extends HandledTransportAction { private final Client client; private final ScriptService scriptService; + private final ClusterService clusterService; @Inject public TransportUpdateByQueryAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver, Client client, TransportService transportService, - ScriptService scriptService) { + ScriptService scriptService, ClusterService clusterService) { super(settings, UpdateByQueryAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver, UpdateByQueryRequest::new); this.client = client; this.scriptService = scriptService; + this.clusterService = clusterService; } @Override protected void doExecute(Task task, UpdateByQueryRequest request, ActionListener listener) { - new AsyncIndexBySearchAction((BulkByScrollTask) task, logger, scriptService, client, threadPool, request, listener).start(); + ClusterState state = clusterService.state(); + new AsyncIndexBySearchAction((BulkByScrollTask) task, logger, scriptService, client, threadPool, state, request, listener) + .start(); } @Override @@ -77,8 +83,9 @@ public class TransportUpdateByQueryAction extends HandledTransportAction { public AsyncIndexBySearchAction(BulkByScrollTask task, ESLogger logger, ScriptService scriptService, Client client, - ThreadPool threadPool, UpdateByQueryRequest request, ActionListener listener) { - super(task, logger, scriptService, client, threadPool, request, request.getSearchRequest(), listener); + ThreadPool threadPool, ClusterState clusterState, UpdateByQueryRequest request, + ActionListener listener) { + super(task, logger, scriptService, clusterState, client, threadPool, request, request.getSearchRequest(), listener); } @Override diff --git a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexMetadataTests.java b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexMetadataTests.java index 01e018a77cb..0e0bae4c1f6 100644 --- a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexMetadataTests.java +++ b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexMetadataTests.java @@ -67,7 +67,8 @@ public class ReindexMetadataTests extends AbstractAsyncBulkIndexbyScrollActionMe @Override protected TransportReindexAction.AsyncIndexBySearchAction action() { - return new TransportReindexAction.AsyncIndexBySearchAction(task, logger, null, null, threadPool, request(), listener()); + return new TransportReindexAction.AsyncIndexBySearchAction(task, logger, null, null, null, threadPool + , request(), listener()); } @Override diff --git a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexScriptTests.java b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexScriptTests.java index c1697ba3020..20d57c27266 100644 --- a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexScriptTests.java +++ b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexScriptTests.java @@ -134,6 +134,7 @@ public class ReindexScriptTests extends AbstractAsyncBulkIndexByScrollActionScri @Override protected AbstractAsyncBulkIndexByScrollAction action() { - return new TransportReindexAction.AsyncIndexBySearchAction(task, logger, null, null, threadPool, request(), listener()); + return new TransportReindexAction.AsyncIndexBySearchAction(task, logger, null, null, null, + threadPool, request(), listener()); } -} \ No newline at end of file +} diff --git a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/UpdateByQueryMetadataTests.java b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/UpdateByQueryMetadataTests.java index e3e4e8e8ad1..5c5e45993b9 100644 --- a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/UpdateByQueryMetadataTests.java +++ b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/UpdateByQueryMetadataTests.java @@ -33,7 +33,8 @@ public class UpdateByQueryMetadataTests @Override protected TransportUpdateByQueryAction.AsyncIndexBySearchAction action() { - return new TransportUpdateByQueryAction.AsyncIndexBySearchAction(task, logger, null, null, threadPool, request(), listener()); + return new TransportUpdateByQueryAction.AsyncIndexBySearchAction(task, logger, null, null, threadPool, null, request(), + listener()); } @Override diff --git a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/UpdateByQueryWithScriptTests.java b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/UpdateByQueryWithScriptTests.java index 50109f0c0d9..735d3966889 100644 --- a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/UpdateByQueryWithScriptTests.java +++ b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/UpdateByQueryWithScriptTests.java @@ -51,6 +51,6 @@ public class UpdateByQueryWithScriptTests @Override protected AbstractAsyncBulkIndexByScrollAction action() { return new TransportUpdateByQueryAction.AsyncIndexBySearchAction(task, logger, null, null, threadPool, - request(), listener()); + null, request(), listener()); } } diff --git a/plugins/lang-javascript/build.gradle b/plugins/lang-javascript/build.gradle index 1f431241838..256c660eec8 100644 --- a/plugins/lang-javascript/build.gradle +++ b/plugins/lang-javascript/build.gradle @@ -29,6 +29,6 @@ dependencies { integTest { cluster { setting 'script.inline', 'true' - setting 'script.indexed', 'true' + setting 'script.stored', 'true' } } diff --git a/plugins/lang-python/build.gradle b/plugins/lang-python/build.gradle index c7466316806..e7468ed99af 100644 --- a/plugins/lang-python/build.gradle +++ b/plugins/lang-python/build.gradle @@ -29,7 +29,7 @@ dependencies { integTest { cluster { setting 'script.inline', 'true' - setting 'script.indexed', 'true' + setting 'script.stored', 'true' } } 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 d3f7771fc85..2c9742057fe 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 @@ -18,15 +18,6 @@ } }, "params" : { - "version": { - "type": "number", - "description": "Explicit version number for concurrency control" - }, - "version_type": { - "type": "enum", - "options": ["internal", "external", "external_gte", "force"], - "description": "Specific version type" - } } }, "body": null diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/delete_template.json b/rest-api-spec/src/main/resources/rest-api-spec/api/delete_template.json index 1dbc40ae168..e1e40bd95b6 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/delete_template.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/delete_template.json @@ -13,15 +13,6 @@ } }, "params" : { - "version": { - "type": "number", - "description": "Explicit version number for concurrency control" - }, - "version_type": { - "type": "enum", - "options": ["internal", "external", "external_gte", "force"], - "description": "Specific version type" - } } }, "body": null 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 d6cae320caa..163f147aa42 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 @@ -18,15 +18,6 @@ } }, "params" : { - "version": { - "type": "number", - "description": "Explicit version number for concurrency control" - }, - "version_type": { - "type": "enum", - "options": ["internal", "external", "external_gte", "force"], - "description": "Specific version type" - } } }, "body": null diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/get_template.json b/rest-api-spec/src/main/resources/rest-api-spec/api/get_template.json index 8052b1d63fb..487b81c5350 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/get_template.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/get_template.json @@ -13,15 +13,6 @@ } }, "params" : { - "version": { - "type": "number", - "description": "Explicit version number for concurrency control" - }, - "version_type": { - "type": "enum", - "options": ["internal", "external", "external_gte", "force"], - "description": "Specific version type" - } } }, "body": null 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 1a0d6ac5f74..c5676392625 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 @@ -18,21 +18,6 @@ } }, "params" : { - "op_type": { - "type" : "enum", - "options" : ["index", "create"], - "default" : "index", - "description" : "Explicit operation type" - }, - "version": { - "type": "number", - "description": "Explicit version number for concurrency control" - }, - "version_type": { - "type": "enum", - "options": ["internal", "external", "external_gte", "force"], - "description": "Specific version type" - } } }, "body": { diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/put_template.json b/rest-api-spec/src/main/resources/rest-api-spec/api/put_template.json index 845a368493e..294ed32cfff 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/put_template.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/put_template.json @@ -13,21 +13,6 @@ } }, "params" : { - "op_type": { - "type" : "enum", - "options" : ["index", "create"], - "default" : "index", - "description" : "Explicit operation type" - }, - "version": { - "type": "number", - "description": "Explicit version number for concurrency control" - }, - "version_type": { - "type": "enum", - "options": ["internal", "external", "external_gte", "force"], - "description": "Specific version type" - } } }, "body": { diff --git a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java index 5a7fcbec290..d347f001e79 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java @@ -1621,7 +1621,7 @@ public abstract class ESIntegTestCase extends ESTestCase { // from failing on nodes without enough disk space .put(DiskThresholdDecider.CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING.getKey(), "1b") .put(DiskThresholdDecider.CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING.getKey(), "1b") - .put("script.indexed", "true") + .put("script.stored", "true") .put("script.inline", "true") // wait short time for other active shards before actually deleting, default 30s not needed in tests .put(IndicesStore.INDICES_STORE_DELETE_SHARD_TIMEOUT.getKey(), new TimeValue(1, TimeUnit.SECONDS)); diff --git a/test/framework/src/main/java/org/elasticsearch/test/ESSingleNodeTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/ESSingleNodeTestCase.java index 74300bef2ec..1e75f3d8261 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ESSingleNodeTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ESSingleNodeTestCase.java @@ -180,7 +180,7 @@ public abstract class ESSingleNodeTestCase extends ESTestCase { .put("node.name", nodeName()) .put("script.inline", "true") - .put("script.indexed", "true") + .put("script.stored", "true") .put(EsExecutors.PROCESSORS_SETTING.getKey(), 1) // limit the number of threads created .put("http.enabled", false) .put(Node.NODE_LOCAL_SETTING.getKey(), true) diff --git a/test/framework/src/test/java/org/elasticsearch/search/MockSearchServiceTests.java b/test/framework/src/test/java/org/elasticsearch/search/MockSearchServiceTests.java index 7436472f13b..ee567aae779 100644 --- a/test/framework/src/test/java/org/elasticsearch/search/MockSearchServiceTests.java +++ b/test/framework/src/test/java/org/elasticsearch/search/MockSearchServiceTests.java @@ -34,7 +34,7 @@ import org.elasticsearch.test.TestSearchContext; public class MockSearchServiceTests extends ESTestCase { public void testAssertNoInFlightContext() { SearchContext s = new TestSearchContext(new QueryShardContext(new IndexSettings(IndexMetaData.PROTO, Settings.EMPTY), null, null, - null, null, null, null, null, null)) { + null, null, null, null, null, null, null, null)) { @Override public SearchShardTarget shardTarget() { return new SearchShardTarget("node", new Index("idx", "ignored"), 0);