Changed indexed scripts to be stored in the cluster state instead of the `.scripts` index.

Also added max script size soft limit for stored scripts.

Closes #16651
This commit is contained in:
Martijn van Groningen 2016-02-28 13:12:05 +01:00
parent ae61fc4780
commit c5ad2e2865
137 changed files with 2391 additions and 2774 deletions

View File

@ -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);

View File

@ -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<DeleteIndexedScriptRequest, DeleteIndexedScriptResponse, DeleteIndexedScriptRequestBuilder> {
public class DeleteStoredScriptAction extends Action<DeleteStoredScriptRequest, DeleteStoredScriptResponse,
DeleteStoredScriptRequestBuilder> {
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);
}
}

View File

@ -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<DeleteStoredScriptRequest> {
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 + "]}";
}
}

View File

@ -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<DeleteStoredScriptRequest,
DeleteStoredScriptResponse, DeleteStoredScriptRequestBuilder> {
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;
}
}

View File

@ -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);
}
}

View File

@ -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<GetIndexedScriptRequest, GetIndexedScriptResponse, GetIndexedScriptRequestBuilder> {
public class GetStoredScriptAction extends Action<GetStoredScriptRequest, GetStoredScriptResponse,
GetStoredScriptRequestBuilder> {
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);
}
}

View File

@ -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<GetStoredScriptRequest> {
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 + "]";
}
}

View File

@ -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<GetStoredScriptRequest,
GetStoredScriptResponse, GetStoredScriptRequestBuilder> {
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;
}
}

View File

@ -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<GetField>, 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 <code>null</code>
*/
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<GetField> 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);
}
}

View File

@ -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<PutIndexedScriptRequest, PutIndexedScriptResponse, PutIndexedScriptRequestBuilder> {
public class PutStoredScriptAction extends Action<PutStoredScriptRequest, PutStoredScriptResponse,
PutStoredScriptRequestBuilder> {
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);
}
}

View File

@ -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<PutStoredScriptRequest> {
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 + "]}";
}
}

View File

@ -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<PutStoredScriptRequest,
PutStoredScriptResponse, PutStoredScriptRequestBuilder> {
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;
}
}

View File

@ -17,7 +17,33 @@
* under the License.
*/
/**
* Delete action.
*/
package org.elasticsearch.action.indexedscripts.delete;
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);
}
}

View File

@ -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<DeleteStoredScriptRequest,
DeleteStoredScriptResponse> {
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<DeleteStoredScriptResponse> listener) throws Exception {
scriptService.deleteStoredScript(clusterService, request, listener);
}
@Override
protected ClusterBlockException checkBlock(DeleteStoredScriptRequest request, ClusterState state) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
}
}

View File

@ -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<GetStoredScriptRequest,
GetStoredScriptResponse> {
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<GetStoredScriptResponse> 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);
}
}

View File

@ -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<PutStoredScriptRequest, PutStoredScriptResponse> {
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<PutStoredScriptResponse> listener) throws Exception {
scriptService.storeScript(clusterService, request, listener);
}
@Override
protected ClusterBlockException checkBlock(PutStoredScriptRequest request, ClusterState state) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
}
}

View File

@ -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<RenderSearchTemplateRequest, RenderSearchTemplateResponse> {
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);

View File

@ -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
* <p>
* 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<DeleteIndexedScriptRequest> 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 + "]}";
}
}

View File

@ -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<DeleteIndexedScriptRequest, DeleteIndexedScriptResponse, DeleteIndexedScriptRequestBuilder> {
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;
}
}

View File

@ -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 <tt>true</tt> 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);
}
}

View File

@ -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<DeleteIndexedScriptRequest, DeleteIndexedScriptResponse> {
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<DeleteIndexedScriptResponse> listener) {
scriptService.deleteScriptFromIndex(request, new DelegatingActionListener<DeleteResponse, DeleteIndexedScriptResponse>(listener) {
@Override
public DeleteIndexedScriptResponse getDelegatedFromInstigator(DeleteResponse deleteResponse){
return new DeleteIndexedScriptResponse(deleteResponse.getIndex(), deleteResponse.getType(), deleteResponse.getId(), deleteResponse.getVersion(), deleteResponse.isFound());
}
});
}
}

View File

@ -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<GetIndexedScriptRequest> 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 + "]";
}
}

View File

