Skip to content

Commit 356eef0

Browse files
authored
Scripting: get context names REST API (#48026) (#48168)
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: #47411
1 parent f46281a commit 356eef0

File tree

11 files changed

+429
-0
lines changed

11 files changed

+429
-0
lines changed

client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,7 @@ public void testApiNamingConventions() throws Exception {
760760
String[] notYetSupportedApi = new String[]{
761761
"cluster.remote_info",
762762
"create",
763+
"get_script_context",
763764
"get_source",
764765
"indices.delete_alias",
765766
"indices.exists_type",
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"get_script_context":{
3+
"documentation":{
4+
"description":"Returns all script contexts."
5+
},
6+
"stability":"experimental",
7+
"url":{
8+
"paths":[
9+
{
10+
"path":"/_script_context",
11+
"methods":[
12+
"GET"
13+
]
14+
}
15+
]
16+
},
17+
"params":{}
18+
}
19+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"Action to get all contexts":
2+
- skip:
3+
version: " - 7.6.0"
4+
reason: "get_all_contexts introduced in 7.6.0"
5+
- do:
6+
get_script_context: {}
7+
- match: { contexts.aggregation_selector: {} }
8+
- match: { contexts.aggs: {} }
9+
- match: { contexts.aggs_combine: {} }
10+
- match: { contexts.aggs_init: {} }
11+
- match: { contexts.aggs_map: {} }
12+
- match: { contexts.aggs_reduce: {} }
13+
- match: { contexts.bucket_aggregation: {} }
14+
- match: { contexts.field: {} }
15+
- match: { contexts.filter: {} }
16+
- match: { contexts.ingest: {} }
17+
- match: { contexts.interval: {} }
18+
- match: { contexts.number_sort: {} }
19+
- match: { contexts.processor_conditional: {} }
20+
- match: { contexts.score: {} }
21+
- match: { contexts.script_heuristic: {} }
22+
- match: { contexts.similarity: {} }
23+
- match: { contexts.similarity_weight: {} }
24+
- match: { contexts.string_sort: {} }
25+
- match: { contexts.template: {} }
26+
- match: { contexts.terms_set: {} }
27+
- match: { contexts.update: {} }

server/src/main/java/org/elasticsearch/action/ActionModule.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,11 @@
7979
import org.elasticsearch.action.admin.cluster.stats.ClusterStatsAction;
8080
import org.elasticsearch.action.admin.cluster.stats.TransportClusterStatsAction;
8181
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptAction;
82+
import org.elasticsearch.action.admin.cluster.storedscripts.GetScriptContextAction;
8283
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptAction;
8384
import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptAction;
8485
import org.elasticsearch.action.admin.cluster.storedscripts.TransportDeleteStoredScriptAction;
86+
import org.elasticsearch.action.admin.cluster.storedscripts.TransportGetScriptContextAction;
8587
import org.elasticsearch.action.admin.cluster.storedscripts.TransportGetStoredScriptAction;
8688
import org.elasticsearch.action.admin.cluster.storedscripts.TransportPutStoredScriptAction;
8789
import org.elasticsearch.action.admin.cluster.tasks.PendingClusterTasksAction;
@@ -244,6 +246,7 @@
244246
import org.elasticsearch.rest.action.admin.cluster.RestDeleteSnapshotAction;
245247
import org.elasticsearch.rest.action.admin.cluster.RestDeleteStoredScriptAction;
246248
import org.elasticsearch.rest.action.admin.cluster.RestGetRepositoriesAction;
249+
import org.elasticsearch.rest.action.admin.cluster.RestGetScriptContextAction;
247250
import org.elasticsearch.rest.action.admin.cluster.RestGetSnapshotsAction;
248251
import org.elasticsearch.rest.action.admin.cluster.RestGetStoredScriptAction;
249252
import org.elasticsearch.rest.action.admin.cluster.RestGetTaskAction;
@@ -526,6 +529,7 @@ public <Request extends ActionRequest, Response extends ActionResponse> void reg
526529
actions.register(PutStoredScriptAction.INSTANCE, TransportPutStoredScriptAction.class);
527530
actions.register(GetStoredScriptAction.INSTANCE, TransportGetStoredScriptAction.class);
528531
actions.register(DeleteStoredScriptAction.INSTANCE, TransportDeleteStoredScriptAction.class);
532+
actions.register(GetScriptContextAction.INSTANCE, TransportGetScriptContextAction.class);
529533

530534
actions.register(FieldCapabilitiesAction.INSTANCE, TransportFieldCapabilitiesAction.class,
531535
TransportFieldCapabilitiesIndexAction.class);
@@ -655,6 +659,7 @@ public void initRestHandlers(Supplier<DiscoveryNodes> nodesInCluster) {
655659
registerHandler.accept(new RestGetStoredScriptAction(restController));
656660
registerHandler.accept(new RestPutStoredScriptAction(restController));
657661
registerHandler.accept(new RestDeleteStoredScriptAction(restController));
662+
registerHandler.accept(new RestGetScriptContextAction(restController));
658663

659664
registerHandler.accept(new RestFieldCapabilitiesAction(restController));
660665

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.action.admin.cluster.storedscripts;
21+
22+
import org.elasticsearch.action.ActionType;
23+
24+
public class GetScriptContextAction extends ActionType<GetScriptContextResponse> {
25+
26+
public static final GetScriptContextAction INSTANCE = new GetScriptContextAction();
27+
public static final String NAME = "cluster:admin/script_context/get";
28+
29+
private GetScriptContextAction() {
30+
super(NAME, GetScriptContextResponse::new);
31+
}
32+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.elasticsearch.action.admin.cluster.storedscripts;
20+
21+
import org.elasticsearch.action.ActionRequest;
22+
import org.elasticsearch.action.ActionRequestValidationException;
23+
import org.elasticsearch.common.io.stream.StreamInput;
24+
25+
import java.io.IOException;
26+
27+
public class GetScriptContextRequest extends ActionRequest {
28+
public GetScriptContextRequest() {
29+
super();
30+
}
31+
32+
GetScriptContextRequest(StreamInput in) throws IOException {
33+
super(in);
34+
}
35+
36+
@Override
37+
public ActionRequestValidationException validate() {
38+
return null;
39+
}
40+
41+
@Override
42+
public String toString() {
43+
return "get script context";
44+
}
45+
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.action.admin.cluster.storedscripts;
21+
22+
import org.elasticsearch.action.ActionResponse;
23+
import org.elasticsearch.common.ParseField;
24+
import org.elasticsearch.common.io.stream.StreamInput;
25+
import org.elasticsearch.common.io.stream.StreamOutput;
26+
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
27+
import org.elasticsearch.common.xcontent.StatusToXContentObject;
28+
import org.elasticsearch.common.xcontent.XContentBuilder;
29+
import org.elasticsearch.common.xcontent.XContentParser;
30+
import org.elasticsearch.rest.RestStatus;
31+
32+
import java.io.IOException;
33+
import java.util.ArrayList;
34+
import java.util.Collections;
35+
import java.util.List;
36+
import java.util.Map;
37+
import java.util.Objects;
38+
import java.util.stream.Collectors;
39+
40+
import static org.elasticsearch.common.xcontent.XContentParser.Token.END_OBJECT;
41+
import static org.elasticsearch.common.xcontent.XContentParser.Token.START_OBJECT;
42+
43+
public class GetScriptContextResponse extends ActionResponse implements StatusToXContentObject {
44+
45+
private static final ParseField CONTEXTS = new ParseField("contexts");
46+
private final List<String> contextNames;
47+
48+
@SuppressWarnings("unchecked")
49+
public static final ConstructingObjectParser<GetScriptContextResponse,Void> PARSER =
50+
new ConstructingObjectParser<>("get_script_context", true,
51+
(a) -> {
52+
Map<String, Object> contexts = ((List<String>) a[0]).stream().collect(Collectors.toMap(
53+
name -> name, name -> new Object()
54+
));
55+
return new GetScriptContextResponse(contexts);
56+
}
57+
);
58+
59+
static {
60+
PARSER.declareNamedObjects(
61+
ConstructingObjectParser.constructorArg(),
62+
(p, c, n) ->
63+
{
64+
// advance empty object
65+
assert(p.nextToken() == START_OBJECT);
66+
assert(p.nextToken() == END_OBJECT);
67+
return n;
68+
},
69+
CONTEXTS
70+
);
71+
}
72+
73+
GetScriptContextResponse(StreamInput in) throws IOException {
74+
super(in);
75+
int size = in.readInt();
76+
ArrayList<String> contextNames = new ArrayList<>(size);
77+
for (int i = 0; i < size; i++) {
78+
contextNames.add(in.readString());
79+
}
80+
this.contextNames = Collections.unmodifiableList(contextNames);
81+
}
82+
83+
GetScriptContextResponse(Map<String,Object> contexts) {
84+
List<String> contextNames = new ArrayList<>(contexts.keySet());
85+
contextNames.sort(String::compareTo);
86+
this.contextNames = Collections.unmodifiableList(contextNames);
87+
}
88+
89+
@Override
90+
public void writeTo(StreamOutput out) throws IOException {
91+
out.writeInt(this.contextNames.size());
92+
for (String context: this.contextNames) {
93+
out.writeString(context);
94+
}
95+
}
96+
97+
@Override
98+
public RestStatus status() {
99+
return RestStatus.OK;
100+
}
101+
102+
@Override
103+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
104+
builder.startObject().startObject(CONTEXTS.getPreferredName());
105+
for (String contextName: this.contextNames) {
106+
builder.startObject(contextName).endObject();
107+
}
108+
builder.endObject().endObject(); // CONTEXTS
109+
return builder;
110+
}
111+
112+
public static GetScriptContextResponse fromXContent(XContentParser parser) throws IOException {
113+
return PARSER.apply(parser, null);
114+
}
115+
116+
@Override
117+
public boolean equals(Object o) {
118+
if (this == o) {
119+
return true;
120+
}
121+
if (o == null || getClass() != o.getClass()) {
122+
return false;
123+
}
124+
GetScriptContextResponse that = (GetScriptContextResponse) o;
125+
return contextNames.equals(that.contextNames);
126+
}
127+
128+
@Override
129+
public int hashCode() {
130+
return Objects.hash(contextNames);
131+
}
132+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.elasticsearch.action.admin.cluster.storedscripts;
20+
21+
import org.elasticsearch.action.ActionListener;
22+
import org.elasticsearch.action.support.ActionFilters;
23+
import org.elasticsearch.action.support.HandledTransportAction;
24+
import org.elasticsearch.common.inject.Inject;
25+
import org.elasticsearch.script.ScriptService;
26+
import org.elasticsearch.tasks.Task;
27+
import org.elasticsearch.transport.TransportService;
28+
29+
import java.util.Map;
30+
import java.util.stream.Collectors;
31+
32+
public class TransportGetScriptContextAction extends HandledTransportAction<GetScriptContextRequest, GetScriptContextResponse> {
33+
34+
private final ScriptService scriptService;
35+
36+
@Inject
37+
public TransportGetScriptContextAction(TransportService transportService, ActionFilters actionFilters, ScriptService scriptService) {
38+
super(GetScriptContextAction.NAME, transportService, actionFilters, GetScriptContextRequest::new);
39+
this.scriptService = scriptService;
40+
}
41+
42+
@Override
43+
protected void doExecute(Task task, GetScriptContextRequest request, ActionListener<GetScriptContextResponse> listener) {
44+
Map<String,Object> contexts = scriptService.getContextNames().stream().collect(
45+
Collectors.toMap(name -> name, name -> new Object())
46+
);
47+
listener.onResponse(new GetScriptContextResponse(contexts));
48+
}
49+
}

0 commit comments

Comments
 (0)