Skip to content

Commit

Permalink
Scripting: get context names REST API (elastic#48026)
Browse files Browse the repository at this point in the history
Adds `GET /_script_context`, returning a `contexts` object with each
available context as a key whose value is an empty object. eg.
```
{
  "contexts": {
    "aggregation_selector": {},
    "aggs": {},
    "aggs_combine": {},
...
  }
}
```

refs: elastic#47411
  • Loading branch information
stu-elastic committed Oct 16, 2019
1 parent ac1ed6e commit 1311835
Show file tree
Hide file tree
Showing 11 changed files with 429 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,7 @@ public void testApiNamingConventions() throws Exception {
String[] notYetSupportedApi = new String[]{
"cluster.remote_info",
"create",
"get_script_context",
"get_source",
"indices.delete_alias",
"indices.exists_type",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"get_script_context":{
"documentation":{
"description":"Returns all script contexts."
},
"stability":"experimental",
"url":{
"paths":[
{
"path":"/_script_context",
"methods":[
"GET"
]
}
]
},
"params":{}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"Action to get all contexts":
- skip:
version: " - 7.6.0"
reason: "get_all_contexts introduced in 7.6.0"
- do:
get_script_context: {}
- match: { contexts.aggregation_selector: {} }
- match: { contexts.aggs: {} }
- match: { contexts.aggs_combine: {} }
- match: { contexts.aggs_init: {} }
- match: { contexts.aggs_map: {} }
- match: { contexts.aggs_reduce: {} }
- match: { contexts.bucket_aggregation: {} }
- match: { contexts.field: {} }
- match: { contexts.filter: {} }
- match: { contexts.ingest: {} }
- match: { contexts.interval: {} }
- match: { contexts.number_sort: {} }
- match: { contexts.processor_conditional: {} }
- match: { contexts.score: {} }
- match: { contexts.script_heuristic: {} }
- match: { contexts.similarity: {} }
- match: { contexts.similarity_weight: {} }
- match: { contexts.string_sort: {} }
- match: { contexts.template: {} }
- match: { contexts.terms_set: {} }
- match: { contexts.update: {} }
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,11 @@
import org.elasticsearch.action.admin.cluster.stats.ClusterStatsAction;
import org.elasticsearch.action.admin.cluster.stats.TransportClusterStatsAction;
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptAction;
import org.elasticsearch.action.admin.cluster.storedscripts.GetScriptContextAction;
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptAction;
import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptAction;
import org.elasticsearch.action.admin.cluster.storedscripts.TransportDeleteStoredScriptAction;
import org.elasticsearch.action.admin.cluster.storedscripts.TransportGetScriptContextAction;
import org.elasticsearch.action.admin.cluster.storedscripts.TransportGetStoredScriptAction;
import org.elasticsearch.action.admin.cluster.storedscripts.TransportPutStoredScriptAction;
import org.elasticsearch.action.admin.cluster.tasks.PendingClusterTasksAction;
Expand Down Expand Up @@ -244,6 +246,7 @@
import org.elasticsearch.rest.action.admin.cluster.RestDeleteSnapshotAction;
import org.elasticsearch.rest.action.admin.cluster.RestDeleteStoredScriptAction;
import org.elasticsearch.rest.action.admin.cluster.RestGetRepositoriesAction;
import org.elasticsearch.rest.action.admin.cluster.RestGetScriptContextAction;
import org.elasticsearch.rest.action.admin.cluster.RestGetSnapshotsAction;
import org.elasticsearch.rest.action.admin.cluster.RestGetStoredScriptAction;
import org.elasticsearch.rest.action.admin.cluster.RestGetTaskAction;
Expand Down Expand Up @@ -526,6 +529,7 @@ public <Request extends ActionRequest, Response extends ActionResponse> void reg
actions.register(PutStoredScriptAction.INSTANCE, TransportPutStoredScriptAction.class);
actions.register(GetStoredScriptAction.INSTANCE, TransportGetStoredScriptAction.class);
actions.register(DeleteStoredScriptAction.INSTANCE, TransportDeleteStoredScriptAction.class);
actions.register(GetScriptContextAction.INSTANCE, TransportGetScriptContextAction.class);

actions.register(FieldCapabilitiesAction.INSTANCE, TransportFieldCapabilitiesAction.class,
TransportFieldCapabilitiesIndexAction.class);
Expand Down Expand Up @@ -655,6 +659,7 @@ public void initRestHandlers(Supplier<DiscoveryNodes> nodesInCluster) {
registerHandler.accept(new RestGetStoredScriptAction(restController));
registerHandler.accept(new RestPutStoredScriptAction(restController));
registerHandler.accept(new RestDeleteStoredScriptAction(restController));
registerHandler.accept(new RestGetScriptContextAction(restController));

registerHandler.accept(new RestFieldCapabilitiesAction(restController));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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.ActionType;

public class GetScriptContextAction extends ActionType<GetScriptContextResponse> {

public static final GetScriptContextAction INSTANCE = new GetScriptContextAction();
public static final String NAME = "cluster:admin/script_context/get";

private GetScriptContextAction() {
super(NAME, GetScriptContextResponse::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.common.io.stream.StreamInput;

import java.io.IOException;

public class GetScriptContextRequest extends ActionRequest {
public GetScriptContextRequest() {
super();
}

GetScriptContextRequest(StreamInput in) throws IOException {
super(in);
}

@Override
public ActionRequestValidationException validate() {
return null;
}

@Override
public String toString() {
return "get script context";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* 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.ActionResponse;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.StatusToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.rest.RestStatus;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static org.elasticsearch.common.xcontent.XContentParser.Token.END_OBJECT;
import static org.elasticsearch.common.xcontent.XContentParser.Token.START_OBJECT;

public class GetScriptContextResponse extends ActionResponse implements StatusToXContentObject {

private static final ParseField CONTEXTS = new ParseField("contexts");
private final List<String> contextNames;

@SuppressWarnings("unchecked")
public static final ConstructingObjectParser<GetScriptContextResponse,Void> PARSER =
new ConstructingObjectParser<>("get_script_context", true,
(a) -> {
Map<String, Object> contexts = ((List<String>) a[0]).stream().collect(Collectors.toMap(
name -> name, name -> new Object()
));
return new GetScriptContextResponse(contexts);
}
);

static {
PARSER.declareNamedObjects(
ConstructingObjectParser.constructorArg(),
(p, c, n) ->
{
// advance empty object
assert(p.nextToken() == START_OBJECT);
assert(p.nextToken() == END_OBJECT);
return n;
},
CONTEXTS
);
}

GetScriptContextResponse(StreamInput in) throws IOException {
super(in);
int size = in.readInt();
ArrayList<String> contextNames = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
contextNames.add(in.readString());
}
this.contextNames = Collections.unmodifiableList(contextNames);
}

GetScriptContextResponse(Map<String,Object> contexts) {
List<String> contextNames = new ArrayList<>(contexts.keySet());
contextNames.sort(String::compareTo);
this.contextNames = Collections.unmodifiableList(contextNames);
}

@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeInt(this.contextNames.size());
for (String context: this.contextNames) {
out.writeString(context);
}
}

@Override
public RestStatus status() {
return RestStatus.OK;
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject().startObject(CONTEXTS.getPreferredName());
for (String contextName: this.contextNames) {
builder.startObject(contextName).endObject();
}
builder.endObject().endObject(); // CONTEXTS
return builder;
}

public static GetScriptContextResponse fromXContent(XContentParser parser) throws IOException {
return PARSER.apply(parser, null);
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GetScriptContextResponse that = (GetScriptContextResponse) o;
return contextNames.equals(that.contextNames);
}

@Override
public int hashCode() {
return Objects.hash(contextNames);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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.HandledTransportAction;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.tasks.Task;
import org.elasticsearch.transport.TransportService;

import java.util.Map;
import java.util.stream.Collectors;

public class TransportGetScriptContextAction extends HandledTransportAction<GetScriptContextRequest, GetScriptContextResponse> {

private final ScriptService scriptService;

@Inject
public TransportGetScriptContextAction(TransportService transportService, ActionFilters actionFilters, ScriptService scriptService) {
super(GetScriptContextAction.NAME, transportService, actionFilters, GetScriptContextRequest::new);
this.scriptService = scriptService;
}

@Override
protected void doExecute(Task task, GetScriptContextRequest request, ActionListener<GetScriptContextResponse> listener) {
Map<String,Object> contexts = scriptService.getContextNames().stream().collect(
Collectors.toMap(name -> name, name -> new Object())
);
listener.onResponse(new GetScriptContextResponse(contexts));
}
}
Loading

0 comments on commit 1311835

Please sign in to comment.