@ -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<GetIndexedScriptRequest, GetIndexedScriptResponse, GetIndexedScriptRequestBuilder> {
public GetIndexedScriptRequestBuilder(ElasticsearchClient client, GetIndexedScriptAction action) {
super(client, action, new GetIndexedScriptRequest());
}
/**
* Sets the type of the document to fetch. If set to <tt>null</tt>, 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;
}
}

View File

@ -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<GetIndexedScriptRequest, GetIndexedScriptResponse> {
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<GetIndexedScriptResponse> listener){
// forward the handling to the script service we are running on a network thread here...
scriptService.queryScriptIndex(request, new ActionListener<GetResponse>() {
@Override
public void onResponse(GetResponse getFields) {
listener.onResponse(new GetIndexedScriptResponse(getFields));
}
@Override
public void onFailure(Throwable e) {
listener.onFailure(e);
}
});
}
}

View File

@ -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;

View File

@ -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.
* <p>
* The request requires the {@link #scriptLang(String)}, {@link #id(String)} and
* {@link #source(byte[])} to be set.
* <p>
* 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)}).
* <p>
* If the {@link #id(String)} is not set, it will be automatically generated.
*
* @see PutIndexedScriptResponse
*/
public class PutIndexedScriptRequest extends ActionRequest<PutIndexedScriptRequest> 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<String, Object> 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.
* <p>
* 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 <tt>true</tt> 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 + "]}";
}
}

View File

@ -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<PutIndexedScriptRequest, PutIndexedScriptResponse, PutIndexedScriptRequestBuilder> {
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<String, Object> source) {
request.source(source);
return this;
}
/**
* Index the Map as the provided content type.
*
* @param source The map to index
*/
public PutIndexedScriptRequestBuilder setSource(Map<String, Object> source, XContentType contentType) {
request.source(source, contentType);
return this;
}
/**
* Sets the document source to index.
* <p>
* 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.
* <b>Note: the number of objects passed to this method must be an even number.</b>
*/
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 <tt>true</tt> 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;
}
}

View File

@ -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);
}
}

View File

@ -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<PutIndexedScriptRequest, PutIndexedScriptResponse> {
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<PutIndexedScriptResponse> listener) {
scriptService.putScriptToIndex(request, new DelegatingActionListener<IndexResponse,PutIndexedScriptResponse>(listener) {
@Override
public PutIndexedScriptResponse getDelegatedFromInstigator(IndexResponse indexResponse){
return new PutIndexedScriptResponse(indexResponse.getType(),indexResponse.getId(),indexResponse.getVersion(),indexResponse.isCreated());
}
});
}
}

View File

@ -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;

View File

@ -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<String, Object> executeScript(Script script, Map<String, Object> 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...

View File

@ -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<DeleteIndexedScriptResponse> listener);
/**
* Delete an indexed script
*
* @param request The put request
* @return The result future
*/
ActionFuture<DeleteIndexedScriptResponse> 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<PutIndexedScriptResponse> listener);
/**
* Put an indexed script
*
* @param request The put request
* @return The result future
*/
ActionFuture<PutIndexedScriptResponse> 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<GetIndexedScriptResponse> 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<GetIndexedScriptResponse> getIndexedScript(GetIndexedScriptRequest request);
/**
* Multi get documents.
*/

View File

@ -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<DeleteStoredScriptResponse> listener);
/**
* Delete a script from the cluster state
*/
ActionFuture<DeleteStoredScriptResponse> 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<PutStoredScriptResponse> listener);
/**
* Store a script in the cluster state
*/
ActionFuture<PutStoredScriptResponse> 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<GetStoredScriptResponse> listener);
/**
* Get a script from the cluster state
*/
ActionFuture<GetStoredScriptResponse> getStoredScript(GetStoredScriptRequest request);
}

View File

@ -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<GetIndexedScriptResponse> getIndexedScript(final GetIndexedScriptRequest request) {
return execute(GetIndexedScriptAction.INSTANCE, request);
}
@Override
public void getIndexedScript(final GetIndexedScriptRequest request, final ActionListener<GetIndexedScriptResponse> 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<PutIndexedScriptResponse> listener){
execute(PutIndexedScriptAction.INSTANCE, request, listener);
}
/**
* Put an indexed script
*
* @param request The put request
* @return The result future
*/
@Override
public ActionFuture<PutIndexedScriptResponse> putIndexedScript(final PutIndexedScriptRequest request){
return execute(PutIndexedScriptAction.INSTANCE, request);
}
/**
* delete an indexed script
*/
@Override
public void deleteIndexedScript(DeleteIndexedScriptRequest request, ActionListener<DeleteIndexedScriptResponse> listener){
execute(DeleteIndexedScriptAction.INSTANCE, request, listener);
}
/**
* Delete an indexed script
*
* @param request The put request
* @return The result future
*/
@Override
public ActionFuture<DeleteIndexedScriptResponse> 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<MultiGetResponse> 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<GetStoredScriptResponse> getStoredScript(final GetStoredScriptRequest request) {
return execute(GetStoredScriptAction.INSTANCE, request);
}
@Override
public void getStoredScript(final GetStoredScriptRequest request, final ActionListener<GetStoredScriptResponse> 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<PutStoredScriptResponse> listener){
execute(PutStoredScriptAction.INSTANCE, request, listener);
}
@Override
public ActionFuture<PutStoredScriptResponse> putStoredScript(final PutStoredScriptRequest request){
return execute(PutStoredScriptAction.INSTANCE, request);
}
@Override
public void deleteStoredScript(DeleteStoredScriptRequest request, ActionListener<DeleteStoredScriptResponse> listener){
execute(DeleteStoredScriptAction.INSTANCE, request, listener);
}
@Override
public ActionFuture<DeleteStoredScriptResponse> 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 {

View File

@ -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<IndexMetaData>, Diffable<MetaData>, Fr
// register non plugin custom metadata
registerPrototype(RepositoriesMetaData.TYPE, RepositoriesMetaData.PROTO);
registerPrototype(IngestMetadata.TYPE, IngestMetadata.PROTO);
registerPrototype(ScriptMetaData.TYPE, ScriptMetaData.PROTO);
}
/**

View File

@ -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 (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 (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));
}

View File

@ -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,

View File

@ -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,

View File

@ -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()
);
}

View File

@ -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;
}
}

View File

@ -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_\":{}}";
}
if (logger.isTraceEnabled()) {
logger.trace("using dynamic[{}], default mapping source[{}]", dynamic, defaultMappingSource);

View File

@ -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

View File

@ -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();
}

View File

@ -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<ScriptQueryBuilder>
@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<ScriptQueryBuilder>
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

View File

@ -50,7 +50,7 @@ public class TemplateQueryBuilder extends AbstractQueryBuilder<TemplateQueryBuil
static {
parametersToTypes.put("query", ScriptService.ScriptType.INLINE);
parametersToTypes.put("file", ScriptService.ScriptType.FILE);
parametersToTypes.put("id", ScriptService.ScriptType.INDEXED);
parametersToTypes.put("id", ScriptService.ScriptType.STORED);
}
/** Template to fill. */
@ -175,7 +175,7 @@ public class TemplateQueryBuilder extends AbstractQueryBuilder<TemplateQueryBuil
@Override
protected QueryBuilder<?> 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);

View File

@ -103,7 +103,7 @@ public class ScriptScoreFunctionBuilder extends ScoreFunctionBuilder<ScriptScore
protected ScoreFunction doToFunction(QueryShardContext context) {
try {
SearchScript searchScript = context.getScriptService().search(context.lookup(), script, ScriptContext.Standard.SEARCH,
Collections.emptyMap());
Collections.emptyMap(), context.getClusterState());
return new ScriptScoreFunction(script, searchScript);
} catch (Exception e) {
throw new QueryShardException(context, "script_score: the script could not be loaded", e);

View File

@ -459,7 +459,7 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
if (scriptFields != null) {
for (ScriptField field : scriptFields) {
SearchScript searchScript = innerHitsContext.scriptService().search(innerHitsContext.lookup(), field.script(),
ScriptContext.Standard.SEARCH, Collections.emptyMap());
ScriptContext.Standard.SEARCH, Collections.emptyMap(), context.getClusterState());
innerHitsContext.scriptFields().add(new org.elasticsearch.search.fetch.script.ScriptFieldsContext.ScriptField(
field.fieldName(), searchScript, field.ignoreFailure()));
}

View File

@ -47,8 +47,8 @@ public class InternalTemplateService implements TemplateService {
CompiledScript compiledScript = scriptService.compile(
script,
ScriptContext.Standard.INGEST,
Collections.emptyMap()
);
Collections.emptyMap(),
null); // null == OK, because ingest templates are only inline templates.
return new Template() {
@Override
public String execute(Map<String, Object> model) {

View File

@ -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) {

View File

@ -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));
}
}

View File

@ -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) {

View File

@ -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<GetIndexedScriptResponse>(channel) {
final GetStoredScriptRequest getRequest = new GetStoredScriptRequest(getScriptLang(request), request.param("id"));
client.admin().cluster().getStoredScript(getRequest, new RestBuilderListener<GetStoredScriptResponse>(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";
}
}

View File

@ -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) {

View File

@ -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));
}
}

View File

@ -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);

View File

@ -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<DeleteIndexedScriptResponse>(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";
}
}

View File

@ -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<PutIndexedScriptResponse>(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";
}
}

View File

@ -78,8 +78,8 @@ public abstract class AbstractScriptParser<S extends Script> {
} 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<S extends Script> {
}
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<S extends Script> {
} 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,7 +187,7 @@ public abstract class AbstractScriptParser<S extends Script> {
}
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";

View File

@ -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<String, ScriptAsBytes> scripts;
ScriptMetaData(Map<String, ScriptAsBytes> 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<String, ScriptAsBytes> 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<MetaData.XContentContext> context() {
return MetaData.API_AND_GATEWAY;
}
@Override
public ScriptMetaData readFrom(StreamInput in) throws IOException {
int size = in.readVInt();
Map<String, ScriptAsBytes> 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<String, ScriptAsBytes> 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<String, ScriptAsBytes> entry : scripts.entrySet()) {
out.writeString(entry.getKey());
entry.getValue().writeTo(out);
}
}
@Override
public Diff<MetaData.Custom> diff(MetaData.Custom before) {
return new ScriptMetadataDiff((ScriptMetaData) before, this);
}
@Override
public Diff<MetaData.Custom> 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<String, ScriptAsBytes> 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<MetaData.Custom> {
final Diff<Map<String, ScriptAsBytes>> 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<ScriptAsBytes> {
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();
}
}
}

View File

@ -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);
}
}

View File

@ -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<TimeValue> 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<Boolean> SCRIPT_AUTO_RELOAD_ENABLED_SETTING =
Setting.boolSetting("script.auto_reload_enabled", true, Property.NodeScope);
public static final Setting<Integer> 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<ScriptEngineService> 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<String, String> params) {
public CompiledScript compile(Script script, ScriptContext scriptContext, Map<String, String> 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<String, String> params) {
CompiledScript compileInternal(Script script, Map<String, String> 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<GetResponse> 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);
}
throw new IllegalArgumentException("Unable to find script [" + SCRIPT_INDEX + "/"
+ scriptLang + "/" + id + "]");
ScriptMetaData scriptMetadata = state.metaData().custom(ScriptMetaData.TYPE);
if (scriptMetadata == null) {
throw new ResourceNotFoundException("Unable to find script [" + scriptLang + "/" + id + "] in cluster state");
}
private void validate(BytesReference scriptBytes, String scriptLang) {
String script = scriptMetadata.getScript(scriptLang, id);
if (script == null) {
throw new ResourceNotFoundException("Unable to find script [" + scriptLang + "/" + id + "] in cluster state");
}
return script;
}
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<IndexResponse> listener) {
public void storeScript(ClusterService clusterService, PutStoredScriptRequest request, ActionListener<PutStoredScriptResponse> 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<PutStoredScriptResponse>(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);
}
public void deleteScriptFromIndex(DeleteIndexedScriptRequest request, ActionListener<DeleteResponse> listener) {
@Override
public ClusterState execute(ClusterState currentState) throws Exception {
return innerStoreScript(currentState, scriptLang, request);
}
});
}
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<DeleteStoredScriptResponse> 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<DeleteStoredScriptResponse>(request, listener) {
@Override
protected DeleteStoredScriptResponse newResponse(boolean acknowledged) {
return new DeleteStoredScriptResponse(acknowledged);
}
@SuppressWarnings("unchecked")
public static String getScriptFromResponse(GetResponse responseFields) {
Map<String, Object> 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<String, Object>)template);
return builder.string();
@Override
public ClusterState execute(ClusterState currentState) throws Exception {
return innerDeleteScript(currentState, scriptLang, request);
}
});
}
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 {
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();
} 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<String, String> params) {
return executable(compile(script, scriptContext, params), script.getParams());
public ExecutableScript executable(Script script, ScriptContext scriptContext, Map<String, String> 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<String, String> params) {
CompiledScript compiledScript = compile(script, scriptContext, params);
public SearchScript search(SearchLookup lookup, Script script, ScriptContext scriptContext, Map<String, String> 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{

View File

@ -566,7 +566,8 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> 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<SearchService> 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()));
}
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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 {

View File

@ -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;
}

View File

@ -106,7 +106,7 @@ public class TopHitsAggregatorFactory extends AggregatorFactory<TopHitsAggregato
if (scriptFields != null) {
for (ScriptField field : scriptFields) {
SearchScript searchScript = subSearchContext.scriptService().search(subSearchContext.lookup(), field.script(),
ScriptContext.Standard.SEARCH, Collections.emptyMap());
ScriptContext.Standard.SEARCH, Collections.emptyMap(), subSearchContext.getQueryShardContext().getClusterState());
subSearchContext.scriptFields().add(new org.elasticsearch.search.fetch.script.ScriptFieldsContext.ScriptField(
field.fieldName(), searchScript, field.ignoreFailure()));
}

View File

@ -92,7 +92,8 @@ public class BucketScriptPipelineAggregator extends PipelineAggregator {
InternalMultiBucketAggregation<InternalMultiBucketAggregation, InternalMultiBucketAggregation.InternalBucket> originalAgg = (InternalMultiBucketAggregation<InternalMultiBucketAggregation, InternalMultiBucketAggregation.InternalBucket>) aggregation;
List<? extends Bucket> 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<String, Object> vars = new HashMap<>();

View File

@ -89,7 +89,8 @@ public class BucketSelectorPipelineAggregator extends PipelineAggregator {
(InternalMultiBucketAggregation<InternalMultiBucketAggregation, InternalMultiBucketAggregation.InternalBucket>) aggregation;
List<? extends Bucket> 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<String, Object> vars = new HashMap<>();

View File

@ -377,7 +377,8 @@ public abstract class ValuesSourceAggregatorBuilder<VS extends ValuesSource, AB
private SearchScript createScript(Script script, SearchContext context) {
return script == null ? null
: context.scriptService().search(context.lookup(), script, ScriptContext.Standard.AGGS, Collections.emptyMap());
: context.scriptService().search(context.lookup(), script, ScriptContext.Standard.AGGS, Collections.emptyMap(),
context.getQueryShardContext().getClusterState());
}
private static DocValueFormat resolveFormat(@Nullable String format, @Nullable ValueType valueType) {

View File

@ -31,6 +31,7 @@ import org.apache.lucene.search.TermStatistics;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.TopFieldDocs;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.collect.HppcMaps;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
@ -85,14 +86,15 @@ public class SearchPhaseController extends AbstractComponent {
public static final ScoreDoc[] EMPTY_DOCS = new ScoreDoc[0];
private final BigArrays bigArrays;
private ScriptService scriptService;
private final ScriptService scriptService;
private final ClusterService clusterService;
@Inject
public SearchPhaseController(Settings settings, BigArrays bigArrays, ScriptService scriptService) {
public SearchPhaseController(Settings settings, BigArrays bigArrays, ScriptService scriptService, ClusterService clusterService) {
super(settings);
this.bigArrays = bigArrays;
this.scriptService = scriptService;
this.clusterService = clusterService;
}
public AggregatedDfs aggregateDfs(AtomicArray<DfsSearchResult> results) {
@ -397,7 +399,8 @@ public class SearchPhaseController extends AbstractComponent {
for (AtomicArray.Entry<? extends QuerySearchResultProvider> 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);

View File

@ -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));
}
}

View File

@ -304,7 +304,7 @@ public class ScriptSortBuilder extends SortBuilder<ScriptSortBuilder> {
@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) {

View File

@ -631,7 +631,7 @@ public class PhraseSuggestionBuilder extends SuggestionBuilder<PhraseSuggestionB
if (this.collateQuery != null) {
CompiledScript compiledScript = context.getScriptService().compile(this.collateQuery, ScriptContext.Standard.SEARCH,
Collections.emptyMap());
Collections.emptyMap(), context.getClusterState());
suggestionContext.setCollateQueryScript(compiledScript);
if (this.collateParams != null) {
suggestionContext.setCollateScriptParams(this.collateParams);

View File

@ -17,11 +17,11 @@
* under the License.
*/
package org.elasticsearch.action.indexedscripts.get;
package org.elasticsearch.action.admin.cluster.storedscripts;
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.index.VersionType;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
@ -29,13 +29,9 @@ import java.io.IOException;
import static org.elasticsearch.test.VersionUtils.randomVersion;
import static org.hamcrest.CoreMatchers.equalTo;
public class GetIndexedScriptRequestTests extends ESTestCase {
public class GetStoredScriptRequestTests extends ESTestCase {
public void testGetIndexedScriptRequestSerialization() throws IOException {
GetIndexedScriptRequest request = new GetIndexedScriptRequest("lang", "id");
if (randomBoolean()) {
request.version(randomIntBetween(1, Integer.MAX_VALUE));
request.versionType(randomFrom(VersionType.values()));
}
GetStoredScriptRequest request = new GetStoredScriptRequest("lang", "id");
BytesStreamOutput out = new BytesStreamOutput();
out.setVersion(randomVersion(random()));
@ -43,12 +39,10 @@ public class GetIndexedScriptRequestTests extends ESTestCase {
StreamInput in = StreamInput.wrap(out.bytes());
in.setVersion(out.getVersion());
GetIndexedScriptRequest request2 = new GetIndexedScriptRequest();
GetStoredScriptRequest request2 = new GetStoredScriptRequest();
request2.readFrom(in);
assertThat(request2.id(), equalTo(request.id()));
assertThat(request2.scriptLang(), equalTo(request.scriptLang()));
assertThat(request2.version(), equalTo(request.version()));
assertThat(request2.versionType(), equalTo(request.versionType()));
assertThat(request2.lang(), equalTo(request.lang()));
}
}

View File

@ -135,7 +135,7 @@ public class UpdateRequestTests extends ESTestCase {
TimeValue providedTTLValue = TimeValue.parseTimeValue(randomTimeValue(), null, "ttl");
Settings settings = settings(Version.CURRENT).build();
UpdateHelper updateHelper = new UpdateHelper(settings, null);
UpdateHelper updateHelper = new UpdateHelper(settings, null, null);
// We just upsert one document with ttl
IndexRequest indexRequest = new IndexRequest("test", "type1", "1")

View File

@ -32,7 +32,7 @@ import org.elasticsearch.action.admin.indices.stats.IndicesStatsAction;
import org.elasticsearch.action.delete.DeleteAction;
import org.elasticsearch.action.get.GetAction;
import org.elasticsearch.action.index.IndexAction;
import org.elasticsearch.action.indexedscripts.delete.DeleteIndexedScriptAction;
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptAction;
import org.elasticsearch.action.search.SearchAction;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
@ -60,7 +60,7 @@ public abstract class AbstractClientHeadersTestCase extends ESTestCase {
private static final GenericAction[] ACTIONS = new GenericAction[] {
// client actions
GetAction.INSTANCE, SearchAction.INSTANCE, DeleteAction.INSTANCE, DeleteIndexedScriptAction.INSTANCE,
GetAction.INSTANCE, SearchAction.INSTANCE, DeleteAction.INSTANCE, DeleteStoredScriptAction.INSTANCE,
IndexAction.INSTANCE,
// cluster admin actions
@ -105,7 +105,7 @@ public abstract class AbstractClientHeadersTestCase extends ESTestCase {
client.prepareGet("idx", "type", "id").execute().addListener(new AssertingActionListener<>(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

View File

@ -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);
}

View File

@ -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 {

View File

@ -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<QB extends AbstractQueryBuilder<QB>>
* @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);
}
/**

View File

@ -363,7 +363,7 @@ public class QueryDSLDocumentationTests extends ESTestCase {
public void testTemplate() {
templateQuery(
"gender_template",
ScriptType.INDEXED,
ScriptType.STORED,
new HashMap<>());
}

View File

@ -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);

View File

@ -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));

View File

@ -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"));

View File

@ -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());
}
}

View File

@ -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"));

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -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());

View File

@ -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();
}
}

View File

@ -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<Class<? extends Plugin>> 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());
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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<T extends SortBuilder<T>> 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<String, String> params) {
public CompiledScript compile(Script script, ScriptContext scriptContext, Map<String, String> params, ClusterState state) {
return new CompiledScript(ScriptType.INLINE, "mockName", "test", script);
}
};
@ -226,7 +227,7 @@ public abstract class AbstractSortTestCase<T extends SortBuilder<T>> 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);

View File

@ -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();
}

View File

@ -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:")

View File

@ -42,6 +42,7 @@ way to do this is to upgrade to Elasticsearch 2.3 or later and to use the
* <<breaking_50_plugins>>
* <<breaking_50_fs>>
* <<breaking_50_aggregations_changes>>
* <<breaking_50_scripting>>
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[]

View File

@ -0,0 +1,57 @@
[[breaking_50_scripting]]
=== Script related changes
==== Indexed scripts and templates
Indexed scrips and templates have been replaced by <<modules-scripting-stored-scripts,stored scripts>>
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.

View File

@ -238,3 +238,15 @@ 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.
==== 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.)

View File

@ -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

Some files were not shown because too many files have changed in this diff Show More